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