@gearbox-protocol/sdk 14.12.0-next.73 → 14.12.0-next.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/dev/AccountOpener.js +2 -5
- package/dist/cjs/plugins/accounts-counter/AccountsCounterPlugin.js +1 -1
- package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +118 -974
- package/dist/cjs/sdk/accounts/credit-account-compressor/CreditAccountCompressor.js +280 -0
- package/dist/cjs/sdk/accounts/credit-account-compressor/CreditAccountCompressorV310Contract.js +141 -0
- package/dist/cjs/sdk/accounts/credit-account-compressor/index.js +6 -0
- package/dist/cjs/sdk/accounts/credit-account-compressor/types.js +1 -0
- package/dist/cjs/sdk/accounts/index.js +5 -4
- package/dist/cjs/sdk/accounts/intents/operations/unwrap-rwa-collateral/index.js +1 -1
- package/dist/cjs/sdk/accounts/intents/operations/wrap-rwa-collateral/index.js +1 -1
- package/dist/cjs/sdk/accounts/intents/testing/sdk-mock.js +2 -2
- package/dist/cjs/sdk/accounts/liquidations/LiquidationsService.js +3 -3
- package/dist/cjs/sdk/accounts/liquidations/constants.js +0 -2
- package/dist/cjs/sdk/accounts/liquidations/index.js +0 -2
- package/dist/cjs/sdk/constants/index.js +1 -0
- package/dist/cjs/sdk/constants/math.js +5 -0
- package/dist/cjs/sdk/index.js +12 -4
- package/dist/cjs/sdk/market/MarketRegister.js +10 -0
- package/dist/cjs/sdk/market/credit/CreditFacadeV310Contract.js +181 -0
- package/dist/cjs/sdk/market/credit/CreditSuite.js +107 -1
- package/dist/cjs/sdk/{accounts → market/credit}/dominantCollateral.js +18 -4
- package/dist/cjs/sdk/market/credit/index.js +3 -0
- package/dist/cjs/sdk/market/index.js +3 -0
- package/dist/cjs/sdk/market/math.js +59 -0
- package/dist/cjs/sdk/market/oracle/PriceOracleBaseContract.js +41 -1
- package/dist/cjs/sdk/market/oracle/PriceOracleV310Contract.js +0 -30
- package/dist/cjs/sdk/market/pricefeeds/PriceFeedsRegister.js +1 -1
- package/dist/cjs/sdk/opportunities/index.js +4 -0
- package/dist/esm/dev/AccountOpener.js +2 -5
- package/dist/esm/plugins/accounts-counter/AccountsCounterPlugin.js +1 -1
- package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +121 -977
- package/dist/esm/sdk/accounts/credit-account-compressor/CreditAccountCompressor.js +279 -0
- package/dist/esm/sdk/accounts/credit-account-compressor/CreditAccountCompressorV310Contract.js +141 -0
- package/dist/esm/sdk/accounts/credit-account-compressor/index.js +4 -0
- package/dist/esm/sdk/accounts/credit-account-compressor/types.js +1 -0
- package/dist/esm/sdk/accounts/index.js +4 -3
- package/dist/esm/sdk/accounts/intents/operations/unwrap-rwa-collateral/index.js +1 -1
- package/dist/esm/sdk/accounts/intents/operations/wrap-rwa-collateral/index.js +1 -1
- package/dist/esm/sdk/accounts/intents/testing/sdk-mock.js +2 -2
- package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +2 -2
- package/dist/esm/sdk/accounts/liquidations/constants.js +1 -2
- package/dist/esm/sdk/accounts/liquidations/index.js +1 -2
- package/dist/esm/sdk/constants/index.js +2 -2
- package/dist/esm/sdk/constants/math.js +5 -1
- package/dist/esm/sdk/index.js +6 -5
- package/dist/esm/sdk/market/MarketRegister.js +10 -0
- package/dist/esm/sdk/market/credit/CreditFacadeV310Contract.js +181 -0
- package/dist/esm/sdk/market/credit/CreditSuite.js +108 -2
- package/dist/esm/sdk/{accounts → market/credit}/dominantCollateral.js +18 -5
- package/dist/esm/sdk/market/credit/index.js +2 -1
- package/dist/esm/sdk/market/index.js +2 -1
- package/dist/esm/sdk/market/math.js +56 -1
- package/dist/esm/sdk/market/oracle/PriceOracleBaseContract.js +41 -1
- package/dist/esm/sdk/market/oracle/PriceOracleV310Contract.js +1 -31
- package/dist/esm/sdk/market/pricefeeds/PriceFeedsRegister.js +1 -1
- package/dist/esm/sdk/opportunities/index.js +2 -2
- package/dist/types/plugins/accounts/AccountsPlugin.d.ts +1 -1
- package/dist/types/sdk/OnchainSDK.d.ts +1 -1
- package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +23 -124
- package/dist/types/sdk/accounts/credit-account-compressor/CreditAccountCompressor.d.ts +60 -0
- package/dist/types/sdk/accounts/credit-account-compressor/CreditAccountCompressorV310Contract.d.ts +879 -0
- package/dist/types/sdk/accounts/credit-account-compressor/index.d.ts +4 -0
- package/dist/types/sdk/accounts/credit-account-compressor/types.d.ts +164 -0
- package/dist/types/sdk/accounts/index.d.ts +7 -5
- package/dist/types/sdk/accounts/liquidations/constants.d.ts +1 -2
- package/dist/types/sdk/accounts/liquidations/index.d.ts +1 -2
- package/dist/types/sdk/accounts/types.d.ts +46 -457
- package/dist/types/sdk/base/index.d.ts +2 -2
- package/dist/types/sdk/base/types.d.ts +6 -1
- package/dist/types/sdk/constants/index.d.ts +2 -2
- package/dist/types/sdk/constants/math.d.ts +5 -1
- package/dist/types/sdk/index.d.ts +16 -14
- package/dist/types/sdk/market/MarketRegister.d.ts +7 -0
- package/dist/types/sdk/market/credit/CreditFacadeV310Contract.d.ts +47 -2
- package/dist/types/sdk/market/credit/CreditSuite.d.ts +24 -2
- package/dist/types/sdk/{accounts → market/credit}/dominantCollateral.d.ts +13 -6
- package/dist/types/sdk/market/credit/index.d.ts +3 -2
- package/dist/types/sdk/market/credit/types.d.ts +112 -2
- package/dist/types/sdk/market/index.d.ts +4 -3
- package/dist/types/sdk/market/math.d.ts +60 -1
- package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +15 -4
- package/dist/types/sdk/market/oracle/PriceOracleV310Contract.d.ts +0 -10
- package/dist/types/sdk/market/oracle/index.d.ts +2 -2
- package/dist/types/sdk/market/oracle/types.d.ts +30 -14
- package/dist/types/sdk/market/rwa/securitize/SecuritizeRWAFactory.d.ts +1 -1
- package/dist/types/sdk/market/rwa/types.d.ts +1 -1
- package/dist/types/sdk/opportunities/index.d.ts +2 -2
- package/package.json +1 -1
- package/dist/cjs/sdk/accounts/constants.js +0 -12
- package/dist/esm/sdk/accounts/constants.js +0 -11
- package/dist/types/sdk/accounts/constants.d.ts +0 -11
|
@@ -2,29 +2,17 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_abi_iBaseRewardPool = require("../../abi/iBaseRewardPool.js");
|
|
3
3
|
const require_abi_ierc4626Adapter = require("../../abi/ierc4626Adapter.js");
|
|
4
4
|
const require_abi_310_generated = require("../../abi/310/generated.js");
|
|
5
|
-
const require_abi_compressors_creditAccountCompressor = require("../../abi/compressors/creditAccountCompressor.js");
|
|
6
5
|
const require_abi_compressors_peripheryCompressor = require("../../abi/compressors/peripheryCompressor.js");
|
|
7
6
|
const require_abi_compressors_rewardsCompressor = require("../../abi/compressors/rewardsCompressor.js");
|
|
8
|
-
const require_abi_rwa_iRWAFactory = require("../../abi/rwa/iRWAFactory.js");
|
|
9
|
-
const require_sdk_utils_AddressMap = require("../utils/AddressMap.js");
|
|
10
|
-
const require_sdk_utils_AddressSet = require("../utils/AddressSet.js");
|
|
11
|
-
const require_sdk_utils_AssetsMap = require("../utils/AssetsMap.js");
|
|
12
7
|
const require_sdk_constants_address_provider = require("../constants/address-provider.js");
|
|
13
8
|
const require_sdk_constants_addresses = require("../constants/addresses.js");
|
|
14
9
|
const require_sdk_constants_math = require("../constants/math.js");
|
|
15
10
|
const require_sdk_constants_versions = require("../constants/versions.js");
|
|
16
11
|
require("../constants/index.js");
|
|
17
|
-
const require_sdk_utils_hex = require("../utils/hex.js");
|
|
18
|
-
require("../utils/index.js");
|
|
19
12
|
const require_sdk_base_SDKConstruct = require("../base/SDKConstruct.js");
|
|
20
13
|
require("../base/index.js");
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
require("../utils/viem/index.js");
|
|
24
|
-
const require_sdk_market_pricefeeds_getRawPriceUpdates = require("../market/pricefeeds/getRawPriceUpdates.js");
|
|
25
|
-
require("../market/index.js");
|
|
26
|
-
require("./constants.js");
|
|
27
|
-
const require_sdk_accounts_dominantCollateral = require("./dominantCollateral.js");
|
|
14
|
+
const require_sdk_accounts_credit_account_compressor_CreditAccountCompressor = require("./credit-account-compressor/CreditAccountCompressor.js");
|
|
15
|
+
require("./credit-account-compressor/index.js");
|
|
28
16
|
const require_sdk_accounts_multicall_utils = require("./multicall-utils.js");
|
|
29
17
|
let viem = require("viem");
|
|
30
18
|
//#region src/sdk/accounts/CreditAccountsServiceV310.ts
|
|
@@ -39,268 +27,33 @@ let viem = require("viem");
|
|
|
39
27
|
**/
|
|
40
28
|
var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKConstruct {
|
|
41
29
|
#compressor;
|
|
42
|
-
|
|
43
|
-
constructor(sdk, options) {
|
|
30
|
+
constructor(sdk) {
|
|
44
31
|
super(sdk);
|
|
45
|
-
this.#
|
|
46
|
-
}
|
|
47
|
-
setBatchSize(batchSize) {
|
|
48
|
-
this.#batchSize = batchSize;
|
|
32
|
+
this.#compressor = new require_sdk_accounts_credit_account_compressor_CreditAccountCompressor.CreditAccountCompressor(sdk);
|
|
49
33
|
}
|
|
50
34
|
/**
|
|
51
35
|
* {@inheritDoc ICreditAccountsService.getCreditAccountData}
|
|
52
36
|
**/
|
|
53
37
|
async getCreditAccountData(account, blockNumber) {
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
raw = await this.client.readContract({
|
|
57
|
-
abi: require_abi_compressors_creditAccountCompressor.creditAccountCompressorAbi,
|
|
58
|
-
address: this.compressor,
|
|
59
|
-
functionName: "getCreditAccountData",
|
|
60
|
-
args: [account],
|
|
61
|
-
blockNumber,
|
|
62
|
-
gas: this.sdk.gasLimit
|
|
63
|
-
});
|
|
64
|
-
} catch (_e) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const factory = this.sdk.marketRegister.findByCreditManager(raw.creditManager).rwaFactory;
|
|
68
|
-
let ca;
|
|
69
|
-
let investor;
|
|
70
|
-
if (raw.success) {
|
|
71
|
-
ca = raw;
|
|
72
|
-
investor = await factory?.getInvestor(raw.creditAccount, false);
|
|
73
|
-
} else {
|
|
74
|
-
const { txs: priceUpdateTxs } = await this.#getUpdateForAccount(raw);
|
|
75
|
-
[ca, investor] = await require_sdk_utils_viem_simulateWithPriceUpdates.simulateWithPriceUpdates(this.client, {
|
|
76
|
-
priceUpdates: priceUpdateTxs,
|
|
77
|
-
contracts: [{
|
|
78
|
-
abi: require_abi_compressors_creditAccountCompressor.creditAccountCompressorAbi,
|
|
79
|
-
address: this.compressor,
|
|
80
|
-
functionName: "getCreditAccountData",
|
|
81
|
-
args: [account]
|
|
82
|
-
}, ...factory ? [{
|
|
83
|
-
abi: require_abi_rwa_iRWAFactory.iRWAFactoryAbi,
|
|
84
|
-
address: factory.address,
|
|
85
|
-
functionName: "getInvestor",
|
|
86
|
-
args: [raw.creditAccount]
|
|
87
|
-
}] : []],
|
|
88
|
-
blockNumber,
|
|
89
|
-
gas: this.sdk.gasLimit
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
return {
|
|
93
|
-
...ca,
|
|
94
|
-
investor
|
|
95
|
-
};
|
|
38
|
+
return this.#compressor.getCreditAccountData(account, blockNumber);
|
|
96
39
|
}
|
|
97
40
|
/**
|
|
98
41
|
* {@inheritDoc ICreditAccountsService.getCreditAccounts}
|
|
99
42
|
**/
|
|
100
43
|
async getCreditAccounts(options, blockNumber) {
|
|
101
|
-
|
|
102
|
-
const arg0 = creditManager ?? {
|
|
103
|
-
configurators: this.marketConfigurators,
|
|
104
|
-
creditManagers: [],
|
|
105
|
-
pools: [],
|
|
106
|
-
underlying: "0x0000000000000000000000000000000000000000"
|
|
107
|
-
};
|
|
108
|
-
const caFilter = {
|
|
109
|
-
owner,
|
|
110
|
-
includeZeroDebt,
|
|
111
|
-
minHealthFactor,
|
|
112
|
-
maxHealthFactor,
|
|
113
|
-
reverting: false
|
|
114
|
-
};
|
|
115
|
-
const { txs: priceUpdateTxs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(ignoreReservePrices ? { main: true } : void 0);
|
|
116
|
-
const allCAs = [];
|
|
117
|
-
let revertingOffset = 0;
|
|
118
|
-
for (const reverting of [false, true]) {
|
|
119
|
-
let offset = 0n;
|
|
120
|
-
revertingOffset = allCAs.length;
|
|
121
|
-
do {
|
|
122
|
-
const [accounts, newOffset] = await this.#getCreditAccounts(this.#batchSize ? [
|
|
123
|
-
arg0,
|
|
124
|
-
{
|
|
125
|
-
...caFilter,
|
|
126
|
-
reverting
|
|
127
|
-
},
|
|
128
|
-
offset,
|
|
129
|
-
BigInt(this.#batchSize)
|
|
130
|
-
] : [
|
|
131
|
-
arg0,
|
|
132
|
-
{
|
|
133
|
-
...caFilter,
|
|
134
|
-
reverting
|
|
135
|
-
},
|
|
136
|
-
offset
|
|
137
|
-
], priceUpdateTxs, blockNumber);
|
|
138
|
-
allCAs.push(...accounts);
|
|
139
|
-
offset = newOffset;
|
|
140
|
-
} while (offset !== 0n);
|
|
141
|
-
}
|
|
142
|
-
this.logger?.debug(`loaded ${allCAs.length} credit accounts (${allCAs.length - revertingOffset} reverting)`);
|
|
143
|
-
return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
44
|
+
return this.#compressor.getCreditAccounts(options, blockNumber);
|
|
144
45
|
}
|
|
145
46
|
/**
|
|
146
47
|
* {@inheritDoc ICreditAccountsService.getBorrowerCreditAccounts}
|
|
147
48
|
**/
|
|
148
49
|
async getBorrowerCreditAccounts(borrower, options, blockNumber) {
|
|
149
|
-
|
|
150
|
-
const { txs: priceUpdateTxs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(ignoreReservePrices ? { main: true } : void 0);
|
|
151
|
-
const rwaAccountAddresses = (await this.sdk.rwa.getInvestorData(borrower)).flatMap((d) => d.creditAccounts.map((ca) => ca.creditAccount));
|
|
152
|
-
const cmFilter = creditManager ? {
|
|
153
|
-
configurators: [],
|
|
154
|
-
creditManagers: [creditManager],
|
|
155
|
-
pools: [],
|
|
156
|
-
underlying: require_sdk_constants_addresses.ADDRESS_0X0
|
|
157
|
-
} : {
|
|
158
|
-
configurators: this.marketConfigurators,
|
|
159
|
-
creditManagers: [],
|
|
160
|
-
pools: [],
|
|
161
|
-
underlying: require_sdk_constants_addresses.ADDRESS_0X0
|
|
162
|
-
};
|
|
163
|
-
const permissiveFilter = {
|
|
164
|
-
owner: borrower,
|
|
165
|
-
includeZeroDebt: true,
|
|
166
|
-
minHealthFactor: 0n,
|
|
167
|
-
maxHealthFactor: require_sdk_constants_math.MAX_UINT256,
|
|
168
|
-
reverting: false
|
|
169
|
-
};
|
|
170
|
-
const rwaContracts = rwaAccountAddresses.map((account) => ({
|
|
171
|
-
abi: require_abi_compressors_creditAccountCompressor.creditAccountCompressorAbi,
|
|
172
|
-
address: this.compressor,
|
|
173
|
-
functionName: "getCreditAccountData",
|
|
174
|
-
args: [account]
|
|
175
|
-
}));
|
|
176
|
-
const getCreditAccountsContracts = [false, true].map((reverting) => ({
|
|
177
|
-
abi: require_abi_compressors_creditAccountCompressor.creditAccountCompressorAbi,
|
|
178
|
-
address: this.compressor,
|
|
179
|
-
functionName: "getCreditAccounts",
|
|
180
|
-
args: [
|
|
181
|
-
cmFilter,
|
|
182
|
-
{
|
|
183
|
-
...permissiveFilter,
|
|
184
|
-
reverting
|
|
185
|
-
},
|
|
186
|
-
0n
|
|
187
|
-
]
|
|
188
|
-
}));
|
|
189
|
-
const allContracts = [...rwaContracts, ...getCreditAccountsContracts];
|
|
190
|
-
const results = await require_sdk_utils_viem_simulateWithPriceUpdates.simulateWithPriceUpdates(this.client, {
|
|
191
|
-
priceUpdates: priceUpdateTxs,
|
|
192
|
-
contracts: allContracts,
|
|
193
|
-
blockNumber,
|
|
194
|
-
gas: this.sdk.gasLimit
|
|
195
|
-
});
|
|
196
|
-
const rwaResults = results.slice(0, rwaAccountAddresses.length);
|
|
197
|
-
const normalResults = results.slice(rwaAccountAddresses.length);
|
|
198
|
-
const seen = new require_sdk_utils_AddressSet.AddressSet();
|
|
199
|
-
const allCAs = [];
|
|
200
|
-
for (const ca of rwaResults) if (!seen.has(ca.creditAccount)) {
|
|
201
|
-
seen.add(ca.creditAccount);
|
|
202
|
-
allCAs.push({
|
|
203
|
-
...ca,
|
|
204
|
-
investor: borrower
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
for (const [accounts] of normalResults) for (const ca of accounts) if (!seen.has(ca.creditAccount)) {
|
|
208
|
-
seen.add(ca.creditAccount);
|
|
209
|
-
allCAs.push({
|
|
210
|
-
...ca,
|
|
211
|
-
investor: void 0
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
const filtered = allCAs.filter((ca) => {
|
|
215
|
-
if (!includeZeroDebt && ca.debt === 0n) return false;
|
|
216
|
-
if (ca.healthFactor < minHealthFactor) return false;
|
|
217
|
-
if (ca.healthFactor > maxHealthFactor) return false;
|
|
218
|
-
if (creditManager && !require_sdk_utils_hex.hexEq(ca.creditManager, creditManager)) return false;
|
|
219
|
-
return true;
|
|
220
|
-
});
|
|
221
|
-
this.logger?.debug(`loaded ${allCAs.length} borrower credit accounts (${rwaResults.length} RWA, ${filtered.length} after filter)`);
|
|
222
|
-
return filtered.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
50
|
+
return this.#compressor.getBorrowerCreditAccounts(borrower, options, blockNumber);
|
|
223
51
|
}
|
|
224
52
|
/**
|
|
225
53
|
* {@inheritDoc ICreditAccountsService.listPositions}
|
|
226
54
|
**/
|
|
227
55
|
async listPositions(props) {
|
|
228
|
-
|
|
229
|
-
const [accounts] = await Promise.all([this.getBorrowerCreditAccounts(owner, { includeZeroDebt }), this.sdk.withdrawalCompressor?.loadWithdrawableAssets()]);
|
|
230
|
-
const describable = accounts.filter((ca) => {
|
|
231
|
-
if (!ca.success) this.logger?.warn(`cannot describe position of ${this.labelAddress(ca.creditAccount)}: collateral computation failed`);
|
|
232
|
-
return ca.success;
|
|
233
|
-
});
|
|
234
|
-
const withdrawals = await Promise.all(describable.map((ca) => this.#accountWithdrawals(ca)));
|
|
235
|
-
return describable.map((ca, i) => this.#strategyPosition(ca, withdrawals[i] ?? new require_sdk_utils_AddressMap.AddressMap()));
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Builds one strategy position from an account snapshot.
|
|
239
|
-
*
|
|
240
|
-
* @param withdrawals - Delayed withdrawals of the account, keyed by the
|
|
241
|
-
* phantom token that represents them on it.
|
|
242
|
-
**/
|
|
243
|
-
#strategyPosition(ca, withdrawals) {
|
|
244
|
-
const suite = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
245
|
-
const { market } = suite;
|
|
246
|
-
const { priceOracle } = market;
|
|
247
|
-
const { pool } = market.pool;
|
|
248
|
-
const token = this.sdk.tokensMeta.mustGetToken(market.unwrappedUnderlying);
|
|
249
|
-
const totalDebtValue = ca.debt + ca.accruedInterest + ca.accruedFees;
|
|
250
|
-
const collateral = require_sdk_accounts_dominantCollateral.dominantCollateral(ca, market);
|
|
251
|
-
return {
|
|
252
|
-
kind: "strategy",
|
|
253
|
-
chainId: this.sdk.chainId,
|
|
254
|
-
creditManager: ca.creditManager,
|
|
255
|
-
creditAccount: ca.creditAccount,
|
|
256
|
-
name: collateral ? suite.strategyName(collateral) : token.symbol,
|
|
257
|
-
targetCollateral: collateral ? this.sdk.tokensMeta.mustGetToken(collateral) : null,
|
|
258
|
-
leverage: require_sdk_market_math.positionLeverage(totalDebtValue, ca.totalValue),
|
|
259
|
-
borrowApy: require_sdk_market_math.borrowApyBps(pool.baseInterestRate, suite.creditManager.feeInterest),
|
|
260
|
-
totalDebt: {
|
|
261
|
-
token,
|
|
262
|
-
value: totalDebtValue,
|
|
263
|
-
valueUsd: require_sdk_market_math.usdToNumber(ca.totalDebtUSD)
|
|
264
|
-
},
|
|
265
|
-
totalValue: {
|
|
266
|
-
token,
|
|
267
|
-
value: ca.totalValue,
|
|
268
|
-
valueUsd: require_sdk_market_math.usdToNumber(ca.totalValueUSD)
|
|
269
|
-
},
|
|
270
|
-
healthFactor: require_sdk_market_math.healthFactorBps(ca.healthFactor),
|
|
271
|
-
collaterals: ca.tokens.flatMap((t) => {
|
|
272
|
-
if ((t.mask & ca.enabledTokensMask) === 0n || t.balance <= 10n) return [];
|
|
273
|
-
return [{
|
|
274
|
-
collateral: priceOracle.toTokenAmount(t.token, t.balance),
|
|
275
|
-
quota: priceOracle.toTokenAmount(market.underlying, t.quota),
|
|
276
|
-
withdrawals: withdrawals.get(t.token) ?? []
|
|
277
|
-
}];
|
|
278
|
-
})
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Delayed withdrawals of one account, keyed by the phantom token that
|
|
283
|
-
* represents them on it, so that each collateral row can pick up its own.
|
|
284
|
-
**/
|
|
285
|
-
async #accountWithdrawals(ca) {
|
|
286
|
-
const compressor = this.sdk.withdrawalCompressor;
|
|
287
|
-
const byPhantomToken = new require_sdk_utils_AddressMap.AddressMap(void 0, "accountWithdrawals");
|
|
288
|
-
const holdsPhantomToken = ca.tokens.some((t) => t.balance > 10n && compressor?.getWithdrawalSourceToken(t.token) !== void 0);
|
|
289
|
-
if (!compressor || !holdsPhantomToken) return byPhantomToken;
|
|
290
|
-
const { priceOracle } = this.sdk.marketRegister.findByCreditManager(ca.creditManager);
|
|
291
|
-
const { claimable, pending } = await compressor.getCurrentWithdrawals(ca.creditAccount);
|
|
292
|
-
const add = (w, outputs, claimableAt) => {
|
|
293
|
-
const assets = outputs.map((o) => ({
|
|
294
|
-
isDelayed: true,
|
|
295
|
-
...priceOracle.toTokenAmount(o.token, o.amount),
|
|
296
|
-
redeemer: w.redeemer,
|
|
297
|
-
claimableAt: claimableAt === void 0 ? void 0 : Number(claimableAt)
|
|
298
|
-
}));
|
|
299
|
-
byPhantomToken.upsert(w.withdrawalPhantomToken, [...byPhantomToken.get(w.withdrawalPhantomToken) ?? [], ...assets]);
|
|
300
|
-
};
|
|
301
|
-
for (const w of claimable) add(w, w.outputs);
|
|
302
|
-
for (const w of pending) add(w, w.expectedOutputs, w.claimableAt);
|
|
303
|
-
return byPhantomToken;
|
|
56
|
+
return this.#compressor.listPositions(props);
|
|
304
57
|
}
|
|
305
58
|
/**
|
|
306
59
|
* {@inheritDoc ICreditAccountsService.getRewards}
|
|
@@ -422,7 +175,7 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
422
175
|
keepAssets,
|
|
423
176
|
debtOnly
|
|
424
177
|
});
|
|
425
|
-
const calls = await this
|
|
178
|
+
const calls = await this.prependPriceUpdates(account.creditManager, routerCloseResult.calls, account, { ignoreReservePrices });
|
|
426
179
|
let lossPolicyData;
|
|
427
180
|
if (applyLossPolicy) {
|
|
428
181
|
lossPolicyData = await this.sdk.marketRegister.findByCreditManager(account.creditManager).lossPolicy.getLiquidationData(account.creditAccount);
|
|
@@ -437,210 +190,28 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
437
190
|
};
|
|
438
191
|
}
|
|
439
192
|
/**
|
|
440
|
-
* {@inheritDoc ICreditAccountsService.defaultPartialLiquidationParams}
|
|
441
|
-
*/
|
|
442
|
-
defaultPartialLiquidationParams(ca) {
|
|
443
|
-
const tokenOut = this.#getBestTokenOut(ca);
|
|
444
|
-
const optimalHF = this.getOptimalHFForPartialLiquidation(ca);
|
|
445
|
-
const repaidAmount = this.#calcOptimalRepaidAmount(ca, tokenOut, optimalHF);
|
|
446
|
-
return {
|
|
447
|
-
tokenOut,
|
|
448
|
-
optimalHF,
|
|
449
|
-
repaidAmount,
|
|
450
|
-
minSeizedAmount: this.#calcMinSeizedAmount(ca, tokenOut, repaidAmount)
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
193
|
* {@inheritDoc ICreditAccountsService.partiallyLiquidate}
|
|
455
194
|
*/
|
|
456
195
|
async partiallyLiquidate(props) {
|
|
457
196
|
const { account, to } = props;
|
|
458
|
-
const tokenOut = props.tokenOut ?? this.#getBestTokenOut(account);
|
|
459
|
-
const optimalHF = props.optimalHF ?? this.getOptimalHFForPartialLiquidation(account);
|
|
460
|
-
const repaidAmount = props.repaidAmount ?? this.#calcOptimalRepaidAmount(account, tokenOut, optimalHF);
|
|
461
|
-
const minSeizedAmount = props.minSeizedAmount ?? this.#calcMinSeizedAmount(account, tokenOut, repaidAmount);
|
|
462
197
|
const cm = this.sdk.marketRegister.findCreditManager(account.creditManager);
|
|
198
|
+
const { tokenOut, repaidAmount, minSeizedAmount } = cm.partialLiquidationParams(account, props);
|
|
463
199
|
const updates = await this.getOnDemandPriceUpdates(account, true);
|
|
464
200
|
return cm.creditFacade.partiallyLiquidateCreditAccount(account.creditAccount, tokenOut, repaidAmount, minSeizedAmount, to, updates);
|
|
465
201
|
}
|
|
466
202
|
/**
|
|
467
|
-
* Picks the most valuable enabled non-underlying collateral token on the
|
|
468
|
-
* credit account (by oracle value in underlying).
|
|
469
|
-
*
|
|
470
|
-
* Ported from solidity:
|
|
471
|
-
* https://github.com/Gearbox-protocol/router-v3/blob/main/contracts/liquidation/AbstractLiquidator.sol#L270
|
|
472
|
-
*/
|
|
473
|
-
#getBestTokenOut(account) {
|
|
474
|
-
const market = this.sdk.marketRegister.findByCreditManager(account.creditManager);
|
|
475
|
-
const underlying = market.underlying;
|
|
476
|
-
let bestVal = 0n;
|
|
477
|
-
let bestToken;
|
|
478
|
-
for (const t of account.tokens) {
|
|
479
|
-
if (t.token === underlying) continue;
|
|
480
|
-
if ((t.mask & account.enabledTokensMask) === 0n) continue;
|
|
481
|
-
if (t.balance === 0n) continue;
|
|
482
|
-
const val = market.priceOracle.convert(t.token, underlying, t.balance);
|
|
483
|
-
if (val > bestVal) {
|
|
484
|
-
bestVal = val;
|
|
485
|
-
bestToken = t.token;
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
if (!bestToken) throw new Error(`cannot determine tokenOut for partial liquidation of ${this.sdk.labelAddress(account.creditAccount)}: no enabled non-underlying collateral with value`);
|
|
489
|
-
return bestToken;
|
|
490
|
-
}
|
|
491
|
-
/**
|
|
492
|
-
* Returns the minimum amount of `token` collateral that must be seized when
|
|
493
|
-
* repaying `repaidAmount` of underlying. Mirrors the on-chain liquidation
|
|
494
|
-
* discount math, expired-aware.
|
|
495
|
-
*/
|
|
496
|
-
#calcMinSeizedAmount(account, token, repaidAmount) {
|
|
497
|
-
const market = this.sdk.marketRegister.findByCreditManager(account.creditManager);
|
|
498
|
-
const suite = this.sdk.marketRegister.findCreditManager(account.creditManager);
|
|
499
|
-
const fee = suite.isExpired ? suite.creditManager.liquidationDiscountExpired : suite.creditManager.liquidationDiscount;
|
|
500
|
-
return market.priceOracle.convert(market.underlying, token, repaidAmount) * 9990n / BigInt(fee);
|
|
501
|
-
}
|
|
502
|
-
/**
|
|
503
|
-
* Computes the optimal `repaidAmount` (in underlying) that brings the credit
|
|
504
|
-
* account's health factor close to `optimalHF` after partial liquidation.
|
|
505
|
-
*
|
|
506
|
-
* Ported from solidity:
|
|
507
|
-
* https://github.com/Gearbox-protocol/router-v3/blob/56e2d515ec6d9bb1e324e71c3708e59710779b24/contracts/liquidation/AbstractLiquidator.sol#L292
|
|
508
|
-
*/
|
|
509
|
-
#calcOptimalRepaidAmount(account, token, optimalHF) {
|
|
510
|
-
const suite = this.sdk.marketRegister.findCreditManager(account.creditManager);
|
|
511
|
-
const market = this.sdk.marketRegister.findByCreditManager(account.creditManager);
|
|
512
|
-
const cm = suite.creditManager;
|
|
513
|
-
const feeLiquidation = suite.isExpired ? cm.feeLiquidationExpired : cm.feeLiquidation;
|
|
514
|
-
const liquidationDiscount = suite.isExpired ? cm.liquidationDiscountExpired : cm.liquidationDiscount;
|
|
515
|
-
const discount = BigInt(liquidationDiscount) - BigInt(feeLiquidation);
|
|
516
|
-
const ltTokenOut = cm.liquidationThresholds.get(token);
|
|
517
|
-
if (ltTokenOut === void 0) throw new Error(`token ${this.sdk.labelAddress(token)} is not a collateral token in credit manager ${this.sdk.labelAddress(account.creditManager)}`);
|
|
518
|
-
const totalDebt = account.debt + account.accruedInterest + account.accruedFees;
|
|
519
|
-
const twvUnderlying = market.priceOracle.convertFromUSD(market.underlying, account.twvUSD);
|
|
520
|
-
const denominator = discount * optimalHF / require_sdk_constants_math.PERCENTAGE_FACTOR - BigInt(ltTokenOut);
|
|
521
|
-
if (denominator <= 0n) throw new Error("cannot compute optimal repaid amount: invalid liquidation parameters (discount * hfOptimal <= ltTokenOut)");
|
|
522
|
-
const numerator = totalDebt * optimalHF - twvUnderlying * require_sdk_constants_math.PERCENTAGE_FACTOR;
|
|
523
|
-
if (numerator <= 0n) return 0n;
|
|
524
|
-
let repaidAmount = numerator / denominator * discount / require_sdk_constants_math.PERCENTAGE_FACTOR;
|
|
525
|
-
const minDebt = suite.creditFacade.minDebt;
|
|
526
|
-
if (totalDebt < minDebt) return 0n;
|
|
527
|
-
const surplusDebt = totalDebt - minDebt;
|
|
528
|
-
if (repaidAmount > surplusDebt) repaidAmount = surplusDebt * 999n / 1000n;
|
|
529
|
-
return repaidAmount;
|
|
530
|
-
}
|
|
531
|
-
/**
|
|
532
|
-
* {@inheritDoc ICreditAccountsService.closeCreditAccount}
|
|
533
|
-
**/
|
|
534
|
-
async closeCreditAccount({ operation, assetsToWithdraw, creditAccount: ca, to, slippage = 50n, closePath }) {
|
|
535
|
-
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
536
|
-
const routerCloseResult = closePath || await this.sdk.routerFor(ca).findBestClosePath({
|
|
537
|
-
creditAccount: ca,
|
|
538
|
-
creditManager: cm.creditManager,
|
|
539
|
-
slippage
|
|
540
|
-
});
|
|
541
|
-
const operationCalls = await this.assembleCloseCreditAccountCalls({
|
|
542
|
-
creditAccount: ca,
|
|
543
|
-
routerCalls: routerCloseResult.calls,
|
|
544
|
-
assetsToWithdraw,
|
|
545
|
-
to
|
|
546
|
-
});
|
|
547
|
-
const calls = operation === "close" ? operationCalls : await this.#prependPriceUpdates(ca.creditManager, operationCalls, ca);
|
|
548
|
-
return {
|
|
549
|
-
tx: await this.#closeCreditAccountTx(cm, ca.creditAccount, calls, operation),
|
|
550
|
-
calls,
|
|
551
|
-
routerCloseResult,
|
|
552
|
-
creditFacade: cm.creditFacade
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
203
|
* {@inheritDoc ICreditAccountsService.assembleCloseCreditAccountCalls}
|
|
557
204
|
*/
|
|
558
205
|
async assembleCloseCreditAccountCalls({ creditAccount: ca, routerCalls, assetsToWithdraw, to }) {
|
|
559
|
-
const unwrapCalls = await this.
|
|
206
|
+
const unwrapCalls = await this.assembleRedeemDiffCalls(1n, ca.creditManager) ?? [];
|
|
207
|
+
const { creditFacade } = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
560
208
|
return [
|
|
561
209
|
...routerCalls,
|
|
562
|
-
...
|
|
563
|
-
...
|
|
564
|
-
...unwrapCalls,
|
|
565
|
-
...assetsToWithdraw.map((t) => this.prepareWithdrawToken(ca.creditFacade, t, require_sdk_constants_math.MAX_UINT256, to))
|
|
566
|
-
];
|
|
567
|
-
}
|
|
568
|
-
/**
|
|
569
|
-
* {@inheritDoc ICreditAccountsService.updateQuotas}
|
|
570
|
-
**/
|
|
571
|
-
async updateQuotas({ minQuota, averageQuota, creditAccount }) {
|
|
572
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
573
|
-
const operationCalls = this.prepareUpdateQuotas(creditAccount.creditFacade, {
|
|
574
|
-
minQuota,
|
|
575
|
-
averageQuota
|
|
576
|
-
});
|
|
577
|
-
const calls = await this.#prependPriceUpdates(creditAccount.creditManager, operationCalls, creditAccount);
|
|
578
|
-
return {
|
|
579
|
-
tx: await this.#multicallTx(cm, creditAccount.creditAccount, calls),
|
|
580
|
-
calls,
|
|
581
|
-
creditFacade: cm.creditFacade
|
|
582
|
-
};
|
|
583
|
-
}
|
|
584
|
-
/**
|
|
585
|
-
* {@inheritDoc ICreditAccountsService.addCollateral}
|
|
586
|
-
**/
|
|
587
|
-
async addCollateral({ creditAccount, asset, permit, ethAmount, minQuota, averageQuota }) {
|
|
588
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
589
|
-
const operationCalls = [...this.prepareAddCollateral(creditAccount.creditFacade, [asset], permit ? { [asset.token]: permit } : {}), ...this.prepareUpdateQuotas(creditAccount.creditFacade, {
|
|
590
|
-
minQuota,
|
|
591
|
-
averageQuota
|
|
592
|
-
})];
|
|
593
|
-
const calls = await this.#prependPriceUpdates(creditAccount.creditManager, operationCalls, creditAccount);
|
|
594
|
-
const tx = await this.#multicallTx(cm, creditAccount.creditAccount, calls);
|
|
595
|
-
tx.value = ethAmount.toString(10);
|
|
596
|
-
return {
|
|
597
|
-
tx,
|
|
598
|
-
calls,
|
|
599
|
-
creditFacade: cm.creditFacade
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* {@inheritDoc ICreditAccountsService.changeDebt}
|
|
604
|
-
**/
|
|
605
|
-
async changeDebt({ creditAccount, amount, collateral }) {
|
|
606
|
-
if (amount === 0n) throw new Error("debt increase or decrease must be non-zero");
|
|
607
|
-
const isDecrease = amount < 0n;
|
|
608
|
-
const change = amount > 0n ? amount : -amount;
|
|
609
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
610
|
-
const addCollateralCalls = collateral && isDecrease ? this.prepareAddCollateral(creditAccount.creditFacade, [{
|
|
611
|
-
token: collateral[0].token,
|
|
612
|
-
balance: collateral[0].balance
|
|
613
|
-
}], {}) : [];
|
|
614
|
-
const unwrapCalls = collateral && isDecrease ? await this.getRWAUnwrapCalls(collateral[0].balance, creditAccount.creditManager) || [] : [];
|
|
615
|
-
if (addCollateralCalls.length > 0 && unwrapCalls.length === 0 && collateral && collateral?.[0].token !== creditAccount.underlying) throw new Error("Can't use collateral other than underlying for non RWA market");
|
|
616
|
-
const operationCalls = [
|
|
617
|
-
...addCollateralCalls,
|
|
210
|
+
...creditFacade.prepareDisableQuotas([...ca.tokens]),
|
|
211
|
+
...ca.debt > 0n ? [creditFacade.prepareDecreaseDebtFull()] : [],
|
|
618
212
|
...unwrapCalls,
|
|
619
|
-
|
|
213
|
+
...assetsToWithdraw.map((t) => creditFacade.prepareWithdrawCollateral(t, require_sdk_constants_math.MAX_UINT256, to))
|
|
620
214
|
];
|
|
621
|
-
const calls = await this.#prependPriceUpdates(creditAccount.creditManager, operationCalls, creditAccount);
|
|
622
|
-
return {
|
|
623
|
-
tx: await this.#multicallTx(cm, creditAccount.creditAccount, calls),
|
|
624
|
-
calls,
|
|
625
|
-
creditFacade: cm.creditFacade
|
|
626
|
-
};
|
|
627
|
-
}
|
|
628
|
-
/**
|
|
629
|
-
* {@inheritDoc ICreditAccountsService.executeSwap}
|
|
630
|
-
**/
|
|
631
|
-
async executeSwap({ creditAccount, calls: swapCalls, minQuota, averageQuota }) {
|
|
632
|
-
if (swapCalls.length === 0) throw new Error("No path to execute");
|
|
633
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
634
|
-
const operationCalls = [...swapCalls, ...this.prepareUpdateQuotas(creditAccount.creditFacade, {
|
|
635
|
-
minQuota,
|
|
636
|
-
averageQuota
|
|
637
|
-
})];
|
|
638
|
-
const calls = await this.#prependPriceUpdates(creditAccount.creditManager, operationCalls, creditAccount);
|
|
639
|
-
return {
|
|
640
|
-
tx: await this.#multicallTx(cm, creditAccount.creditAccount, calls),
|
|
641
|
-
calls,
|
|
642
|
-
creditFacade: cm.creditFacade
|
|
643
|
-
};
|
|
644
215
|
}
|
|
645
216
|
/**
|
|
646
217
|
* {@inheritDoc ICreditAccountsService.previewDelayedWithdrawal}
|
|
@@ -665,25 +236,6 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
665
236
|
};
|
|
666
237
|
}
|
|
667
238
|
/**
|
|
668
|
-
* {@inheritDoc ICreditAccountsService.startDelayedWithdrawal}
|
|
669
|
-
**/
|
|
670
|
-
async startDelayedWithdrawal({ creditAccount, minQuota, averageQuota, preview }) {
|
|
671
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
672
|
-
const operationCalls = [...this.assembleStartDelayedWithdrawalCalls({
|
|
673
|
-
creditFacade: cm.creditFacade.address,
|
|
674
|
-
preview
|
|
675
|
-
}), ...this.prepareUpdateQuotas(cm.creditFacade.address, {
|
|
676
|
-
minQuota,
|
|
677
|
-
averageQuota
|
|
678
|
-
})];
|
|
679
|
-
const calls = await this.#prependPriceUpdates(creditAccount.creditManager, operationCalls, creditAccount);
|
|
680
|
-
return {
|
|
681
|
-
tx: await this.#multicallTx(cm, creditAccount.creditAccount, calls),
|
|
682
|
-
calls,
|
|
683
|
-
creditFacade: cm.creditFacade
|
|
684
|
-
};
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
239
|
* {@inheritDoc ICreditAccountsService.assembleStartDelayedWithdrawalCalls}
|
|
688
240
|
**/
|
|
689
241
|
assembleStartDelayedWithdrawalCalls({ creditFacade, preview }) {
|
|
@@ -700,50 +252,14 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
700
252
|
token: preview.token,
|
|
701
253
|
amount: -preview.amountIn
|
|
702
254
|
});
|
|
703
|
-
const
|
|
704
|
-
target: creditFacade,
|
|
705
|
-
callData: (0, viem.encodeFunctionData)({
|
|
706
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
707
|
-
functionName: "storeExpectedBalances",
|
|
708
|
-
args: [deltas]
|
|
709
|
-
})
|
|
710
|
-
};
|
|
711
|
-
const compareBalances = {
|
|
712
|
-
target: creditFacade,
|
|
713
|
-
callData: (0, viem.encodeFunctionData)({
|
|
714
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
715
|
-
functionName: "compareBalances",
|
|
716
|
-
args: []
|
|
717
|
-
})
|
|
718
|
-
};
|
|
255
|
+
const facade = this.sdk.marketRegister.findCreditFacade(creditFacade);
|
|
719
256
|
return [
|
|
720
|
-
|
|
257
|
+
facade.prepareStoreExpectedBalances(deltas),
|
|
721
258
|
...preview.requestCalls,
|
|
722
|
-
|
|
259
|
+
facade.prepareCompareBalances()
|
|
723
260
|
];
|
|
724
261
|
}
|
|
725
262
|
/**
|
|
726
|
-
* {@inheritDoc ICreditAccountsService.claimDelayed}
|
|
727
|
-
**/
|
|
728
|
-
async claimDelayed({ creditAccount, minQuota, averageQuota, claimableNow }) {
|
|
729
|
-
const zeroDebt = creditAccount.debt === 0n;
|
|
730
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
731
|
-
const quotaCalls = zeroDebt ? [] : this.prepareUpdateQuotas(cm.creditFacade.address, {
|
|
732
|
-
minQuota,
|
|
733
|
-
averageQuota
|
|
734
|
-
});
|
|
735
|
-
const operationCalls = [...this.assembleClaimDelayedCalls({
|
|
736
|
-
creditFacade: cm.creditFacade.address,
|
|
737
|
-
claimableNow
|
|
738
|
-
}), ...quotaCalls];
|
|
739
|
-
const calls = zeroDebt ? operationCalls : await this.#prependPriceUpdates(creditAccount.creditManager, operationCalls, creditAccount);
|
|
740
|
-
return {
|
|
741
|
-
tx: await this.#multicallTx(cm, creditAccount.creditAccount, calls),
|
|
742
|
-
calls,
|
|
743
|
-
creditFacade: cm.creditFacade
|
|
744
|
-
};
|
|
745
|
-
}
|
|
746
|
-
/**
|
|
747
263
|
* {@inheritDoc ICreditAccountsService.assembleClaimDelayedCalls}
|
|
748
264
|
**/
|
|
749
265
|
assembleClaimDelayedCalls({ creditFacade, claimableNow }) {
|
|
@@ -760,26 +276,11 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
760
276
|
token: claimableNow.withdrawalPhantomToken,
|
|
761
277
|
amount: -claimableNow.withdrawalTokenSpent
|
|
762
278
|
});
|
|
763
|
-
const
|
|
764
|
-
target: creditFacade,
|
|
765
|
-
callData: (0, viem.encodeFunctionData)({
|
|
766
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
767
|
-
functionName: "storeExpectedBalances",
|
|
768
|
-
args: [deltas]
|
|
769
|
-
})
|
|
770
|
-
};
|
|
771
|
-
const compareBalances = {
|
|
772
|
-
target: creditFacade,
|
|
773
|
-
callData: (0, viem.encodeFunctionData)({
|
|
774
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
775
|
-
functionName: "compareBalances",
|
|
776
|
-
args: []
|
|
777
|
-
})
|
|
778
|
-
};
|
|
279
|
+
const facade = this.sdk.marketRegister.findCreditFacade(creditFacade);
|
|
779
280
|
return [
|
|
780
|
-
|
|
281
|
+
facade.prepareStoreExpectedBalances(deltas),
|
|
781
282
|
...claimableNow.claimCalls,
|
|
782
|
-
|
|
283
|
+
facade.prepareCompareBalances()
|
|
783
284
|
];
|
|
784
285
|
}
|
|
785
286
|
/**
|
|
@@ -810,185 +311,94 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
810
311
|
let tokenToWithdraw;
|
|
811
312
|
if (withdrawToken === true) tokenToWithdraw = cm.underlying;
|
|
812
313
|
else if (typeof withdrawToken === "string") tokenToWithdraw = withdrawToken;
|
|
314
|
+
const { creditFacade } = cmSuite;
|
|
813
315
|
const operationCalls = [
|
|
814
|
-
|
|
815
|
-
...
|
|
316
|
+
creditFacade.prepareIncreaseDebt(debt),
|
|
317
|
+
...creditFacade.prepareAddCollateral(collateral, permits),
|
|
816
318
|
...openPathCalls,
|
|
817
|
-
...tokenToWithdraw ? [
|
|
818
|
-
...
|
|
319
|
+
...tokenToWithdraw ? [creditFacade.prepareWithdrawCollateral(tokenToWithdraw, require_sdk_constants_math.MAX_UINT256, to)] : [],
|
|
320
|
+
...creditFacade.prepareUpdateQuotas({
|
|
819
321
|
minQuota,
|
|
820
322
|
averageQuota
|
|
821
323
|
}),
|
|
822
324
|
...callsAfter ?? []
|
|
823
325
|
];
|
|
824
|
-
const calls = await this
|
|
326
|
+
const calls = await this.prependPriceUpdates(cm.address, operationCalls);
|
|
825
327
|
let tx;
|
|
826
328
|
if (reopenCreditAccount) tx = await this.#multicallTx(cmSuite, reopenCreditAccount, calls);
|
|
827
329
|
else tx = await this.#openCreditAccountTx(cmSuite, to, calls, referralCode, rwaOptions);
|
|
828
330
|
tx.value = ethAmount.toString(10);
|
|
829
|
-
return
|
|
830
|
-
calls,
|
|
831
|
-
tx,
|
|
832
|
-
creditFacade: cmSuite.creditFacade
|
|
833
|
-
};
|
|
834
|
-
}
|
|
835
|
-
/**
|
|
836
|
-
* {@inheritDoc ICreditAccountsService.getBorrowRate}
|
|
837
|
-
**/
|
|
838
|
-
getBorrowRate(ca) {
|
|
839
|
-
const { creditManager } = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
840
|
-
const { pool } = this.sdk.marketRegister.findByCreditManager(ca.creditManager);
|
|
841
|
-
const { feeInterest } = creditManager;
|
|
842
|
-
const { baseInterestRate } = pool.pool;
|
|
843
|
-
const baseRateWithFee = baseInterestRate * (BigInt(feeInterest) + require_sdk_constants_math.PERCENTAGE_FACTOR);
|
|
844
|
-
const totalDebt = ca.debt + ca.accruedInterest + ca.accruedFees;
|
|
845
|
-
const r = ca.debt * baseRateWithFee / (totalDebt * require_sdk_constants_math.RAY);
|
|
846
|
-
const caTokens = new require_sdk_utils_AddressMap.AddressMap(ca.tokens.map((t) => [t.token, t]));
|
|
847
|
-
let qr = 0n;
|
|
848
|
-
for (const t of creditManager.collateralTokens) {
|
|
849
|
-
const b = caTokens.get(t);
|
|
850
|
-
if (b) qr += b.quota * BigInt(pool.pqk.quotas.get(t)?.rate ?? 0);
|
|
851
|
-
}
|
|
852
|
-
qr = qr * (BigInt(feeInterest) + require_sdk_constants_math.PERCENTAGE_FACTOR) / require_sdk_constants_math.PERCENTAGE_FACTOR;
|
|
853
|
-
qr /= totalDebt;
|
|
854
|
-
return r + qr;
|
|
855
|
-
}
|
|
856
|
-
/**
|
|
857
|
-
* {@inheritDoc ICreditAccountsService.getOptimalHFForPartialLiquidation}
|
|
858
|
-
**/
|
|
859
|
-
getOptimalHFForPartialLiquidation(ca) {
|
|
860
|
-
const borrowRate = this.getBorrowRate(ca);
|
|
861
|
-
return require_sdk_constants_math.PERCENTAGE_FACTOR + (borrowRate < 100n ? borrowRate : 100n);
|
|
862
|
-
}
|
|
863
|
-
/**
|
|
864
|
-
* Internal wrapper for CreditAccountCompressor.getCreditAccounts + price updates wrapped into multicall
|
|
865
|
-
* @param args
|
|
866
|
-
* @param priceUpdateTxs
|
|
867
|
-
* @param blockNumber
|
|
868
|
-
* @returns
|
|
869
|
-
*/
|
|
870
|
-
async #getCreditAccounts(args, priceUpdateTxs, blockNumber) {
|
|
871
|
-
let resp;
|
|
872
|
-
if (priceUpdateTxs?.length) [resp] = await require_sdk_utils_viem_simulateWithPriceUpdates.simulateWithPriceUpdates(this.client, {
|
|
873
|
-
priceUpdates: priceUpdateTxs,
|
|
874
|
-
contracts: [{
|
|
875
|
-
abi: require_abi_compressors_creditAccountCompressor.creditAccountCompressorAbi,
|
|
876
|
-
address: this.compressor,
|
|
877
|
-
functionName: "getCreditAccounts",
|
|
878
|
-
args
|
|
879
|
-
}],
|
|
880
|
-
blockNumber,
|
|
881
|
-
gas: this.sdk.gasLimit
|
|
882
|
-
});
|
|
883
|
-
else resp = await this.client.readContract({
|
|
884
|
-
abi: require_abi_compressors_creditAccountCompressor.creditAccountCompressorAbi,
|
|
885
|
-
address: this.compressor,
|
|
886
|
-
functionName: "getCreditAccounts",
|
|
887
|
-
args,
|
|
888
|
-
blockNumber,
|
|
889
|
-
gas: this.sdk.gasLimit
|
|
890
|
-
});
|
|
891
|
-
this.logger?.debug({
|
|
892
|
-
accounts: resp[0]?.length ?? 0,
|
|
893
|
-
nextOffset: Number(resp[1])
|
|
894
|
-
}, "got credit accounts");
|
|
895
|
-
return resp;
|
|
331
|
+
return tx;
|
|
896
332
|
}
|
|
897
333
|
/**
|
|
898
|
-
*
|
|
899
|
-
*
|
|
900
|
-
*
|
|
901
|
-
* @param amount -
|
|
334
|
+
* Encodes one ERC-4626 adapter call for an RWA market's underlying vault.
|
|
335
|
+
*
|
|
336
|
+
* @param functionName - Adapter function to call
|
|
337
|
+
* @param amount - Amount passed to the adapter, in the units the function expects
|
|
902
338
|
* @param creditManager - Credit manager address
|
|
903
|
-
* @returns Array of MultiCall to pass to credit facade multicall, or undefined
|
|
339
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined
|
|
340
|
+
* if the underlying is not RWA-gated or no adapter is configured for it
|
|
904
341
|
*/
|
|
905
|
-
|
|
342
|
+
#rwaVaultCalls(functionName, amount, creditManager) {
|
|
906
343
|
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
907
344
|
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
908
345
|
if (!this.sdk.tokensMeta.isRWAUnderlying(meta)) return;
|
|
909
|
-
const
|
|
910
|
-
if (!
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
346
|
+
const target = suite.creditManager.adapters.get(meta.addr)?.address;
|
|
347
|
+
if (!target) return;
|
|
348
|
+
let callData;
|
|
349
|
+
switch (functionName) {
|
|
350
|
+
case "deposit":
|
|
351
|
+
callData = (0, viem.encodeFunctionData)({
|
|
352
|
+
abi: require_abi_ierc4626Adapter.ierc4626AdapterAbi,
|
|
353
|
+
functionName,
|
|
354
|
+
args: [amount, require_sdk_constants_addresses.ADDRESS_0X0]
|
|
355
|
+
});
|
|
356
|
+
break;
|
|
357
|
+
case "redeem":
|
|
358
|
+
callData = (0, viem.encodeFunctionData)({
|
|
359
|
+
abi: require_abi_ierc4626Adapter.ierc4626AdapterAbi,
|
|
360
|
+
functionName,
|
|
361
|
+
args: [
|
|
362
|
+
amount,
|
|
363
|
+
require_sdk_constants_addresses.ADDRESS_0X0,
|
|
364
|
+
require_sdk_constants_addresses.ADDRESS_0X0
|
|
365
|
+
]
|
|
366
|
+
});
|
|
367
|
+
break;
|
|
368
|
+
default: callData = (0, viem.encodeFunctionData)({
|
|
914
369
|
abi: require_abi_ierc4626Adapter.ierc4626AdapterAbi,
|
|
915
|
-
functionName
|
|
916
|
-
args: [
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
370
|
+
functionName,
|
|
371
|
+
args: [amount]
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
return [{
|
|
375
|
+
target,
|
|
376
|
+
callData
|
|
922
377
|
}];
|
|
923
378
|
}
|
|
924
379
|
/**
|
|
925
|
-
*
|
|
926
|
-
* Used when adding debt on a RWA market: deposits underlying into the adapter vault so shares are minted on the account.
|
|
927
|
-
* Only applies when the credit manager's underlying is RWA-gated and has an ERC-4626 adapter configured.
|
|
928
|
-
* @param amount - Amount of underlying assets to deposit into the vault (in underlying decimals)
|
|
929
|
-
* @param creditManager - Credit manager address
|
|
930
|
-
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not RWA or no adapter is configured
|
|
380
|
+
* {@inheritDoc ICreditAccountsService.assembleRWAUnwrapCalls}
|
|
931
381
|
*/
|
|
932
|
-
async
|
|
933
|
-
|
|
934
|
-
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
935
|
-
if (!this.sdk.tokensMeta.isRWAUnderlying(meta)) return;
|
|
936
|
-
const adapterAddress = suite.creditManager.adapters.get(meta.addr)?.address;
|
|
937
|
-
if (!adapterAddress) return;
|
|
938
|
-
return [{
|
|
939
|
-
target: adapterAddress,
|
|
940
|
-
callData: (0, viem.encodeFunctionData)({
|
|
941
|
-
abi: require_abi_ierc4626Adapter.ierc4626AdapterAbi,
|
|
942
|
-
functionName: "deposit",
|
|
943
|
-
args: [amount, require_sdk_constants_addresses.ADDRESS_0X0]
|
|
944
|
-
})
|
|
945
|
-
}];
|
|
382
|
+
async assembleRWAUnwrapCalls(amount, creditManager) {
|
|
383
|
+
return this.#rwaVaultCalls("redeem", amount, creditManager);
|
|
946
384
|
}
|
|
947
385
|
/**
|
|
948
|
-
*
|
|
949
|
-
* Redeems the leftover vault shares (e.g. after repaying debt) so the account does not hold excess RWA vault tokens.
|
|
950
|
-
* Only applies when the credit manager's underlying is RWA-gated and has an ERC-4626 adapter configured.
|
|
951
|
-
* @param amount - Leftover vault share amount to redeem (in adapter/vault decimals)
|
|
952
|
-
* @param creditManager - Credit manager address
|
|
953
|
-
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not RWA or no adapter is configured
|
|
386
|
+
* {@inheritDoc ICreditAccountsService.assembleRWAWrapCalls}
|
|
954
387
|
*/
|
|
955
|
-
async
|
|
956
|
-
|
|
957
|
-
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
958
|
-
if (!this.sdk.tokensMeta.isRWAUnderlying(meta)) return;
|
|
959
|
-
const adapterAddress = suite.creditManager.adapters.get(meta.addr)?.address;
|
|
960
|
-
if (!adapterAddress) return;
|
|
961
|
-
return [{
|
|
962
|
-
target: adapterAddress,
|
|
963
|
-
callData: (0, viem.encodeFunctionData)({
|
|
964
|
-
abi: require_abi_ierc4626Adapter.ierc4626AdapterAbi,
|
|
965
|
-
functionName: "redeemDiff",
|
|
966
|
-
args: [amount]
|
|
967
|
-
})
|
|
968
|
-
}];
|
|
388
|
+
async assembleRWAWrapCalls(amount, creditManager) {
|
|
389
|
+
return this.#rwaVaultCalls("deposit", amount, creditManager);
|
|
969
390
|
}
|
|
970
391
|
/**
|
|
971
|
-
*
|
|
972
|
-
* Deposits the leftover underlying (e.g. after decreasing debt) into the vault so the account does not hold excess underlying.
|
|
973
|
-
* Only applies when the credit manager's underlying is RWA-gated and has an ERC-4626 adapter configured.
|
|
974
|
-
* @param amount - Leftover underlying amount to deposit into the vault (in underlying decimals)
|
|
975
|
-
* @param creditManager - Credit manager address
|
|
976
|
-
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not RWA or no adapter is configured
|
|
392
|
+
* {@inheritDoc ICreditAccountsService.assembleRedeemDiffCalls}
|
|
977
393
|
*/
|
|
978
|
-
async
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
callData: (0, viem.encodeFunctionData)({
|
|
987
|
-
abi: require_abi_ierc4626Adapter.ierc4626AdapterAbi,
|
|
988
|
-
functionName: "depositDiff",
|
|
989
|
-
args: [amount]
|
|
990
|
-
})
|
|
991
|
-
}];
|
|
394
|
+
async assembleRedeemDiffCalls(amount, creditManager) {
|
|
395
|
+
return this.#rwaVaultCalls("redeemDiff", amount, creditManager);
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* {@inheritDoc ICreditAccountsService.assembleDepositDiffCalls}
|
|
399
|
+
*/
|
|
400
|
+
async assembleDepositDiffCalls(amount, creditManager) {
|
|
401
|
+
return this.#rwaVaultCalls("depositDiff", amount, creditManager);
|
|
992
402
|
}
|
|
993
403
|
/**
|
|
994
404
|
* {@inheritDoc ICreditAccountsService.setBot}
|
|
@@ -1010,15 +420,8 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
1010
420
|
stateMutability: "view"
|
|
1011
421
|
}]
|
|
1012
422
|
}).read.requiredPermissions();
|
|
1013
|
-
const addBotCall =
|
|
1014
|
-
|
|
1015
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1016
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1017
|
-
functionName: "setBotPermissions",
|
|
1018
|
-
args: [botAddress, permissions]
|
|
1019
|
-
})
|
|
1020
|
-
};
|
|
1021
|
-
const calls = targetContract.type === "creditAccount" ? await this.#prependPriceUpdates(targetContract.creditManager, [addBotCall], targetContract) : [addBotCall];
|
|
423
|
+
const addBotCall = cm.creditFacade.prepareSetBotPermissions(botAddress, permissions);
|
|
424
|
+
const calls = targetContract.type === "creditAccount" ? await this.prependPriceUpdates(targetContract.creditManager, [addBotCall], targetContract) : [addBotCall];
|
|
1022
425
|
return {
|
|
1023
426
|
tx: targetContract.type === "creditAccount" ? await this.#multicallTx(cm, targetContract.creditAccount, calls) : void 0,
|
|
1024
427
|
calls,
|
|
@@ -1026,79 +429,26 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
1026
429
|
};
|
|
1027
430
|
}
|
|
1028
431
|
/**
|
|
1029
|
-
* {@inheritDoc ICreditAccountsService.withdrawCollateral}
|
|
1030
|
-
*/
|
|
1031
|
-
async withdrawCollateral({ creditAccount, assetsToWithdraw, to, minQuota, averageQuota }) {
|
|
1032
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
1033
|
-
const operationCalls = [...assetsToWithdraw.map((a) => this.prepareWithdrawToken(cm.creditFacade.address, a.token, a.balance, to)), ...this.prepareUpdateQuotas(cm.creditFacade.address, {
|
|
1034
|
-
minQuota,
|
|
1035
|
-
averageQuota
|
|
1036
|
-
})];
|
|
1037
|
-
const calls = await this.#prependPriceUpdates(creditAccount.creditManager, operationCalls, creditAccount);
|
|
1038
|
-
return {
|
|
1039
|
-
tx: await this.#multicallTx(cm, creditAccount.creditAccount, calls),
|
|
1040
|
-
calls,
|
|
1041
|
-
creditFacade: cm.creditFacade
|
|
1042
|
-
};
|
|
1043
|
-
}
|
|
1044
|
-
/**
|
|
1045
|
-
* {@inheritDoc ICreditAccountsService.repayCreditAccount}
|
|
1046
|
-
*/
|
|
1047
|
-
async repayCreditAccount(props) {
|
|
1048
|
-
const { operation, creditAccount: ca } = props;
|
|
1049
|
-
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
1050
|
-
const operationCalls = await this.assembleRepayCreditAccountCalls(props);
|
|
1051
|
-
const calls = operation === "close" ? operationCalls : await this.#prependPriceUpdates(ca.creditManager, operationCalls, ca);
|
|
1052
|
-
return {
|
|
1053
|
-
tx: await this.#closeCreditAccountTx(cm, ca.creditAccount, calls, operation),
|
|
1054
|
-
calls,
|
|
1055
|
-
creditFacade: cm.creditFacade
|
|
1056
|
-
};
|
|
1057
|
-
}
|
|
1058
|
-
/**
|
|
1059
432
|
* {@inheritDoc ICreditAccountsService.assembleRepayCreditAccountCalls}
|
|
1060
433
|
*/
|
|
1061
434
|
async assembleRepayCreditAccountCalls({ collateralAssets, assetsToWithdraw, creditAccount: ca, permits, to, tokensToClaim, calls: wrapCalls = [] }) {
|
|
1062
435
|
const addCollateral = collateralAssets.filter((a) => a.balance > 0);
|
|
1063
436
|
const router = this.sdk.routerFor(ca);
|
|
1064
|
-
const unwrapCalls = await this.
|
|
437
|
+
const unwrapCalls = await this.assembleRedeemDiffCalls(1n, ca.creditManager) ?? [];
|
|
1065
438
|
const claimPath = await router.findClaimAllRewards({
|
|
1066
439
|
tokensToClaim,
|
|
1067
440
|
creditAccount: ca
|
|
1068
441
|
});
|
|
442
|
+
const { creditFacade } = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
1069
443
|
return [
|
|
1070
|
-
...
|
|
444
|
+
...creditFacade.prepareAddCollateral(addCollateral, permits),
|
|
1071
445
|
...wrapCalls,
|
|
1072
|
-
...
|
|
1073
|
-
...
|
|
446
|
+
...creditFacade.prepareDisableQuotas([...ca.tokens]),
|
|
447
|
+
...ca.debt > 0n ? [creditFacade.prepareDecreaseDebtFull()] : [],
|
|
1074
448
|
...unwrapCalls,
|
|
1075
449
|
...claimPath.calls,
|
|
1076
|
-
...assetsToWithdraw.map((t) =>
|
|
1077
|
-
];
|
|
1078
|
-
}
|
|
1079
|
-
/**
|
|
1080
|
-
* {@inheritDoc ICreditAccountsService.repayAndLiquidateCreditAccount}
|
|
1081
|
-
*/
|
|
1082
|
-
async repayAndLiquidateCreditAccount({ collateralAssets, assetsToWithdraw, creditAccount: ca, permits, to, tokensToClaim }) {
|
|
1083
|
-
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
1084
|
-
const claimPath = await this.sdk.routerFor(ca).findClaimAllRewards({
|
|
1085
|
-
tokensToClaim,
|
|
1086
|
-
creditAccount: ca
|
|
1087
|
-
});
|
|
1088
|
-
const wrapCalls = await this.getDepositDiffCalls(1n, ca.creditManager) ?? [];
|
|
1089
|
-
const addCollateral = collateralAssets.filter((a) => a.balance > 0);
|
|
1090
|
-
const operationCalls = [
|
|
1091
|
-
...this.prepareAddCollateral(ca.creditFacade, addCollateral, permits),
|
|
1092
|
-
...claimPath.calls,
|
|
1093
|
-
...wrapCalls,
|
|
1094
|
-
...assetsToWithdraw.map((t) => this.prepareWithdrawToken(ca.creditFacade, t.token, require_sdk_constants_math.MAX_UINT256, to))
|
|
450
|
+
...assetsToWithdraw.map((t) => creditFacade.prepareWithdrawCollateral(t.token, require_sdk_constants_math.MAX_UINT256, to))
|
|
1095
451
|
];
|
|
1096
|
-
const calls = await this.#prependPriceUpdates(ca.creditManager, operationCalls, ca);
|
|
1097
|
-
return {
|
|
1098
|
-
tx: cm.creditFacade.liquidateCreditAccount(ca.creditAccount, to, calls),
|
|
1099
|
-
calls,
|
|
1100
|
-
creditFacade: cm.creditFacade
|
|
1101
|
-
};
|
|
1102
452
|
}
|
|
1103
453
|
/**
|
|
1104
454
|
* {@inheritDoc ICreditAccountsService.claimFarmRewards}
|
|
@@ -1113,138 +463,59 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
1113
463
|
creditAccount: ca
|
|
1114
464
|
});
|
|
1115
465
|
if (claimPath.calls.length === 0) throw new Error("No path to execute");
|
|
1116
|
-
const operationCalls = [...claimPath.calls, ...
|
|
466
|
+
const operationCalls = [...claimPath.calls, ...cm.creditFacade.prepareUpdateQuotas({
|
|
1117
467
|
minQuota,
|
|
1118
468
|
averageQuota
|
|
1119
469
|
})];
|
|
1120
|
-
const calls = await this
|
|
1121
|
-
return
|
|
1122
|
-
tx: await this.#multicallTx(cm, ca.creditAccount, calls),
|
|
1123
|
-
calls,
|
|
1124
|
-
creditFacade: cm.creditFacade
|
|
1125
|
-
};
|
|
470
|
+
const calls = await this.prependPriceUpdates(ca.creditManager, operationCalls, ca);
|
|
471
|
+
return await this.#multicallTx(cm, ca.creditAccount, calls);
|
|
1126
472
|
}
|
|
1127
473
|
/**
|
|
1128
474
|
* Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
|
|
1129
475
|
* {@inheritDoc ICreditAccountsService.getOnDemandPriceUpdates}
|
|
1130
476
|
**/
|
|
1131
477
|
async getOnDemandPriceUpdates(account, ignoreReservePrices) {
|
|
1132
|
-
const {
|
|
1133
|
-
|
|
1134
|
-
const update = await this.#getUpdateForAccount(account, ignoreReservePrices);
|
|
1135
|
-
this.logger?.debug({
|
|
1136
|
-
account: creditAccount,
|
|
1137
|
-
manager: cm.name
|
|
1138
|
-
}, `getting on demand price updates from ${update.txs.length} txs`);
|
|
1139
|
-
return require_sdk_market_pricefeeds_getRawPriceUpdates.getRawPriceUpdates(update);
|
|
478
|
+
const { priceOracle } = this.sdk.marketRegister.findByCreditManager(account.creditManager);
|
|
479
|
+
return priceOracle.priceUpdatesForAccount(account, { reserve: !ignoreReservePrices });
|
|
1140
480
|
}
|
|
1141
481
|
/**
|
|
1142
|
-
*
|
|
1143
|
-
*
|
|
1144
|
-
* Deduplicates existing `onDemandPriceUpdates` calls
|
|
1145
|
-
*
|
|
1146
|
-
* @param creditManager - Address of the credit manager
|
|
1147
|
-
* @param calls - The multicall array to prepend price updates to
|
|
1148
|
-
* @param ca - Credit account slice, undefined when opening a new account
|
|
1149
|
-
* @param options - Optional settings for price update generation
|
|
1150
|
-
* @returns A new array with a single consolidated price update call prepended,
|
|
1151
|
-
* followed by the non-price-update calls in their original order
|
|
482
|
+
* {@inheritDoc ICreditAccountsService.prependPriceUpdates}
|
|
1152
483
|
*/
|
|
1153
|
-
async
|
|
1154
|
-
const
|
|
1155
|
-
const
|
|
484
|
+
async prependPriceUpdates(creditManager, calls, creditAccount, options) {
|
|
485
|
+
const { priceOracle } = this.sdk.marketRegister.findByCreditManager(creditManager);
|
|
486
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
1156
487
|
const { priceUpdates: existingUpdates, remainingCalls } = require_sdk_accounts_multicall_utils.extractPriceUpdates(calls);
|
|
1157
|
-
const
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
}
|
|
1162
|
-
const
|
|
1163
|
-
const priceFeeds = market.priceOracle.priceFeedsForTokens(Array.from(tokens), {
|
|
1164
|
-
main: true,
|
|
1165
|
-
reserve: !ignoreReservePrices
|
|
1166
|
-
});
|
|
1167
|
-
const tStr = tokens.map((t) => this.labelAddress(t)).join(", ");
|
|
1168
|
-
const remark = ignoreReservePrices ? " main" : "";
|
|
1169
|
-
this.logger?.debug({
|
|
1170
|
-
account: ca?.creditAccount,
|
|
1171
|
-
manager: cm.name
|
|
1172
|
-
}, `prependPriceUpdates for ${tStr} from ${priceFeeds.length}${remark} price feeds`);
|
|
1173
|
-
const generatedUpdates = await this.sdk.priceFeeds.generatePriceFeedsUpdates(priceFeeds);
|
|
488
|
+
const extraTokens = require_sdk_accounts_multicall_utils.extractQuotaTokens(calls).asArray();
|
|
489
|
+
const opts = {
|
|
490
|
+
reserve: !options?.ignoreReservePrices,
|
|
491
|
+
extraTokens
|
|
492
|
+
};
|
|
493
|
+
const generatedUpdates = creditAccount ? await priceOracle.priceUpdatesForAccount(creditAccount, opts) : await priceOracle.priceUpdatesForTokens([suite.creditManager.underlying, ...extraTokens], opts);
|
|
1174
494
|
const merged = require_sdk_accounts_multicall_utils.mergePriceUpdates(existingUpdates, generatedUpdates);
|
|
1175
495
|
if (merged.length === 0) return remainingCalls;
|
|
1176
|
-
return [
|
|
1177
|
-
target: cm.creditFacade,
|
|
1178
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1179
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1180
|
-
functionName: "onDemandPriceUpdates",
|
|
1181
|
-
args: [merged]
|
|
1182
|
-
})
|
|
1183
|
-
}, ...remainingCalls];
|
|
1184
|
-
}
|
|
1185
|
-
async #getUpdateForAccount(account, ignoreReservePrices) {
|
|
1186
|
-
const { creditManager, creditAccount, enabledTokensMask } = account;
|
|
1187
|
-
const market = this.sdk.marketRegister.findByCreditManager(creditManager);
|
|
1188
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditManager).creditManager;
|
|
1189
|
-
const tokens = new require_sdk_utils_AddressSet.AddressSet([cm.underlying]);
|
|
1190
|
-
for (const t of account.tokens) {
|
|
1191
|
-
const isEnabled = (t.mask & enabledTokensMask) !== 0n;
|
|
1192
|
-
if (t.balance > 10n && isEnabled) tokens.add(t.token);
|
|
1193
|
-
}
|
|
1194
|
-
const priceFeeds = market.priceOracle.priceFeedsForTokens(Array.from(tokens), {
|
|
1195
|
-
main: true,
|
|
1196
|
-
reserve: !ignoreReservePrices
|
|
1197
|
-
});
|
|
1198
|
-
const tStr = tokens.map((t) => this.labelAddress(t)).join(", ");
|
|
1199
|
-
const remark = ignoreReservePrices ? " main" : "";
|
|
1200
|
-
this.logger?.debug({
|
|
1201
|
-
account: creditAccount,
|
|
1202
|
-
manager: cm.name
|
|
1203
|
-
}, `generating price feed updates for ${tStr} from ${priceFeeds.length}${remark} price feeds`);
|
|
1204
|
-
return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(priceFeeds);
|
|
1205
|
-
}
|
|
1206
|
-
/**
|
|
1207
|
-
* {@inheritDoc ICreditAccountsService.multicall}
|
|
1208
|
-
*/
|
|
1209
|
-
async multicall(creditAccount, calls, options) {
|
|
1210
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
1211
|
-
const callsWithPrices = await this.#prependPriceUpdates(creditAccount.creditManager, calls, creditAccount, options);
|
|
1212
|
-
return cm.creditFacade.multicall(creditAccount.creditAccount, callsWithPrices);
|
|
1213
|
-
}
|
|
1214
|
-
/**
|
|
1215
|
-
* {@inheritDoc ICreditAccountsService.botMulticall}
|
|
1216
|
-
*/
|
|
1217
|
-
async botMulticall(creditAccount, calls, options) {
|
|
1218
|
-
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
1219
|
-
const callsWithPrices = await this.#prependPriceUpdates(creditAccount.creditManager, calls, creditAccount, options);
|
|
1220
|
-
return cm.creditFacade.botMulticall(creditAccount.creditAccount, callsWithPrices);
|
|
1221
|
-
}
|
|
1222
|
-
/**
|
|
1223
|
-
* {@inheritDoc ICreditAccountsService.prependPriceUpdates}
|
|
1224
|
-
*/
|
|
1225
|
-
async prependPriceUpdates(creditManager, calls, creditAccount, options) {
|
|
1226
|
-
return this.#prependPriceUpdates(creditManager, calls, creditAccount, options);
|
|
496
|
+
return [suite.creditFacade.prepareOnDemandPriceUpdates(merged), ...remainingCalls];
|
|
1227
497
|
}
|
|
1228
498
|
/**
|
|
1229
499
|
* {@inheritDoc ICreditAccountsService.assembleCaOperations}
|
|
1230
500
|
*/
|
|
1231
501
|
assembleCaOperations({ operations, creditFacade }) {
|
|
502
|
+
const facade = this.sdk.marketRegister.findCreditFacade(creditFacade);
|
|
1232
503
|
const calls = [];
|
|
1233
504
|
for (const op of operations) switch (op.type) {
|
|
1234
505
|
case "increaseDebt":
|
|
1235
|
-
calls.push(
|
|
506
|
+
calls.push(facade.prepareIncreaseDebt(op.amount));
|
|
1236
507
|
break;
|
|
1237
508
|
case "decreaseDebt":
|
|
1238
|
-
calls.push(
|
|
509
|
+
calls.push(facade.prepareChangeDebt(op.amount, true));
|
|
1239
510
|
break;
|
|
1240
511
|
case "addCollateral":
|
|
1241
|
-
calls.push(...
|
|
512
|
+
calls.push(...facade.prepareAddCollateral([{
|
|
1242
513
|
token: op.token,
|
|
1243
514
|
balance: op.amount
|
|
1244
515
|
}], {}));
|
|
1245
516
|
break;
|
|
1246
517
|
case "withdrawCollateral":
|
|
1247
|
-
calls.push(
|
|
518
|
+
calls.push(facade.prepareWithdrawCollateral(op.token, op.amount, op.to));
|
|
1248
519
|
break;
|
|
1249
520
|
case "swap":
|
|
1250
521
|
case "wrapRwaCollateral":
|
|
@@ -1254,7 +525,7 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
1254
525
|
case "changeQuota": {
|
|
1255
526
|
const quotaAssets = [...op.quotaIncrease, ...op.quotaDecrease];
|
|
1256
527
|
if (quotaAssets.length === 0) break;
|
|
1257
|
-
calls.push(...
|
|
528
|
+
calls.push(...facade.prepareUpdateQuotas({
|
|
1258
529
|
averageQuota: quotaAssets,
|
|
1259
530
|
minQuota: quotaAssets
|
|
1260
531
|
}));
|
|
@@ -1269,142 +540,40 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
1269
540
|
*/
|
|
1270
541
|
async executeCaUpdate(creditAccount, calls, options) {
|
|
1271
542
|
const cm = this.sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
1272
|
-
const callsWithPrices = await this
|
|
543
|
+
const callsWithPrices = await this.prependPriceUpdates(creditAccount.creditManager, calls, creditAccount, { ignoreReservePrices: options?.ignoreReservePrices });
|
|
1273
544
|
const tx = await this.#multicallTx(cm, creditAccount.creditAccount, callsWithPrices);
|
|
1274
545
|
if (options?.ethAmount && options.ethAmount > 0n) tx.value = options.ethAmount.toString(10);
|
|
1275
|
-
return
|
|
1276
|
-
tx,
|
|
1277
|
-
calls: callsWithPrices
|
|
1278
|
-
};
|
|
1279
|
-
}
|
|
1280
|
-
#prepareDisableQuotas(ca) {
|
|
1281
|
-
const calls = [];
|
|
1282
|
-
for (const { token, quota } of ca.tokens) if (quota > 0n) calls.push({
|
|
1283
|
-
target: ca.creditFacade,
|
|
1284
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1285
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1286
|
-
functionName: "updateQuota",
|
|
1287
|
-
args: [
|
|
1288
|
-
token,
|
|
1289
|
-
require_sdk_constants_math.MIN_INT96,
|
|
1290
|
-
0n
|
|
1291
|
-
]
|
|
1292
|
-
})
|
|
1293
|
-
});
|
|
1294
|
-
return calls;
|
|
546
|
+
return tx;
|
|
1295
547
|
}
|
|
1296
548
|
/**
|
|
1297
549
|
* {@inheritDoc ICreditAccountsService.prepareUpdateQuotas}
|
|
1298
550
|
*/
|
|
1299
|
-
prepareUpdateQuotas(creditFacade,
|
|
1300
|
-
|
|
1301
|
-
return averageQuota.map((q) => {
|
|
1302
|
-
const minBalance = minRecord.get(q.token);
|
|
1303
|
-
const min = minBalance && minBalance > 0n ? minBalance : 0n;
|
|
1304
|
-
return {
|
|
1305
|
-
target: creditFacade,
|
|
1306
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1307
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1308
|
-
functionName: "updateQuota",
|
|
1309
|
-
args: [
|
|
1310
|
-
q.token,
|
|
1311
|
-
q.balance,
|
|
1312
|
-
min
|
|
1313
|
-
]
|
|
1314
|
-
})
|
|
1315
|
-
};
|
|
1316
|
-
});
|
|
1317
|
-
}
|
|
1318
|
-
#prepareDecreaseDebt(ca) {
|
|
1319
|
-
if (ca.debt > 0n) return [{
|
|
1320
|
-
target: ca.creditFacade,
|
|
1321
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1322
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1323
|
-
functionName: "decreaseDebt",
|
|
1324
|
-
args: [require_sdk_constants_math.MAX_UINT256]
|
|
1325
|
-
})
|
|
1326
|
-
}];
|
|
1327
|
-
return [];
|
|
551
|
+
prepareUpdateQuotas(creditFacade, props) {
|
|
552
|
+
return this.sdk.marketRegister.findCreditFacade(creditFacade).prepareUpdateQuotas(props);
|
|
1328
553
|
}
|
|
1329
554
|
/**
|
|
1330
555
|
* {@inheritDoc ICreditAccountsService.prepareWithdrawToken}
|
|
1331
556
|
*/
|
|
1332
557
|
prepareWithdrawToken(creditFacade, token, amount, to) {
|
|
1333
|
-
return
|
|
1334
|
-
target: creditFacade,
|
|
1335
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1336
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1337
|
-
functionName: "withdrawCollateral",
|
|
1338
|
-
args: [
|
|
1339
|
-
token,
|
|
1340
|
-
amount,
|
|
1341
|
-
to
|
|
1342
|
-
]
|
|
1343
|
-
})
|
|
1344
|
-
};
|
|
558
|
+
return this.sdk.marketRegister.findCreditFacade(creditFacade).prepareWithdrawCollateral(token, amount, to);
|
|
1345
559
|
}
|
|
1346
560
|
/**
|
|
1347
561
|
* {@inheritDoc ICreditAccountsService.prepareIncreaseDebt}
|
|
1348
562
|
*/
|
|
1349
563
|
prepareIncreaseDebt(creditFacade, debt) {
|
|
1350
|
-
return
|
|
1351
|
-
target: creditFacade,
|
|
1352
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1353
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1354
|
-
functionName: "increaseDebt",
|
|
1355
|
-
args: [debt]
|
|
1356
|
-
})
|
|
1357
|
-
};
|
|
564
|
+
return this.sdk.marketRegister.findCreditFacade(creditFacade).prepareIncreaseDebt(debt);
|
|
1358
565
|
}
|
|
1359
566
|
/**
|
|
1360
567
|
* {@inheritDoc ICreditAccountsService.prepareChangeDebt}
|
|
1361
568
|
*/
|
|
1362
569
|
prepareChangeDebt(creditFacade, change, isDecrease) {
|
|
1363
|
-
return
|
|
1364
|
-
target: creditFacade,
|
|
1365
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1366
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1367
|
-
functionName: isDecrease ? "decreaseDebt" : "increaseDebt",
|
|
1368
|
-
args: [change]
|
|
1369
|
-
})
|
|
1370
|
-
};
|
|
570
|
+
return this.sdk.marketRegister.findCreditFacade(creditFacade).prepareChangeDebt(change, isDecrease);
|
|
1371
571
|
}
|
|
1372
572
|
/**
|
|
1373
573
|
* {@inheritDoc ICreditAccountsService.prepareAddCollateral}
|
|
1374
574
|
*/
|
|
1375
575
|
prepareAddCollateral(creditFacade, assets, permits) {
|
|
1376
|
-
return
|
|
1377
|
-
const p = permits[token];
|
|
1378
|
-
if (p) return {
|
|
1379
|
-
target: creditFacade,
|
|
1380
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1381
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1382
|
-
functionName: "addCollateralWithPermit",
|
|
1383
|
-
args: [
|
|
1384
|
-
token,
|
|
1385
|
-
balance,
|
|
1386
|
-
p.deadline,
|
|
1387
|
-
p.v,
|
|
1388
|
-
p.r,
|
|
1389
|
-
p.s
|
|
1390
|
-
]
|
|
1391
|
-
})
|
|
1392
|
-
};
|
|
1393
|
-
return {
|
|
1394
|
-
target: creditFacade,
|
|
1395
|
-
callData: (0, viem.encodeFunctionData)({
|
|
1396
|
-
abi: require_abi_310_generated.iCreditFacadeMulticallV310Abi,
|
|
1397
|
-
functionName: "addCollateral",
|
|
1398
|
-
args: [token, balance]
|
|
1399
|
-
})
|
|
1400
|
-
};
|
|
1401
|
-
});
|
|
1402
|
-
}
|
|
1403
|
-
/**
|
|
1404
|
-
* Returns addresses of market configurators
|
|
1405
|
-
*/
|
|
1406
|
-
get marketConfigurators() {
|
|
1407
|
-
return this.sdk.marketRegister.marketConfigurators.map((mc) => mc.address);
|
|
576
|
+
return this.sdk.marketRegister.findCreditFacade(creditFacade).prepareAddCollateral(assets, permits);
|
|
1408
577
|
}
|
|
1409
578
|
get rewardCompressor() {
|
|
1410
579
|
return this.sdk.addressProvider.mustGetLatest(require_sdk_constants_address_provider.AP_REWARDS_COMPRESSOR, require_sdk_constants_versions.VERSION_RANGE_310)[0];
|
|
@@ -1412,13 +581,6 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
1412
581
|
get peripheryCompressor() {
|
|
1413
582
|
return this.sdk.addressProvider.mustGetLatest(require_sdk_constants_address_provider.AP_PERIPHERY_COMPRESSOR, require_sdk_constants_versions.VERSION_RANGE_310)[0];
|
|
1414
583
|
}
|
|
1415
|
-
get compressor() {
|
|
1416
|
-
if (!this.#compressor) {
|
|
1417
|
-
[this.#compressor] = this.sdk.addressProvider.mustGetLatest(require_sdk_constants_address_provider.AP_CREDIT_ACCOUNT_COMPRESSOR, require_sdk_constants_versions.VERSION_RANGE_310);
|
|
1418
|
-
this.logger?.debug(`credit account compressor address: ${this.#compressor}`);
|
|
1419
|
-
}
|
|
1420
|
-
return this.#compressor;
|
|
1421
|
-
}
|
|
1422
584
|
/**
|
|
1423
585
|
* Wrapper that selects between credit facade and RWA factory
|
|
1424
586
|
* @param suite
|
|
@@ -1447,24 +609,6 @@ var CreditAccountsServiceV310 = class extends require_sdk_base_SDKConstruct.SDKC
|
|
|
1447
609
|
return suite.creditFacade.multicall(creditAccount, calls);
|
|
1448
610
|
}
|
|
1449
611
|
/**
|
|
1450
|
-
* Wrapper that selects between credit facade and RWA factory
|
|
1451
|
-
* @param suite
|
|
1452
|
-
* @param creditAccount
|
|
1453
|
-
* @param calls
|
|
1454
|
-
* @param operation
|
|
1455
|
-
* @param rwaOptions
|
|
1456
|
-
* @returns
|
|
1457
|
-
*/
|
|
1458
|
-
async #closeCreditAccountTx(suite, creditAccount, calls, operation, rwaOptions) {
|
|
1459
|
-
const factory = this.sdk.marketRegister.findByCreditManager(suite.creditManager.address).rwaFactory;
|
|
1460
|
-
if (operation === "close") {
|
|
1461
|
-
if (factory) throw new Error("CloseOptions=close is not supported for RWA underlying credit accounts");
|
|
1462
|
-
return suite.creditFacade.closeCreditAccount(creditAccount, calls);
|
|
1463
|
-
}
|
|
1464
|
-
if (factory) return factory.multicall(creditAccount, calls, rwaOptions);
|
|
1465
|
-
return suite.creditFacade.multicall(creditAccount, calls);
|
|
1466
|
-
}
|
|
1467
|
-
/**
|
|
1468
612
|
* Withdrawal compressor of the current chain.
|
|
1469
613
|
* @throws If no withdrawal compressor is supported on the current chain.
|
|
1470
614
|
**/
|