@gearbox-protocol/sdk 13.4.0 → 13.5.0-next.1
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/abi/310/iSecuritizeDegenNFT.js +263 -0
- package/dist/cjs/abi/310/iSecuritizeKYCFactory.js +278 -0
- package/dist/cjs/{sdk/pools/PoolServiceV310.js → abi/iStateSerializer.js} +14 -8
- package/dist/cjs/dev/AccountOpener.js +45 -5
- package/dist/cjs/sdk/accounts/AbstractCreditAccountsService.js +375 -13
- package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +16 -5
- package/dist/cjs/sdk/base/ChainContractsRegister.js +1 -1
- package/dist/cjs/sdk/base/TokensMeta.js +255 -32
- package/dist/cjs/sdk/base/index.js +2 -0
- package/dist/cjs/sdk/{constants/phantom-tokens.js → base/token-types.js} +9 -3
- package/dist/cjs/sdk/chain/chains.js +2 -1
- package/dist/cjs/sdk/constants/index.js +0 -2
- package/dist/cjs/sdk/market/MarketRegister.js +5 -2
- package/dist/cjs/sdk/market/MarketSuite.js +6 -0
- package/dist/cjs/{plugins/zappers/extraZappers.js → sdk/market/ZapperRegister.js} +110 -6
- package/dist/cjs/sdk/market/index.js +3 -1
- package/dist/cjs/sdk/market/pool/PoolSuite.js +3 -0
- package/dist/cjs/sdk/market/pool/PoolV310Contract.js +17 -2
- package/dist/cjs/sdk/market/pool/SecuritizeKYCFactory.js +97 -0
- package/dist/cjs/sdk/market/pool/index.js +4 -0
- package/dist/cjs/sdk/pools/PoolService.js +391 -0
- package/dist/cjs/sdk/pools/index.js +2 -4
- package/dist/esm/abi/310/iSecuritizeDegenNFT.js +239 -0
- package/dist/esm/abi/310/iSecuritizeKYCFactory.js +254 -0
- package/dist/esm/abi/iStateSerializer.js +12 -0
- package/dist/esm/dev/AccountOpener.js +47 -6
- package/dist/esm/sdk/accounts/AbstractCreditAccountsService.js +375 -13
- package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +16 -5
- package/dist/esm/sdk/base/ChainContractsRegister.js +1 -1
- package/dist/esm/sdk/base/TokensMeta.js +261 -32
- package/dist/esm/sdk/base/index.js +1 -0
- package/dist/esm/sdk/{constants/phantom-tokens.js → base/token-types.js} +4 -0
- package/dist/esm/sdk/chain/chains.js +2 -1
- package/dist/esm/sdk/constants/index.js +0 -1
- package/dist/esm/sdk/market/MarketRegister.js +5 -2
- package/dist/esm/sdk/market/MarketSuite.js +6 -0
- package/dist/esm/{plugins/zappers/extraZappers.js → sdk/market/ZapperRegister.js} +109 -2
- package/dist/esm/sdk/market/index.js +1 -0
- package/dist/esm/sdk/market/pool/PoolSuite.js +3 -0
- package/dist/esm/sdk/market/pool/PoolV310Contract.js +17 -2
- package/dist/esm/sdk/market/pool/SecuritizeKYCFactory.js +73 -0
- package/dist/esm/sdk/market/pool/index.js +2 -0
- package/dist/esm/sdk/pools/PoolService.js +371 -0
- package/dist/esm/sdk/pools/index.js +1 -2
- package/dist/types/abi/310/iSecuritizeDegenNFT.d.ts +324 -0
- package/dist/types/abi/310/iSecuritizeKYCFactory.d.ts +322 -0
- package/dist/types/abi/iStateSerializer.d.ts +11 -0
- package/dist/types/sdk/accounts/AbstractCreditAccountsService.d.ts +114 -3
- package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +1 -1
- package/dist/types/sdk/accounts/types.d.ts +96 -6
- package/dist/types/sdk/base/TokensMeta.d.ts +34 -21
- package/dist/types/sdk/base/index.d.ts +1 -0
- package/dist/types/sdk/base/token-types.d.ts +33 -0
- package/dist/types/sdk/base/types.d.ts +0 -7
- package/dist/types/sdk/chain/chains.d.ts +1 -1
- package/dist/types/sdk/constants/index.d.ts +0 -1
- package/dist/types/sdk/market/MarketRegister.d.ts +2 -2
- package/dist/types/sdk/market/MarketSuite.d.ts +3 -0
- package/dist/types/sdk/market/ZapperRegister.d.ts +17 -0
- package/dist/types/sdk/market/index.d.ts +1 -0
- package/dist/types/sdk/market/pool/PoolSuite.d.ts +2 -0
- package/dist/types/sdk/market/pool/PoolV310Contract.d.ts +6 -2
- package/dist/types/sdk/market/pool/SecuritizeKYCFactory.d.ts +345 -0
- package/dist/types/sdk/market/pool/index.d.ts +2 -0
- package/dist/types/sdk/market/types.d.ts +10 -0
- package/dist/types/sdk/pools/PoolService.d.ts +14 -0
- package/dist/types/sdk/pools/index.d.ts +1 -2
- package/dist/types/sdk/pools/types.d.ts +85 -111
- package/package.json +1 -1
- package/dist/cjs/plugins/zappers/ZappersPlugin.js +0 -144
- package/dist/cjs/plugins/zappers/index.js +0 -26
- package/dist/cjs/plugins/zappers/package.json +0 -1
- package/dist/cjs/sdk/pools/AbstractPoolService.js +0 -143
- package/dist/cjs/sdk/pools/createPoolService.js +0 -35
- package/dist/esm/plugins/zappers/ZappersPlugin.js +0 -126
- package/dist/esm/plugins/zappers/index.js +0 -3
- package/dist/esm/plugins/zappers/package.json +0 -1
- package/dist/esm/sdk/pools/AbstractPoolService.js +0 -119
- package/dist/esm/sdk/pools/PoolServiceV310.js +0 -6
- package/dist/esm/sdk/pools/createPoolService.js +0 -11
- package/dist/types/plugins/zappers/ZappersPlugin.d.ts +0 -18
- package/dist/types/plugins/zappers/extraZappers.d.ts +0 -6
- package/dist/types/plugins/zappers/index.d.ts +0 -3
- package/dist/types/plugins/zappers/types.d.ts +0 -12
- package/dist/types/sdk/constants/phantom-tokens.d.ts +0 -2
- package/dist/types/sdk/pools/AbstractPoolService.d.ts +0 -21
- package/dist/types/sdk/pools/PoolServiceV310.d.ts +0 -4
- package/dist/types/sdk/pools/createPoolService.d.ts +0 -3
- /package/dist/cjs/{plugins/zappers → sdk/market}/types.js +0 -0
- /package/dist/esm/{plugins/zappers → sdk/market}/types.js +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ierc4626AdapterAbi } from "@gearbox-protocol/integrations-v3";
|
|
1
2
|
import { encodeFunctionData, getContract } from "viem";
|
|
2
3
|
import {
|
|
3
4
|
iBotListV310Abi,
|
|
@@ -90,6 +91,23 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
90
91
|
});
|
|
91
92
|
return cad;
|
|
92
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Returns credit account data for a single account with the investor address resolved.
|
|
96
|
+
* Loads CA via getCreditAccountData; for KYC underlyings fetches the investor from the KYC factory's getInvestor(creditAccount), otherwise uses the account owner.
|
|
97
|
+
* @param account - Credit account address
|
|
98
|
+
* @param blockNumber - Optional block number for the read
|
|
99
|
+
* @returns CreditAccountDataWithInvestor (CA data + investor address), or undefined if the account is not found
|
|
100
|
+
*/
|
|
101
|
+
async getCreditAccountDataWithInvestor(account, blockNumber) {
|
|
102
|
+
const ca = await this.getCreditAccountData(account, blockNumber);
|
|
103
|
+
if (!ca) return ca;
|
|
104
|
+
const marketSuite = this.sdk.marketRegister.findByCreditManager(
|
|
105
|
+
ca.creditManager
|
|
106
|
+
);
|
|
107
|
+
const factory = await marketSuite.getKYCFactory();
|
|
108
|
+
const investor = factory ? await factory.getInvestor(ca.creditAccount, true) : void 0;
|
|
109
|
+
return { ...ca, investor: investor ?? ca.owner };
|
|
110
|
+
}
|
|
93
111
|
/**
|
|
94
112
|
* {@inheritDoc ICreditAccountsService.getCreditAccounts}
|
|
95
113
|
**/
|
|
@@ -144,6 +162,75 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
144
162
|
);
|
|
145
163
|
return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
146
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Returns all credit accounts matching the filter, with investor set on each item.
|
|
167
|
+
* Delegates to getCreditAccounts; when options.owner is set, also loads KYC credit accounts for that owner and merges them into the list. Result is sorted by health factor ascending.
|
|
168
|
+
* @param options - Filter options (owner, creditManager, health factor, etc.)
|
|
169
|
+
* @param blockNumber - Optional block number for the read
|
|
170
|
+
* @returns Array of credit accounts (with investor field), sorted by health factor ascending
|
|
171
|
+
*/
|
|
172
|
+
async getCreditAccountsWithInvestor(options, blockNumber) {
|
|
173
|
+
const { owner, ignoreReservePrices = false } = options ?? {};
|
|
174
|
+
const priceUpdate = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
|
|
175
|
+
ignoreReservePrices ? { main: true } : void 0
|
|
176
|
+
);
|
|
177
|
+
const { txs: priceUpdateTxs } = priceUpdate;
|
|
178
|
+
const [common, kyc] = await Promise.all([
|
|
179
|
+
this.getCreditAccounts(options, blockNumber),
|
|
180
|
+
owner ? this.getKYCCreditAccountsOfOwner(owner, priceUpdateTxs, blockNumber) : void 0
|
|
181
|
+
]);
|
|
182
|
+
const allCAs = common.map(
|
|
183
|
+
(ca) => ({
|
|
184
|
+
...ca,
|
|
185
|
+
investor: owner || ca.owner
|
|
186
|
+
})
|
|
187
|
+
);
|
|
188
|
+
allCAs.push(...kyc || []);
|
|
189
|
+
return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
190
|
+
}
|
|
191
|
+
async getKYCCreditAccountsOfOwner(owner, priceUpdateTxs, blockNumber) {
|
|
192
|
+
const suites = this.marketConfigurators.map((mc) => {
|
|
193
|
+
const suite = this.sdk.marketRegister.markets.find(
|
|
194
|
+
(m) => m.configurator.address === mc
|
|
195
|
+
);
|
|
196
|
+
return suite;
|
|
197
|
+
});
|
|
198
|
+
const kycCAAddresses = await this.getKYCCaOfInvestor(owner, suites);
|
|
199
|
+
const kycCAs = await this.loadSpecifiedAccounts(
|
|
200
|
+
kycCAAddresses,
|
|
201
|
+
priceUpdateTxs,
|
|
202
|
+
blockNumber
|
|
203
|
+
);
|
|
204
|
+
return kycCAs.map((ca) => ({
|
|
205
|
+
...ca,
|
|
206
|
+
investor: owner
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Loads credit account data for the given addresses using simulateWithPriceUpdates.
|
|
211
|
+
* Applies the provided price update txs before reading, so returned data is consistent with up-to-date prices.
|
|
212
|
+
* @param accounts - Credit account addresses to load
|
|
213
|
+
* @param priceUpdateTxs - Price feed update txs to simulate before the read (e.g. from generatePriceFeedsUpdateTxs)
|
|
214
|
+
* @param blockNumber - Optional block number for the read
|
|
215
|
+
* @returns Array of CreditAccountData in the same order as accounts (throws if any getCreditAccountData call reverts)
|
|
216
|
+
*/
|
|
217
|
+
async loadSpecifiedAccounts(accounts, priceUpdateTxs, blockNumber) {
|
|
218
|
+
if (accounts.length === 0) return [];
|
|
219
|
+
const list = await simulateWithPriceUpdates(this.client, {
|
|
220
|
+
priceUpdates: priceUpdateTxs,
|
|
221
|
+
contracts: accounts.map(
|
|
222
|
+
(account) => ({
|
|
223
|
+
abi: creditAccountCompressorAbi,
|
|
224
|
+
address: this.#compressor,
|
|
225
|
+
functionName: "getCreditAccountData",
|
|
226
|
+
args: [account]
|
|
227
|
+
})
|
|
228
|
+
),
|
|
229
|
+
blockNumber,
|
|
230
|
+
gas: this.sdk.gasLimit
|
|
231
|
+
});
|
|
232
|
+
return list;
|
|
233
|
+
}
|
|
147
234
|
/**
|
|
148
235
|
* {@inheritDoc ICreditAccountsService.getRewards}
|
|
149
236
|
**/
|
|
@@ -353,6 +440,13 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
353
440
|
closePath
|
|
354
441
|
}) {
|
|
355
442
|
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
443
|
+
await this.sdk.tokensMeta.loadTokenData(cm.underlying);
|
|
444
|
+
const underlying = this.sdk.tokensMeta.mustGet(cm.underlying);
|
|
445
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
446
|
+
throw new Error(
|
|
447
|
+
"closeCreditAccount is not supported for KYC underlying credit accounts"
|
|
448
|
+
);
|
|
449
|
+
}
|
|
356
450
|
const routerCloseResult = closePath || await this.sdk.routerFor(ca).findBestClosePath({
|
|
357
451
|
creditAccount: ca,
|
|
358
452
|
creditManager: cm.creditManager,
|
|
@@ -367,7 +461,12 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
367
461
|
)
|
|
368
462
|
];
|
|
369
463
|
const calls = operation === "close" ? operationCalls : await this.prependPriceUpdates(ca.creditManager, operationCalls, ca);
|
|
370
|
-
const tx =
|
|
464
|
+
const tx = await this.closeCreditAccountTx(
|
|
465
|
+
cm,
|
|
466
|
+
ca.creditAccount,
|
|
467
|
+
calls,
|
|
468
|
+
operation
|
|
469
|
+
);
|
|
371
470
|
return { tx, calls, routerCloseResult, creditFacade: cm.creditFacade };
|
|
372
471
|
}
|
|
373
472
|
/**
|
|
@@ -390,7 +489,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
390
489
|
operationCalls,
|
|
391
490
|
creditAccount
|
|
392
491
|
);
|
|
393
|
-
const tx =
|
|
492
|
+
const tx = await this.multicallTx(cm, creditAccount.creditAccount, calls);
|
|
394
493
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
395
494
|
}
|
|
396
495
|
/**
|
|
@@ -423,7 +522,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
423
522
|
operationCalls,
|
|
424
523
|
creditAccount
|
|
425
524
|
);
|
|
426
|
-
const tx =
|
|
525
|
+
const tx = await this.multicallTx(cm, creditAccount.creditAccount, calls);
|
|
427
526
|
tx.value = ethAmount.toString(10);
|
|
428
527
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
429
528
|
}
|
|
@@ -433,7 +532,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
433
532
|
async changeDebt({
|
|
434
533
|
creditAccount,
|
|
435
534
|
amount,
|
|
436
|
-
|
|
535
|
+
collateral
|
|
437
536
|
}) {
|
|
438
537
|
if (amount === 0n) {
|
|
439
538
|
throw new Error("debt increase or decrease must be non-zero");
|
|
@@ -443,18 +542,28 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
443
542
|
const cm = this.sdk.marketRegister.findCreditManager(
|
|
444
543
|
creditAccount.creditManager
|
|
445
544
|
);
|
|
446
|
-
const addCollateralCalls =
|
|
545
|
+
const addCollateralCalls = collateral && isDecrease ? this.prepareAddCollateral(
|
|
447
546
|
creditAccount.creditFacade,
|
|
448
547
|
[
|
|
449
548
|
{
|
|
450
|
-
token:
|
|
451
|
-
balance:
|
|
549
|
+
token: collateral[0].token,
|
|
550
|
+
balance: collateral[0].balance
|
|
452
551
|
}
|
|
453
552
|
],
|
|
454
553
|
{}
|
|
455
554
|
) : [];
|
|
555
|
+
const unwrapCalls = collateral && isDecrease ? await this.getKYCUnwrapCalls(
|
|
556
|
+
collateral[0].balance,
|
|
557
|
+
creditAccount.creditManager
|
|
558
|
+
) || [] : [];
|
|
559
|
+
if (addCollateralCalls.length > 0 && unwrapCalls.length === 0 && collateral && collateral?.[0].token !== creditAccount.underlying) {
|
|
560
|
+
throw new Error(
|
|
561
|
+
"Can't use collateral other than underlying for non KYC market"
|
|
562
|
+
);
|
|
563
|
+
}
|
|
456
564
|
const operationCalls = [
|
|
457
565
|
...addCollateralCalls,
|
|
566
|
+
...unwrapCalls,
|
|
458
567
|
this.#prepareChangeDebt(creditAccount.creditFacade, change, isDecrease)
|
|
459
568
|
];
|
|
460
569
|
const calls = await this.prependPriceUpdates(
|
|
@@ -462,7 +571,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
462
571
|
operationCalls,
|
|
463
572
|
creditAccount
|
|
464
573
|
);
|
|
465
|
-
const tx =
|
|
574
|
+
const tx = await this.multicallTx(cm, creditAccount.creditAccount, calls);
|
|
466
575
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
467
576
|
}
|
|
468
577
|
/**
|
|
@@ -490,7 +599,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
490
599
|
operationCalls,
|
|
491
600
|
creditAccount
|
|
492
601
|
);
|
|
493
|
-
const tx =
|
|
602
|
+
const tx = await this.multicallTx(cm, creditAccount.creditAccount, calls);
|
|
494
603
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
495
604
|
}
|
|
496
605
|
/**
|
|
@@ -598,7 +707,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
598
707
|
operationCalls,
|
|
599
708
|
creditAccount
|
|
600
709
|
);
|
|
601
|
-
const tx =
|
|
710
|
+
const tx = await this.multicallTx(cm, creditAccount.creditAccount, calls);
|
|
602
711
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
603
712
|
}
|
|
604
713
|
/**
|
|
@@ -659,9 +768,28 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
659
768
|
operationCalls,
|
|
660
769
|
creditAccount
|
|
661
770
|
);
|
|
662
|
-
const tx =
|
|
771
|
+
const tx = await this.multicallTx(cm, creditAccount.creditAccount, calls);
|
|
663
772
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
664
773
|
}
|
|
774
|
+
/**
|
|
775
|
+
* Returns address to which approval should be given on collateral token
|
|
776
|
+
* It's credit manager for classical markets and special wallet for KYC markets
|
|
777
|
+
* @param options - {@link GetApprovalAddressProps}
|
|
778
|
+
* @returns
|
|
779
|
+
**/
|
|
780
|
+
async getApprovalAddress(options) {
|
|
781
|
+
const { creditManager } = options;
|
|
782
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
783
|
+
const marketSuite = this.sdk.marketRegister.findByPool(suite.pool);
|
|
784
|
+
const factory = await marketSuite.getKYCFactory();
|
|
785
|
+
if (factory) {
|
|
786
|
+
if ("creditAccount" in options) {
|
|
787
|
+
return factory.getWallet(options.creditAccount);
|
|
788
|
+
}
|
|
789
|
+
return factory.precomputeWalletAddress(creditManager, options.borrower);
|
|
790
|
+
}
|
|
791
|
+
return suite.creditManager.address;
|
|
792
|
+
}
|
|
665
793
|
/**
|
|
666
794
|
* {@inheritDoc ICreditAccountsService.openCA}
|
|
667
795
|
**/
|
|
@@ -693,6 +821,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
693
821
|
this.#prepareIncreaseDebt(cm.creditFacade, debt),
|
|
694
822
|
...this.prepareAddCollateral(cm.creditFacade, collateral, permits),
|
|
695
823
|
...openPathCalls,
|
|
824
|
+
// path from underlying to withdrawal token
|
|
696
825
|
...tokenToWithdraw ? [
|
|
697
826
|
this.prepareWithdrawToken(
|
|
698
827
|
cm.creditFacade,
|
|
@@ -710,9 +839,9 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
710
839
|
const calls = await this.prependPriceUpdates(cm.address, operationCalls);
|
|
711
840
|
let tx;
|
|
712
841
|
if (reopenCreditAccount) {
|
|
713
|
-
tx = await
|
|
842
|
+
tx = await this.multicallTx(cmSuite, reopenCreditAccount, calls);
|
|
714
843
|
} else {
|
|
715
|
-
tx =
|
|
844
|
+
tx = await this.openCreditAccountTx(cmSuite, to, calls, referralCode);
|
|
716
845
|
}
|
|
717
846
|
tx.value = ethAmount.toString(10);
|
|
718
847
|
return { calls, tx, creditFacade: cmSuite.creditFacade };
|
|
@@ -795,6 +924,131 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
795
924
|
return resp;
|
|
796
925
|
}
|
|
797
926
|
/**
|
|
927
|
+
* Returns multicall entries to redeem (unwrap) KYC ERC-4626 vault shares into underlying for the given credit manager.
|
|
928
|
+
* Used when withdrawing debt from a KYC market: redeems adapter vault shares so the underlying can be withdrawn.
|
|
929
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
930
|
+
* @param amount - Number of vault shares (adapter tokens) to redeem
|
|
931
|
+
* @param creditManager - Credit manager address
|
|
932
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
933
|
+
*/
|
|
934
|
+
async getKYCUnwrapCalls(amount, creditManager) {
|
|
935
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
936
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
937
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
938
|
+
return void 0;
|
|
939
|
+
}
|
|
940
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
941
|
+
const adapterAddress = adapter?.address;
|
|
942
|
+
if (!adapterAddress) {
|
|
943
|
+
return void 0;
|
|
944
|
+
}
|
|
945
|
+
const mc = [
|
|
946
|
+
{
|
|
947
|
+
target: adapterAddress,
|
|
948
|
+
callData: encodeFunctionData({
|
|
949
|
+
abi: ierc4626AdapterAbi,
|
|
950
|
+
functionName: "redeem",
|
|
951
|
+
args: [amount, ADDRESS_0X0, ADDRESS_0X0]
|
|
952
|
+
})
|
|
953
|
+
}
|
|
954
|
+
];
|
|
955
|
+
return mc;
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Returns multicall entries to deposit (wrap) underlying into KYC ERC-4626 vault shares for the given credit manager.
|
|
959
|
+
* Used when adding debt on a KYC market: deposits underlying into the adapter vault so shares are minted on the account.
|
|
960
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
961
|
+
* @param amount - Amount of underlying assets to deposit into the vault (in underlying decimals)
|
|
962
|
+
* @param creditManager - Credit manager address
|
|
963
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
964
|
+
*/
|
|
965
|
+
async getKYCWrapCalls(amount, creditManager) {
|
|
966
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
967
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
968
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
969
|
+
return void 0;
|
|
970
|
+
}
|
|
971
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
972
|
+
const adapterAddress = adapter?.address;
|
|
973
|
+
if (!adapterAddress) {
|
|
974
|
+
return void 0;
|
|
975
|
+
}
|
|
976
|
+
const mc = [
|
|
977
|
+
{
|
|
978
|
+
target: adapterAddress,
|
|
979
|
+
callData: encodeFunctionData({
|
|
980
|
+
abi: ierc4626AdapterAbi,
|
|
981
|
+
functionName: "deposit",
|
|
982
|
+
args: [amount, ADDRESS_0X0]
|
|
983
|
+
})
|
|
984
|
+
}
|
|
985
|
+
];
|
|
986
|
+
return mc;
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Returns multicall entries to call redeemDiff on the KYC ERC-4626 adapter for the given credit manager.
|
|
990
|
+
* Redeems the leftover vault shares (e.g. after repaying debt) so the account does not hold excess KYC vault tokens.
|
|
991
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
992
|
+
* @param amount - Leftover vault share amount to redeem (in adapter/vault decimals)
|
|
993
|
+
* @param creditManager - Credit manager address
|
|
994
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
995
|
+
*/
|
|
996
|
+
async getRedeemDiffCalls(amount, creditManager) {
|
|
997
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
998
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
999
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
1000
|
+
return void 0;
|
|
1001
|
+
}
|
|
1002
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
1003
|
+
const adapterAddress = adapter?.address;
|
|
1004
|
+
if (!adapterAddress) {
|
|
1005
|
+
return void 0;
|
|
1006
|
+
}
|
|
1007
|
+
const mc = [
|
|
1008
|
+
{
|
|
1009
|
+
target: adapterAddress,
|
|
1010
|
+
callData: encodeFunctionData({
|
|
1011
|
+
abi: ierc4626AdapterAbi,
|
|
1012
|
+
functionName: "redeemDiff",
|
|
1013
|
+
args: [amount]
|
|
1014
|
+
})
|
|
1015
|
+
}
|
|
1016
|
+
];
|
|
1017
|
+
return mc;
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Returns multicall entries to call depositDiff on the KYC ERC-4626 adapter for the given credit manager.
|
|
1021
|
+
* Deposits the leftover underlying (e.g. after decreasing debt) into the vault so the account does not hold excess underlying.
|
|
1022
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
1023
|
+
* @param amount - Leftover underlying amount to deposit into the vault (in underlying decimals)
|
|
1024
|
+
* @param creditManager - Credit manager address
|
|
1025
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
1026
|
+
*/
|
|
1027
|
+
async getDepositDiffCalls(amount, creditManager) {
|
|
1028
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
1029
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
1030
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
1031
|
+
return void 0;
|
|
1032
|
+
}
|
|
1033
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
1034
|
+
const adapterAddress = adapter?.address;
|
|
1035
|
+
if (!adapterAddress) {
|
|
1036
|
+
return void 0;
|
|
1037
|
+
}
|
|
1038
|
+
const mc = [
|
|
1039
|
+
{
|
|
1040
|
+
target: adapterAddress,
|
|
1041
|
+
callData: encodeFunctionData({
|
|
1042
|
+
abi: ierc4626AdapterAbi,
|
|
1043
|
+
functionName: "depositDiff",
|
|
1044
|
+
args: [amount]
|
|
1045
|
+
})
|
|
1046
|
+
}
|
|
1047
|
+
];
|
|
1048
|
+
return mc;
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
|
|
798
1052
|
* {@inheritDoc ICreditAccountsService.getOnDemandPriceUpdates}
|
|
799
1053
|
**/
|
|
800
1054
|
async getOnDemandPriceUpdates(account, ignoreReservePrices) {
|
|
@@ -1055,6 +1309,114 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
1055
1309
|
VERSION_RANGE_310
|
|
1056
1310
|
)[0];
|
|
1057
1311
|
}
|
|
1312
|
+
/**
|
|
1313
|
+
* Wrapper that selects between credit facade and KYC factory
|
|
1314
|
+
* @param suite
|
|
1315
|
+
* @param to
|
|
1316
|
+
* @param calls
|
|
1317
|
+
* @param referralCode
|
|
1318
|
+
* @returns
|
|
1319
|
+
*/
|
|
1320
|
+
async openCreditAccountTx(suite, to, calls, referralCode) {
|
|
1321
|
+
const marketSuite = this.sdk.marketRegister.findByPool(suite.pool);
|
|
1322
|
+
const factory = await marketSuite.getKYCFactory();
|
|
1323
|
+
if (factory) {
|
|
1324
|
+
const tokensToRegister = await factory.getDSTokens();
|
|
1325
|
+
return factory.openCreditAccount(
|
|
1326
|
+
suite.creditManager.address,
|
|
1327
|
+
calls,
|
|
1328
|
+
tokensToRegister
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1331
|
+
return suite.creditFacade.openCreditAccount(to, calls, referralCode ?? 0n);
|
|
1332
|
+
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Wrapper that selects between credit facade and KYC factory
|
|
1335
|
+
* @param suite
|
|
1336
|
+
* @param creditAccount
|
|
1337
|
+
* @param calls
|
|
1338
|
+
* @returns
|
|
1339
|
+
*/
|
|
1340
|
+
async multicallTx(suite, creditAccount, calls) {
|
|
1341
|
+
const marketSuite = this.sdk.marketRegister.findByCreditManager(
|
|
1342
|
+
suite.creditManager.address
|
|
1343
|
+
);
|
|
1344
|
+
const factory = await marketSuite.getKYCFactory();
|
|
1345
|
+
if (factory) {
|
|
1346
|
+
const tokensToRegister = [];
|
|
1347
|
+
return factory.multicall(creditAccount, calls, tokensToRegister);
|
|
1348
|
+
}
|
|
1349
|
+
return suite.creditFacade.multicall(creditAccount, calls);
|
|
1350
|
+
}
|
|
1351
|
+
/**
|
|
1352
|
+
* Wrapper that selects between credit facade and KYC factory
|
|
1353
|
+
* @param suite
|
|
1354
|
+
* @param creditAccount
|
|
1355
|
+
* @param calls
|
|
1356
|
+
* @param operation
|
|
1357
|
+
* @returns
|
|
1358
|
+
*/
|
|
1359
|
+
async closeCreditAccountTx(suite, creditAccount, calls, operation) {
|
|
1360
|
+
const marketSuite = this.sdk.marketRegister.findByCreditManager(
|
|
1361
|
+
suite.creditManager.address
|
|
1362
|
+
);
|
|
1363
|
+
const factory = await marketSuite.getKYCFactory();
|
|
1364
|
+
if (operation === "close") {
|
|
1365
|
+
if (factory) {
|
|
1366
|
+
throw new Error(
|
|
1367
|
+
"CloseOptions=close is not supported for KYC underlying credit accounts"
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1370
|
+
return suite.creditFacade.closeCreditAccount(creditAccount, calls);
|
|
1371
|
+
}
|
|
1372
|
+
if (factory) {
|
|
1373
|
+
const tokensToRegister = [];
|
|
1374
|
+
return factory.multicall(creditAccount, calls, tokensToRegister);
|
|
1375
|
+
}
|
|
1376
|
+
return suite.creditFacade.multicall(creditAccount, calls);
|
|
1377
|
+
}
|
|
1378
|
+
/**
|
|
1379
|
+
* Returns all KYC credit account addresses for an investor across the given market suites.
|
|
1380
|
+
* Resolves KYC factory per suite, then multicalls each factory's getCreditAccounts(investor).
|
|
1381
|
+
* @param investor - Owner address to query
|
|
1382
|
+
* @param suites - Market suites (KYC factories are resolved for each; undefined entries are skipped)
|
|
1383
|
+
* @returns Flat array of credit account addresses from all KYC markets
|
|
1384
|
+
*/
|
|
1385
|
+
async getKYCCaOfInvestor(investor, suites) {
|
|
1386
|
+
if (suites.length === 0 || investor === ADDRESS_0X0) return [];
|
|
1387
|
+
const factories = await Promise.all(
|
|
1388
|
+
suites.map((suite) => suite ? suite.getKYCFactory() : void 0)
|
|
1389
|
+
);
|
|
1390
|
+
const safeFactories = factories.reduce(
|
|
1391
|
+
(acc, v) => {
|
|
1392
|
+
if (v) {
|
|
1393
|
+
acc.push(v);
|
|
1394
|
+
}
|
|
1395
|
+
return acc;
|
|
1396
|
+
},
|
|
1397
|
+
[]
|
|
1398
|
+
);
|
|
1399
|
+
const allResp = await this.client.multicall({
|
|
1400
|
+
contracts: [
|
|
1401
|
+
...safeFactories.map((factory) => {
|
|
1402
|
+
return {
|
|
1403
|
+
abi: factory.abi,
|
|
1404
|
+
address: factory.address,
|
|
1405
|
+
functionName: "getCreditAccounts",
|
|
1406
|
+
args: [investor]
|
|
1407
|
+
};
|
|
1408
|
+
})
|
|
1409
|
+
],
|
|
1410
|
+
allowFailure: true,
|
|
1411
|
+
batchSize: 0
|
|
1412
|
+
});
|
|
1413
|
+
const caLists = safeFactories.reduce((acc, _, index) => {
|
|
1414
|
+
const response = allResp[index];
|
|
1415
|
+
acc.push(...response.result || []);
|
|
1416
|
+
return acc;
|
|
1417
|
+
}, []);
|
|
1418
|
+
return caLists;
|
|
1419
|
+
}
|
|
1058
1420
|
}
|
|
1059
1421
|
export {
|
|
1060
1422
|
AbstractCreditAccountService,
|
|
@@ -42,7 +42,7 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
42
42
|
[addBotCall],
|
|
43
43
|
targetContract
|
|
44
44
|
) : [addBotCall];
|
|
45
|
-
const tx = targetContract.type === "creditAccount" ?
|
|
45
|
+
const tx = targetContract.type === "creditAccount" ? await this.multicallTx(cm, targetContract.creditAccount, calls) : void 0;
|
|
46
46
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
@@ -77,7 +77,7 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
77
77
|
operationCalls,
|
|
78
78
|
creditAccount
|
|
79
79
|
);
|
|
80
|
-
const tx =
|
|
80
|
+
const tx = await this.multicallTx(cm, creditAccount.creditAccount, calls);
|
|
81
81
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
@@ -90,26 +90,35 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
90
90
|
creditAccount: ca,
|
|
91
91
|
permits,
|
|
92
92
|
to,
|
|
93
|
-
tokensToClaim
|
|
93
|
+
tokensToClaim,
|
|
94
|
+
calls: wrapCalls = []
|
|
94
95
|
}) {
|
|
95
96
|
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
96
97
|
const addCollateral = collateralAssets.filter((a) => a.balance > 0);
|
|
97
98
|
const router = this.sdk.routerFor(ca);
|
|
99
|
+
const unwrapCalls = await this.getRedeemDiffCalls(1n, ca.creditManager) ?? [];
|
|
98
100
|
const claimPath = await router.findClaimAllRewards({
|
|
99
101
|
tokensToClaim,
|
|
100
102
|
creditAccount: ca
|
|
101
103
|
});
|
|
102
104
|
const operationCalls = [
|
|
103
105
|
...this.prepareAddCollateral(ca.creditFacade, addCollateral, permits),
|
|
106
|
+
...wrapCalls,
|
|
104
107
|
...this.prepareDisableQuotas(ca),
|
|
105
108
|
...this.prepareDecreaseDebt(ca),
|
|
109
|
+
...unwrapCalls,
|
|
106
110
|
...claimPath.calls,
|
|
107
111
|
...assetsToWithdraw.map(
|
|
108
112
|
(t) => this.prepareWithdrawToken(ca.creditFacade, t.token, MAX_UINT256, to)
|
|
109
113
|
)
|
|
110
114
|
];
|
|
111
115
|
const calls = operation === "close" ? operationCalls : await this.prependPriceUpdates(ca.creditManager, operationCalls, ca);
|
|
112
|
-
const tx =
|
|
116
|
+
const tx = await this.closeCreditAccountTx(
|
|
117
|
+
cm,
|
|
118
|
+
ca.creditAccount,
|
|
119
|
+
calls,
|
|
120
|
+
operation
|
|
121
|
+
);
|
|
113
122
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
114
123
|
}
|
|
115
124
|
/**
|
|
@@ -129,10 +138,12 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
129
138
|
tokensToClaim,
|
|
130
139
|
creditAccount: ca
|
|
131
140
|
});
|
|
141
|
+
const wrapCalls = await this.getDepositDiffCalls(1n, ca.creditManager) ?? [];
|
|
132
142
|
const addCollateral = collateralAssets.filter((a) => a.balance > 0);
|
|
133
143
|
const operationCalls = [
|
|
134
144
|
...this.prepareAddCollateral(ca.creditFacade, addCollateral, permits),
|
|
135
145
|
...claimPath.calls,
|
|
146
|
+
...wrapCalls,
|
|
136
147
|
...assetsToWithdraw.map(
|
|
137
148
|
(t) => this.prepareWithdrawToken(ca.creditFacade, t.token, MAX_UINT256, to)
|
|
138
149
|
)
|
|
@@ -180,7 +191,7 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
180
191
|
operationCalls,
|
|
181
192
|
ca
|
|
182
193
|
);
|
|
183
|
-
const tx =
|
|
194
|
+
const tx = await this.multicallTx(cm, ca.creditAccount, calls);
|
|
184
195
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
185
196
|
}
|
|
186
197
|
async previewWithdrawLlamathenaProportionally(_) {
|