@gearbox-protocol/sdk 13.0.0-next.21 → 13.0.0-next.22
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/sdk/accounts/AbstractCreditAccountsService.js +319 -22
- package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +5 -1
- package/dist/cjs/sdk/market/pool/SecuritizeKYCFactory.js +20 -0
- package/dist/cjs/sdk/sdk-legacy/core/creditAccount.js +2 -0
- package/dist/esm/sdk/accounts/AbstractCreditAccountsService.js +319 -24
- package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +5 -1
- package/dist/esm/sdk/market/pool/SecuritizeKYCFactory.js +20 -0
- package/dist/esm/sdk/sdk-legacy/core/creditAccount.js +2 -0
- package/dist/types/sdk/accounts/AbstractCreditAccountsService.d.ts +71 -4
- package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +1 -1
- package/dist/types/sdk/accounts/types.d.ts +65 -5
- package/dist/types/sdk/market/pool/SecuritizeKYCFactory.d.ts +7 -0
- package/dist/types/sdk/sdk-legacy/core/creditAccount.d.ts +1 -0
- package/dist/types/sdk/sdk-legacy/payload/creditAccount.d.ts +1 -0
- package/package.json +1 -1
|
@@ -33,7 +33,6 @@ var import_v300 = require("../../abi/v300.js");
|
|
|
33
33
|
var import_base = require("../base/index.js");
|
|
34
34
|
var import_chains = require("../chain/chains.js");
|
|
35
35
|
var import_constants = require("../constants/index.js");
|
|
36
|
-
var import_market = require("../market/index.js");
|
|
37
36
|
var import_router = require("../router/index.js");
|
|
38
37
|
var import_sdk_legacy = require("../sdk-legacy/index.js");
|
|
39
38
|
var import_utils = require("../utils/index.js");
|
|
@@ -42,6 +41,7 @@ const COMPRESSORS = {
|
|
|
42
41
|
[import_chains.chains.Mainnet.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023",
|
|
43
42
|
[import_chains.chains.Monad.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023"
|
|
44
43
|
};
|
|
44
|
+
const INVESTORS = new import_utils.AddressMap([], "investors");
|
|
45
45
|
function getWithdrawalCompressorAddress(chainId) {
|
|
46
46
|
return COMPRESSORS[chainId];
|
|
47
47
|
}
|
|
@@ -103,6 +103,23 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
103
103
|
});
|
|
104
104
|
return cad;
|
|
105
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Returns credit account data for a single account with the investor address resolved.
|
|
108
|
+
* Loads CA via getCreditAccountData; for KYC underlyings fetches the investor from the KYC factory's getInvestor(creditAccount), otherwise uses the account owner.
|
|
109
|
+
* @param account - Credit account address
|
|
110
|
+
* @param blockNumber - Optional block number for the read
|
|
111
|
+
* @returns CreditAccountDataWithInvestor (CA data + investor address), or undefined if the account is not found
|
|
112
|
+
*/
|
|
113
|
+
async getCreditAccountDataWithInvestor(account, blockNumber) {
|
|
114
|
+
const ca = await this.getCreditAccountData(account, blockNumber);
|
|
115
|
+
if (!ca) return ca;
|
|
116
|
+
const marketSuite = this.sdk.marketRegister.findByCreditManager(
|
|
117
|
+
ca.creditManager
|
|
118
|
+
);
|
|
119
|
+
const factory = await marketSuite.getKYCFactory();
|
|
120
|
+
const investor = factory ? await factory.getInvestor(ca.creditAccount, true) : void 0;
|
|
121
|
+
return { ...ca, investor: investor ?? ca.owner };
|
|
122
|
+
}
|
|
106
123
|
/**
|
|
107
124
|
* Methods to get all credit accounts with some optional filtering
|
|
108
125
|
* Performs all necessary price feed updates under the hood
|
|
@@ -111,7 +128,7 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
111
128
|
* @param blockNumber
|
|
112
129
|
* @returns returned credit accounts are sorted by health factor in ascending order
|
|
113
130
|
*/
|
|
114
|
-
async getCreditAccounts(options, blockNumber) {
|
|
131
|
+
async getCreditAccounts(options, blockNumber, priceUpdate) {
|
|
115
132
|
const {
|
|
116
133
|
creditManager,
|
|
117
134
|
includeZeroDebt = false,
|
|
@@ -133,7 +150,7 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
133
150
|
maxHealthFactor,
|
|
134
151
|
reverting: false
|
|
135
152
|
};
|
|
136
|
-
const { txs: priceUpdateTxs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
|
|
153
|
+
const { txs: priceUpdateTxs } = priceUpdate ?? await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
|
|
137
154
|
ignoreReservePrices ? { main: true } : void 0
|
|
138
155
|
);
|
|
139
156
|
const allCAs = [];
|
|
@@ -162,6 +179,75 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
162
179
|
);
|
|
163
180
|
return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
164
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Returns all credit accounts matching the filter, with investor set on each item.
|
|
184
|
+
* 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.
|
|
185
|
+
* @param options - Filter options (owner, creditManager, health factor, etc.)
|
|
186
|
+
* @param blockNumber - Optional block number for the read
|
|
187
|
+
* @returns Array of credit accounts (with investor field), sorted by health factor ascending
|
|
188
|
+
*/
|
|
189
|
+
async getCreditAccountsWithInvestor(options, blockNumber) {
|
|
190
|
+
const { owner, ignoreReservePrices = false } = options ?? {};
|
|
191
|
+
const priceUpdate = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
|
|
192
|
+
ignoreReservePrices ? { main: true } : void 0
|
|
193
|
+
);
|
|
194
|
+
const { txs: priceUpdateTxs } = priceUpdate;
|
|
195
|
+
const [common, kyc] = await Promise.all([
|
|
196
|
+
this.getCreditAccounts(options, blockNumber),
|
|
197
|
+
owner ? this.getKYCCreditAccountsOfOwner(owner, priceUpdateTxs, blockNumber) : void 0
|
|
198
|
+
]);
|
|
199
|
+
const allCAs = common.map(
|
|
200
|
+
(ca) => ({
|
|
201
|
+
...ca,
|
|
202
|
+
investor: owner || ca.owner
|
|
203
|
+
})
|
|
204
|
+
);
|
|
205
|
+
allCAs.push(...kyc || []);
|
|
206
|
+
return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
207
|
+
}
|
|
208
|
+
async getKYCCreditAccountsOfOwner(owner, priceUpdateTxs, blockNumber) {
|
|
209
|
+
const suites = this.marketConfigurators.map((mc) => {
|
|
210
|
+
const suite = this.sdk.marketRegister.markets.find(
|
|
211
|
+
(m) => m.configurator.address === mc
|
|
212
|
+
);
|
|
213
|
+
return suite;
|
|
214
|
+
});
|
|
215
|
+
const kycCAAddresses = await this.getKYCCaOfInvestor(owner, suites);
|
|
216
|
+
const kycCAs = await this.loadSpecifiedAccounts(
|
|
217
|
+
kycCAAddresses,
|
|
218
|
+
priceUpdateTxs,
|
|
219
|
+
blockNumber
|
|
220
|
+
);
|
|
221
|
+
return kycCAs.map((ca) => ({
|
|
222
|
+
...ca,
|
|
223
|
+
investor: owner
|
|
224
|
+
}));
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Loads credit account data for the given addresses using simulateWithPriceUpdates.
|
|
228
|
+
* Applies the provided price update txs before reading, so returned data is consistent with up-to-date prices.
|
|
229
|
+
* @param accounts - Credit account addresses to load
|
|
230
|
+
* @param priceUpdateTxs - Price feed update txs to simulate before the read (e.g. from generatePriceFeedsUpdateTxs)
|
|
231
|
+
* @param blockNumber - Optional block number for the read
|
|
232
|
+
* @returns Array of CreditAccountData in the same order as accounts (throws if any getCreditAccountData call reverts)
|
|
233
|
+
*/
|
|
234
|
+
async loadSpecifiedAccounts(accounts, priceUpdateTxs, blockNumber) {
|
|
235
|
+
if (accounts.length === 0) return [];
|
|
236
|
+
const list = await (0, import_viem2.simulateWithPriceUpdates)(this.client, {
|
|
237
|
+
priceUpdates: priceUpdateTxs,
|
|
238
|
+
contracts: accounts.map(
|
|
239
|
+
(account) => ({
|
|
240
|
+
abi: import_creditAccountCompressor.creditAccountCompressorAbi,
|
|
241
|
+
address: this.#compressor,
|
|
242
|
+
functionName: "getCreditAccountData",
|
|
243
|
+
args: [account]
|
|
244
|
+
})
|
|
245
|
+
),
|
|
246
|
+
blockNumber,
|
|
247
|
+
gas: this.sdk.gasLimit
|
|
248
|
+
});
|
|
249
|
+
return list;
|
|
250
|
+
}
|
|
165
251
|
/**
|
|
166
252
|
* Method to get all claimable rewards for credit account (ex. stkUSDS SKY rewards)
|
|
167
253
|
Assosiates rewards by adapter + stakedPhantomToken
|
|
@@ -394,6 +480,13 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
394
480
|
closePath
|
|
395
481
|
}) {
|
|
396
482
|
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
483
|
+
await this.sdk.tokensMeta.loadTokenData(cm.underlying);
|
|
484
|
+
const underlying = this.sdk.tokensMeta.mustGet(cm.underlying);
|
|
485
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
486
|
+
throw new Error(
|
|
487
|
+
"closeCreditAccount is not supported for KYC underlying credit accounts"
|
|
488
|
+
);
|
|
489
|
+
}
|
|
397
490
|
const routerCloseResult = closePath || await this.sdk.routerFor(ca).findBestClosePath({
|
|
398
491
|
creditAccount: ca,
|
|
399
492
|
creditManager: cm.creditManager,
|
|
@@ -796,10 +889,9 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
796
889
|
async getApprovalAddress(options) {
|
|
797
890
|
const { creditManager } = options;
|
|
798
891
|
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
799
|
-
|
|
800
|
-
const
|
|
801
|
-
if (
|
|
802
|
-
const factory = new import_market.SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
892
|
+
const marketSuite = this.sdk.marketRegister.findByPool(suite.pool);
|
|
893
|
+
const factory = await marketSuite.getKYCFactory();
|
|
894
|
+
if (factory) {
|
|
803
895
|
if ("creditAccount" in options) {
|
|
804
896
|
return factory.getWallet(options.creditAccount);
|
|
805
897
|
}
|
|
@@ -955,6 +1047,99 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
955
1047
|
);
|
|
956
1048
|
return resp;
|
|
957
1049
|
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Returns multicall entries to redeem (unwrap) KYC ERC-4626 vault shares into underlying for the given credit manager.
|
|
1052
|
+
* Used when withdrawing debt from a KYC market: redeems adapter vault shares so the underlying can be withdrawn.
|
|
1053
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
1054
|
+
* @param amount - Number of vault shares (adapter tokens) to redeem
|
|
1055
|
+
* @param creditManager - Credit manager address
|
|
1056
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
1057
|
+
*/
|
|
1058
|
+
async getKYCUnwrapCalls(amount, creditManager) {
|
|
1059
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
1060
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
1061
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
1062
|
+
return void 0;
|
|
1063
|
+
}
|
|
1064
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
1065
|
+
const adapterAddress = adapter?.address;
|
|
1066
|
+
if (!adapterAddress) {
|
|
1067
|
+
return void 0;
|
|
1068
|
+
}
|
|
1069
|
+
const mc = [
|
|
1070
|
+
{
|
|
1071
|
+
target: adapterAddress,
|
|
1072
|
+
callData: (0, import_viem.encodeFunctionData)({
|
|
1073
|
+
abi: ierc4626AdapterAbi,
|
|
1074
|
+
functionName: "redeem",
|
|
1075
|
+
args: [amount, import_constants.ADDRESS_0X0, import_constants.ADDRESS_0X0]
|
|
1076
|
+
})
|
|
1077
|
+
}
|
|
1078
|
+
];
|
|
1079
|
+
return mc;
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Returns multicall entries to deposit (wrap) underlying into KYC ERC-4626 vault shares for the given credit manager.
|
|
1083
|
+
* Used when adding debt on a KYC market: deposits underlying into the adapter vault so shares are minted on the account.
|
|
1084
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
1085
|
+
* @param amount - Amount of underlying assets to deposit into the vault (in underlying decimals)
|
|
1086
|
+
* @param creditManager - Credit manager address
|
|
1087
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
1088
|
+
*/
|
|
1089
|
+
async getKYCWrapCalls(amount, creditManager) {
|
|
1090
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
1091
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
1092
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
1093
|
+
return void 0;
|
|
1094
|
+
}
|
|
1095
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
1096
|
+
const adapterAddress = adapter?.address;
|
|
1097
|
+
if (!adapterAddress) {
|
|
1098
|
+
return void 0;
|
|
1099
|
+
}
|
|
1100
|
+
const mc = [
|
|
1101
|
+
{
|
|
1102
|
+
target: adapterAddress,
|
|
1103
|
+
callData: (0, import_viem.encodeFunctionData)({
|
|
1104
|
+
abi: ierc4626AdapterAbi,
|
|
1105
|
+
functionName: "deposit",
|
|
1106
|
+
args: [amount, import_constants.ADDRESS_0X0]
|
|
1107
|
+
})
|
|
1108
|
+
}
|
|
1109
|
+
];
|
|
1110
|
+
return mc;
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Returns multicall entries to call redeemDiff on the KYC ERC-4626 adapter for the given credit manager.
|
|
1114
|
+
* Redeems the leftover vault shares (e.g. after repaying debt) so the account does not hold excess KYC vault tokens.
|
|
1115
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
1116
|
+
* @param amount - Leftover vault share amount to redeem (in adapter/vault decimals)
|
|
1117
|
+
* @param creditManager - Credit manager address
|
|
1118
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
1119
|
+
*/
|
|
1120
|
+
async getRedeemDiffCalls(amount, creditManager) {
|
|
1121
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
1122
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
1123
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
1124
|
+
return void 0;
|
|
1125
|
+
}
|
|
1126
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
1127
|
+
const adapterAddress = adapter?.address;
|
|
1128
|
+
if (!adapterAddress) {
|
|
1129
|
+
return void 0;
|
|
1130
|
+
}
|
|
1131
|
+
const mc = [
|
|
1132
|
+
{
|
|
1133
|
+
target: adapterAddress,
|
|
1134
|
+
callData: (0, import_viem.encodeFunctionData)({
|
|
1135
|
+
abi: ierc4626AdapterAbi,
|
|
1136
|
+
functionName: "redeemDiff",
|
|
1137
|
+
args: [amount]
|
|
1138
|
+
})
|
|
1139
|
+
}
|
|
1140
|
+
];
|
|
1141
|
+
return mc;
|
|
1142
|
+
}
|
|
958
1143
|
/**
|
|
959
1144
|
* Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
|
|
960
1145
|
*
|
|
@@ -1221,10 +1406,9 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
1221
1406
|
* @returns
|
|
1222
1407
|
*/
|
|
1223
1408
|
async openCreditAccountTx(suite, to, calls, referralCode) {
|
|
1224
|
-
|
|
1225
|
-
const
|
|
1226
|
-
if (
|
|
1227
|
-
const factory = new import_market.SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
1409
|
+
const marketSuite = this.sdk.marketRegister.findByPool(suite.pool);
|
|
1410
|
+
const factory = await marketSuite.getKYCFactory();
|
|
1411
|
+
if (factory) {
|
|
1228
1412
|
const tokensToRegister = await factory.getDSTokens();
|
|
1229
1413
|
return factory.openCreditAccount(
|
|
1230
1414
|
suite.creditManager.address,
|
|
@@ -1242,11 +1426,12 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
1242
1426
|
* @returns
|
|
1243
1427
|
*/
|
|
1244
1428
|
async multicallTx(suite, creditAccount, calls) {
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1429
|
+
const marketSuite = this.sdk.marketRegister.findByCreditManager(
|
|
1430
|
+
suite.creditManager.address
|
|
1431
|
+
);
|
|
1432
|
+
const factory = await marketSuite.getKYCFactory();
|
|
1433
|
+
if (factory) {
|
|
1248
1434
|
const tokensToRegister = [];
|
|
1249
|
-
const factory = new import_market.SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
1250
1435
|
return factory.multicall(creditAccount, calls, tokensToRegister);
|
|
1251
1436
|
}
|
|
1252
1437
|
return suite.creditFacade.multicall(creditAccount, calls);
|
|
@@ -1260,16 +1445,128 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
|
|
|
1260
1445
|
* @returns
|
|
1261
1446
|
*/
|
|
1262
1447
|
async closeCreditAccountTx(suite, creditAccount, calls, operation) {
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
)
|
|
1448
|
+
const marketSuite = this.sdk.marketRegister.findByCreditManager(
|
|
1449
|
+
suite.creditManager.address
|
|
1450
|
+
);
|
|
1451
|
+
const factory = await marketSuite.getKYCFactory();
|
|
1452
|
+
if (operation === "close") {
|
|
1453
|
+
if (factory) {
|
|
1454
|
+
throw new Error(
|
|
1455
|
+
"CloseOptions=close is not supported for KYC underlying credit accounts"
|
|
1456
|
+
);
|
|
1457
|
+
}
|
|
1458
|
+
return suite.creditFacade.closeCreditAccount(creditAccount, calls);
|
|
1269
1459
|
}
|
|
1270
|
-
|
|
1460
|
+
if (factory) {
|
|
1461
|
+
const tokensToRegister = [];
|
|
1462
|
+
return factory.multicall(creditAccount, calls, tokensToRegister);
|
|
1463
|
+
}
|
|
1464
|
+
return suite.creditFacade.multicall(creditAccount, calls);
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Returns all KYC credit account addresses for an investor across the given market suites.
|
|
1468
|
+
* Resolves KYC factory per suite, then multicalls each factory's getCreditAccounts(investor).
|
|
1469
|
+
* @param investor - Owner address to query
|
|
1470
|
+
* @param suites - Market suites (KYC factories are resolved for each; undefined entries are skipped)
|
|
1471
|
+
* @returns Flat array of credit account addresses from all KYC markets
|
|
1472
|
+
*/
|
|
1473
|
+
async getKYCCaOfInvestor(investor, suites) {
|
|
1474
|
+
if (suites.length === 0 || investor === import_constants.ADDRESS_0X0) return [];
|
|
1475
|
+
const factories = await Promise.all(
|
|
1476
|
+
suites.map((suite) => suite ? suite.getKYCFactory() : void 0)
|
|
1477
|
+
);
|
|
1478
|
+
const safeFactories = factories.reduce(
|
|
1479
|
+
(acc, v) => {
|
|
1480
|
+
if (v) {
|
|
1481
|
+
acc.push(v);
|
|
1482
|
+
}
|
|
1483
|
+
return acc;
|
|
1484
|
+
},
|
|
1485
|
+
[]
|
|
1486
|
+
);
|
|
1487
|
+
const allResp = await this.client.multicall({
|
|
1488
|
+
contracts: [
|
|
1489
|
+
...safeFactories.map((factory) => {
|
|
1490
|
+
return {
|
|
1491
|
+
abi: factory.abi,
|
|
1492
|
+
address: factory.address,
|
|
1493
|
+
functionName: "getCreditAccounts",
|
|
1494
|
+
args: [investor]
|
|
1495
|
+
};
|
|
1496
|
+
})
|
|
1497
|
+
],
|
|
1498
|
+
allowFailure: true,
|
|
1499
|
+
batchSize: 0
|
|
1500
|
+
});
|
|
1501
|
+
const caLists = safeFactories.reduce((acc, _, index) => {
|
|
1502
|
+
const response = allResp[index];
|
|
1503
|
+
acc.push(...response.result || []);
|
|
1504
|
+
return acc;
|
|
1505
|
+
}, []);
|
|
1506
|
+
return caLists;
|
|
1271
1507
|
}
|
|
1272
1508
|
}
|
|
1509
|
+
const ierc4626AdapterAbi = [
|
|
1510
|
+
{
|
|
1511
|
+
inputs: [
|
|
1512
|
+
{ name: "assets", type: "uint256", internalType: "uint256" },
|
|
1513
|
+
{ name: "receiver", type: "address", internalType: "address" }
|
|
1514
|
+
],
|
|
1515
|
+
name: "deposit",
|
|
1516
|
+
outputs: [{ name: "useSafePrices", type: "bool", internalType: "bool" }],
|
|
1517
|
+
stateMutability: "nonpayable",
|
|
1518
|
+
type: "function"
|
|
1519
|
+
},
|
|
1520
|
+
{
|
|
1521
|
+
inputs: [
|
|
1522
|
+
{ name: "shares", type: "uint256", internalType: "uint256" },
|
|
1523
|
+
{ name: "receiver", type: "address", internalType: "address" },
|
|
1524
|
+
{ name: "owner", type: "address", internalType: "address" }
|
|
1525
|
+
],
|
|
1526
|
+
name: "redeem",
|
|
1527
|
+
outputs: [{ name: "useSafePrices", type: "bool", internalType: "bool" }],
|
|
1528
|
+
stateMutability: "nonpayable",
|
|
1529
|
+
type: "function"
|
|
1530
|
+
},
|
|
1531
|
+
{
|
|
1532
|
+
inputs: [
|
|
1533
|
+
{
|
|
1534
|
+
name: "leftoverAmount",
|
|
1535
|
+
type: "uint256",
|
|
1536
|
+
internalType: "uint256"
|
|
1537
|
+
}
|
|
1538
|
+
],
|
|
1539
|
+
name: "redeemDiff",
|
|
1540
|
+
outputs: [
|
|
1541
|
+
{
|
|
1542
|
+
name: "useSafePrices",
|
|
1543
|
+
type: "bool",
|
|
1544
|
+
internalType: "bool"
|
|
1545
|
+
}
|
|
1546
|
+
],
|
|
1547
|
+
stateMutability: "nonpayable",
|
|
1548
|
+
type: "function"
|
|
1549
|
+
},
|
|
1550
|
+
{
|
|
1551
|
+
inputs: [
|
|
1552
|
+
{
|
|
1553
|
+
name: "leftoverAmount",
|
|
1554
|
+
type: "uint256",
|
|
1555
|
+
internalType: "uint256"
|
|
1556
|
+
}
|
|
1557
|
+
],
|
|
1558
|
+
name: "depositDiff",
|
|
1559
|
+
outputs: [
|
|
1560
|
+
{
|
|
1561
|
+
name: "useSafePrices",
|
|
1562
|
+
type: "bool",
|
|
1563
|
+
internalType: "bool"
|
|
1564
|
+
}
|
|
1565
|
+
],
|
|
1566
|
+
stateMutability: "nonpayable",
|
|
1567
|
+
type: "function"
|
|
1568
|
+
}
|
|
1569
|
+
];
|
|
1273
1570
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1274
1571
|
0 && (module.exports = {
|
|
1275
1572
|
AbstractCreditAccountService,
|
|
@@ -113,11 +113,13 @@ class CreditAccountServiceV310 extends import_AbstractCreditAccountsService.Abst
|
|
|
113
113
|
creditAccount: ca,
|
|
114
114
|
permits,
|
|
115
115
|
to,
|
|
116
|
-
tokensToClaim
|
|
116
|
+
tokensToClaim,
|
|
117
|
+
calls: wrapCalls = []
|
|
117
118
|
}) {
|
|
118
119
|
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
119
120
|
const addCollateral = collateralAssets.filter((a) => a.balance > 0);
|
|
120
121
|
const router = this.sdk.routerFor(ca);
|
|
122
|
+
const unwrapCalls = await this.getRedeemDiffCalls(1n, ca.creditManager) ?? [];
|
|
121
123
|
const claimPath = await router.findClaimAllRewards({
|
|
122
124
|
calls: [],
|
|
123
125
|
tokensToClaim,
|
|
@@ -130,8 +132,10 @@ class CreditAccountServiceV310 extends import_AbstractCreditAccountsService.Abst
|
|
|
130
132
|
const calls = [
|
|
131
133
|
...operation === "close" ? [] : priceUpdates,
|
|
132
134
|
...this.prepareAddCollateral(ca.creditFacade, addCollateral, permits),
|
|
135
|
+
...wrapCalls,
|
|
133
136
|
...this.prepareDisableQuotas(ca),
|
|
134
137
|
...this.prepareDecreaseDebt(ca),
|
|
138
|
+
...unwrapCalls,
|
|
135
139
|
...claimPath.calls,
|
|
136
140
|
...this.prepareDisableTokens(ca),
|
|
137
141
|
...assetsToWithdraw.map(
|
|
@@ -23,8 +23,10 @@ __export(SecuritizeKYCFactory_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(SecuritizeKYCFactory_exports);
|
|
24
24
|
var import_iSecuritizeKYCFactory = require("../../../abi/310/iSecuritizeKYCFactory.js");
|
|
25
25
|
var import_base = require("../../base/index.js");
|
|
26
|
+
var import__ = require("../../index.js");
|
|
26
27
|
const abi = import_iSecuritizeKYCFactory.iSecuritizeKYCFactoryAbi;
|
|
27
28
|
class SecuritizeKYCFactory extends import_base.BaseContract {
|
|
29
|
+
investorCache;
|
|
28
30
|
constructor(options, address) {
|
|
29
31
|
super(options, {
|
|
30
32
|
addr: address,
|
|
@@ -41,6 +43,24 @@ class SecuritizeKYCFactory extends import_base.BaseContract {
|
|
|
41
43
|
async getWallet(creditAccount) {
|
|
42
44
|
return this.contract.read.getWallet([creditAccount]);
|
|
43
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Returns the investor address for a credit account.
|
|
48
|
+
* @param creditAccount - Credit account address
|
|
49
|
+
* @param fromCache - If true, use and update an in-memory cache (creditAccount -> investor). On cache miss, loads from contract and stores the result for future calls.
|
|
50
|
+
*/
|
|
51
|
+
async getInvestor(creditAccount, fromCache) {
|
|
52
|
+
if (fromCache && this.investorCache?.has(creditAccount)) {
|
|
53
|
+
return this.investorCache.get(creditAccount);
|
|
54
|
+
}
|
|
55
|
+
const investor = await this.contract.read.getInvestor([creditAccount]);
|
|
56
|
+
if (fromCache) {
|
|
57
|
+
if (!this.investorCache) {
|
|
58
|
+
this.investorCache = new import__.AddressMap();
|
|
59
|
+
}
|
|
60
|
+
this.investorCache.upsert(creditAccount, investor);
|
|
61
|
+
}
|
|
62
|
+
return investor;
|
|
63
|
+
}
|
|
44
64
|
async getDSTokens() {
|
|
45
65
|
const tokens = await this.contract.read.getDSTokens();
|
|
46
66
|
return [...tokens];
|
|
@@ -38,6 +38,7 @@ class CreditAccountData_Legacy {
|
|
|
38
38
|
underlying;
|
|
39
39
|
expirationDate;
|
|
40
40
|
version;
|
|
41
|
+
investor;
|
|
41
42
|
enabledTokensMask;
|
|
42
43
|
healthFactor;
|
|
43
44
|
baseBorrowRateWithoutFee;
|
|
@@ -67,6 +68,7 @@ class CreditAccountData_Legacy {
|
|
|
67
68
|
this.underlying = payload.underlying.toLowerCase();
|
|
68
69
|
this.expirationDate = Number(payload.expirationDate);
|
|
69
70
|
this.version = Number(payload.cfVersion);
|
|
71
|
+
this.investor = payload.investor.toLowerCase();
|
|
70
72
|
this.healthFactor = Number(
|
|
71
73
|
(payload.healthFactor || 0n) * import_constants.PERCENTAGE_FACTOR / import_constants.WAD
|
|
72
74
|
);
|
|
@@ -23,9 +23,6 @@ import {
|
|
|
23
23
|
RAY,
|
|
24
24
|
VERSION_RANGE_310
|
|
25
25
|
} from "../constants/index.js";
|
|
26
|
-
import {
|
|
27
|
-
SecuritizeKYCFactory
|
|
28
|
-
} from "../market/index.js";
|
|
29
26
|
import { assetsMap } from "../router/index.js";
|
|
30
27
|
import { BigIntMath } from "../sdk-legacy/index.js";
|
|
31
28
|
import { AddressMap } from "../utils/index.js";
|
|
@@ -34,6 +31,7 @@ const COMPRESSORS = {
|
|
|
34
31
|
[chains.Mainnet.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023",
|
|
35
32
|
[chains.Monad.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023"
|
|
36
33
|
};
|
|
34
|
+
const INVESTORS = new AddressMap([], "investors");
|
|
37
35
|
function getWithdrawalCompressorAddress(chainId) {
|
|
38
36
|
return COMPRESSORS[chainId];
|
|
39
37
|
}
|
|
@@ -95,6 +93,23 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
95
93
|
});
|
|
96
94
|
return cad;
|
|
97
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Returns credit account data for a single account with the investor address resolved.
|
|
98
|
+
* Loads CA via getCreditAccountData; for KYC underlyings fetches the investor from the KYC factory's getInvestor(creditAccount), otherwise uses the account owner.
|
|
99
|
+
* @param account - Credit account address
|
|
100
|
+
* @param blockNumber - Optional block number for the read
|
|
101
|
+
* @returns CreditAccountDataWithInvestor (CA data + investor address), or undefined if the account is not found
|
|
102
|
+
*/
|
|
103
|
+
async getCreditAccountDataWithInvestor(account, blockNumber) {
|
|
104
|
+
const ca = await this.getCreditAccountData(account, blockNumber);
|
|
105
|
+
if (!ca) return ca;
|
|
106
|
+
const marketSuite = this.sdk.marketRegister.findByCreditManager(
|
|
107
|
+
ca.creditManager
|
|
108
|
+
);
|
|
109
|
+
const factory = await marketSuite.getKYCFactory();
|
|
110
|
+
const investor = factory ? await factory.getInvestor(ca.creditAccount, true) : void 0;
|
|
111
|
+
return { ...ca, investor: investor ?? ca.owner };
|
|
112
|
+
}
|
|
98
113
|
/**
|
|
99
114
|
* Methods to get all credit accounts with some optional filtering
|
|
100
115
|
* Performs all necessary price feed updates under the hood
|
|
@@ -103,7 +118,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
103
118
|
* @param blockNumber
|
|
104
119
|
* @returns returned credit accounts are sorted by health factor in ascending order
|
|
105
120
|
*/
|
|
106
|
-
async getCreditAccounts(options, blockNumber) {
|
|
121
|
+
async getCreditAccounts(options, blockNumber, priceUpdate) {
|
|
107
122
|
const {
|
|
108
123
|
creditManager,
|
|
109
124
|
includeZeroDebt = false,
|
|
@@ -125,7 +140,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
125
140
|
maxHealthFactor,
|
|
126
141
|
reverting: false
|
|
127
142
|
};
|
|
128
|
-
const { txs: priceUpdateTxs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
|
|
143
|
+
const { txs: priceUpdateTxs } = priceUpdate ?? await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
|
|
129
144
|
ignoreReservePrices ? { main: true } : void 0
|
|
130
145
|
);
|
|
131
146
|
const allCAs = [];
|
|
@@ -154,6 +169,75 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
154
169
|
);
|
|
155
170
|
return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
156
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Returns all credit accounts matching the filter, with investor set on each item.
|
|
174
|
+
* 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.
|
|
175
|
+
* @param options - Filter options (owner, creditManager, health factor, etc.)
|
|
176
|
+
* @param blockNumber - Optional block number for the read
|
|
177
|
+
* @returns Array of credit accounts (with investor field), sorted by health factor ascending
|
|
178
|
+
*/
|
|
179
|
+
async getCreditAccountsWithInvestor(options, blockNumber) {
|
|
180
|
+
const { owner, ignoreReservePrices = false } = options ?? {};
|
|
181
|
+
const priceUpdate = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
|
|
182
|
+
ignoreReservePrices ? { main: true } : void 0
|
|
183
|
+
);
|
|
184
|
+
const { txs: priceUpdateTxs } = priceUpdate;
|
|
185
|
+
const [common, kyc] = await Promise.all([
|
|
186
|
+
this.getCreditAccounts(options, blockNumber),
|
|
187
|
+
owner ? this.getKYCCreditAccountsOfOwner(owner, priceUpdateTxs, blockNumber) : void 0
|
|
188
|
+
]);
|
|
189
|
+
const allCAs = common.map(
|
|
190
|
+
(ca) => ({
|
|
191
|
+
...ca,
|
|
192
|
+
investor: owner || ca.owner
|
|
193
|
+
})
|
|
194
|
+
);
|
|
195
|
+
allCAs.push(...kyc || []);
|
|
196
|
+
return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
197
|
+
}
|
|
198
|
+
async getKYCCreditAccountsOfOwner(owner, priceUpdateTxs, blockNumber) {
|
|
199
|
+
const suites = this.marketConfigurators.map((mc) => {
|
|
200
|
+
const suite = this.sdk.marketRegister.markets.find(
|
|
201
|
+
(m) => m.configurator.address === mc
|
|
202
|
+
);
|
|
203
|
+
return suite;
|
|
204
|
+
});
|
|
205
|
+
const kycCAAddresses = await this.getKYCCaOfInvestor(owner, suites);
|
|
206
|
+
const kycCAs = await this.loadSpecifiedAccounts(
|
|
207
|
+
kycCAAddresses,
|
|
208
|
+
priceUpdateTxs,
|
|
209
|
+
blockNumber
|
|
210
|
+
);
|
|
211
|
+
return kycCAs.map((ca) => ({
|
|
212
|
+
...ca,
|
|
213
|
+
investor: owner
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Loads credit account data for the given addresses using simulateWithPriceUpdates.
|
|
218
|
+
* Applies the provided price update txs before reading, so returned data is consistent with up-to-date prices.
|
|
219
|
+
* @param accounts - Credit account addresses to load
|
|
220
|
+
* @param priceUpdateTxs - Price feed update txs to simulate before the read (e.g. from generatePriceFeedsUpdateTxs)
|
|
221
|
+
* @param blockNumber - Optional block number for the read
|
|
222
|
+
* @returns Array of CreditAccountData in the same order as accounts (throws if any getCreditAccountData call reverts)
|
|
223
|
+
*/
|
|
224
|
+
async loadSpecifiedAccounts(accounts, priceUpdateTxs, blockNumber) {
|
|
225
|
+
if (accounts.length === 0) return [];
|
|
226
|
+
const list = await simulateWithPriceUpdates(this.client, {
|
|
227
|
+
priceUpdates: priceUpdateTxs,
|
|
228
|
+
contracts: accounts.map(
|
|
229
|
+
(account) => ({
|
|
230
|
+
abi: creditAccountCompressorAbi,
|
|
231
|
+
address: this.#compressor,
|
|
232
|
+
functionName: "getCreditAccountData",
|
|
233
|
+
args: [account]
|
|
234
|
+
})
|
|
235
|
+
),
|
|
236
|
+
blockNumber,
|
|
237
|
+
gas: this.sdk.gasLimit
|
|
238
|
+
});
|
|
239
|
+
return list;
|
|
240
|
+
}
|
|
157
241
|
/**
|
|
158
242
|
* Method to get all claimable rewards for credit account (ex. stkUSDS SKY rewards)
|
|
159
243
|
Assosiates rewards by adapter + stakedPhantomToken
|
|
@@ -386,6 +470,13 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
386
470
|
closePath
|
|
387
471
|
}) {
|
|
388
472
|
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
473
|
+
await this.sdk.tokensMeta.loadTokenData(cm.underlying);
|
|
474
|
+
const underlying = this.sdk.tokensMeta.mustGet(cm.underlying);
|
|
475
|
+
if (this.sdk.tokensMeta.isKYCUnderlying(underlying)) {
|
|
476
|
+
throw new Error(
|
|
477
|
+
"closeCreditAccount is not supported for KYC underlying credit accounts"
|
|
478
|
+
);
|
|
479
|
+
}
|
|
389
480
|
const routerCloseResult = closePath || await this.sdk.routerFor(ca).findBestClosePath({
|
|
390
481
|
creditAccount: ca,
|
|
391
482
|
creditManager: cm.creditManager,
|
|
@@ -788,10 +879,9 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
788
879
|
async getApprovalAddress(options) {
|
|
789
880
|
const { creditManager } = options;
|
|
790
881
|
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
791
|
-
|
|
792
|
-
const
|
|
793
|
-
if (
|
|
794
|
-
const factory = new SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
882
|
+
const marketSuite = this.sdk.marketRegister.findByPool(suite.pool);
|
|
883
|
+
const factory = await marketSuite.getKYCFactory();
|
|
884
|
+
if (factory) {
|
|
795
885
|
if ("creditAccount" in options) {
|
|
796
886
|
return factory.getWallet(options.creditAccount);
|
|
797
887
|
}
|
|
@@ -947,6 +1037,99 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
947
1037
|
);
|
|
948
1038
|
return resp;
|
|
949
1039
|
}
|
|
1040
|
+
/**
|
|
1041
|
+
* Returns multicall entries to redeem (unwrap) KYC ERC-4626 vault shares into underlying for the given credit manager.
|
|
1042
|
+
* Used when withdrawing debt from a KYC market: redeems adapter vault shares so the underlying can be withdrawn.
|
|
1043
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
1044
|
+
* @param amount - Number of vault shares (adapter tokens) to redeem
|
|
1045
|
+
* @param creditManager - Credit manager address
|
|
1046
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
1047
|
+
*/
|
|
1048
|
+
async getKYCUnwrapCalls(amount, creditManager) {
|
|
1049
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
1050
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
1051
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
1052
|
+
return void 0;
|
|
1053
|
+
}
|
|
1054
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
1055
|
+
const adapterAddress = adapter?.address;
|
|
1056
|
+
if (!adapterAddress) {
|
|
1057
|
+
return void 0;
|
|
1058
|
+
}
|
|
1059
|
+
const mc = [
|
|
1060
|
+
{
|
|
1061
|
+
target: adapterAddress,
|
|
1062
|
+
callData: encodeFunctionData({
|
|
1063
|
+
abi: ierc4626AdapterAbi,
|
|
1064
|
+
functionName: "redeem",
|
|
1065
|
+
args: [amount, ADDRESS_0X0, ADDRESS_0X0]
|
|
1066
|
+
})
|
|
1067
|
+
}
|
|
1068
|
+
];
|
|
1069
|
+
return mc;
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Returns multicall entries to deposit (wrap) underlying into KYC ERC-4626 vault shares for the given credit manager.
|
|
1073
|
+
* Used when adding debt on a KYC market: deposits underlying into the adapter vault so shares are minted on the account.
|
|
1074
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
1075
|
+
* @param amount - Amount of underlying assets to deposit into the vault (in underlying decimals)
|
|
1076
|
+
* @param creditManager - Credit manager address
|
|
1077
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
1078
|
+
*/
|
|
1079
|
+
async getKYCWrapCalls(amount, creditManager) {
|
|
1080
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
1081
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
1082
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
1083
|
+
return void 0;
|
|
1084
|
+
}
|
|
1085
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
1086
|
+
const adapterAddress = adapter?.address;
|
|
1087
|
+
if (!adapterAddress) {
|
|
1088
|
+
return void 0;
|
|
1089
|
+
}
|
|
1090
|
+
const mc = [
|
|
1091
|
+
{
|
|
1092
|
+
target: adapterAddress,
|
|
1093
|
+
callData: encodeFunctionData({
|
|
1094
|
+
abi: ierc4626AdapterAbi,
|
|
1095
|
+
functionName: "deposit",
|
|
1096
|
+
args: [amount, ADDRESS_0X0]
|
|
1097
|
+
})
|
|
1098
|
+
}
|
|
1099
|
+
];
|
|
1100
|
+
return mc;
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Returns multicall entries to call redeemDiff on the KYC ERC-4626 adapter for the given credit manager.
|
|
1104
|
+
* Redeems the leftover vault shares (e.g. after repaying debt) so the account does not hold excess KYC vault tokens.
|
|
1105
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
1106
|
+
* @param amount - Leftover vault share amount to redeem (in adapter/vault decimals)
|
|
1107
|
+
* @param creditManager - Credit manager address
|
|
1108
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
1109
|
+
*/
|
|
1110
|
+
async getRedeemDiffCalls(amount, creditManager) {
|
|
1111
|
+
const suite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
1112
|
+
const meta = this.sdk.tokensMeta.mustGet(suite.underlying);
|
|
1113
|
+
if (!this.sdk.tokensMeta.isKYCUnderlying(meta)) {
|
|
1114
|
+
return void 0;
|
|
1115
|
+
}
|
|
1116
|
+
const adapter = suite.creditManager.adapters.get(meta.addr);
|
|
1117
|
+
const adapterAddress = adapter?.address;
|
|
1118
|
+
if (!adapterAddress) {
|
|
1119
|
+
return void 0;
|
|
1120
|
+
}
|
|
1121
|
+
const mc = [
|
|
1122
|
+
{
|
|
1123
|
+
target: adapterAddress,
|
|
1124
|
+
callData: encodeFunctionData({
|
|
1125
|
+
abi: ierc4626AdapterAbi,
|
|
1126
|
+
functionName: "redeemDiff",
|
|
1127
|
+
args: [amount]
|
|
1128
|
+
})
|
|
1129
|
+
}
|
|
1130
|
+
];
|
|
1131
|
+
return mc;
|
|
1132
|
+
}
|
|
950
1133
|
/**
|
|
951
1134
|
* Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
|
|
952
1135
|
*
|
|
@@ -1213,10 +1396,9 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
1213
1396
|
* @returns
|
|
1214
1397
|
*/
|
|
1215
1398
|
async openCreditAccountTx(suite, to, calls, referralCode) {
|
|
1216
|
-
|
|
1217
|
-
const
|
|
1218
|
-
if (
|
|
1219
|
-
const factory = new SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
1399
|
+
const marketSuite = this.sdk.marketRegister.findByPool(suite.pool);
|
|
1400
|
+
const factory = await marketSuite.getKYCFactory();
|
|
1401
|
+
if (factory) {
|
|
1220
1402
|
const tokensToRegister = await factory.getDSTokens();
|
|
1221
1403
|
return factory.openCreditAccount(
|
|
1222
1404
|
suite.creditManager.address,
|
|
@@ -1234,11 +1416,12 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
1234
1416
|
* @returns
|
|
1235
1417
|
*/
|
|
1236
1418
|
async multicallTx(suite, creditAccount, calls) {
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1419
|
+
const marketSuite = this.sdk.marketRegister.findByCreditManager(
|
|
1420
|
+
suite.creditManager.address
|
|
1421
|
+
);
|
|
1422
|
+
const factory = await marketSuite.getKYCFactory();
|
|
1423
|
+
if (factory) {
|
|
1240
1424
|
const tokensToRegister = [];
|
|
1241
|
-
const factory = new SecuritizeKYCFactory(this.sdk, underlying.kycFactory);
|
|
1242
1425
|
return factory.multicall(creditAccount, calls, tokensToRegister);
|
|
1243
1426
|
}
|
|
1244
1427
|
return suite.creditFacade.multicall(creditAccount, calls);
|
|
@@ -1252,16 +1435,128 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
1252
1435
|
* @returns
|
|
1253
1436
|
*/
|
|
1254
1437
|
async closeCreditAccountTx(suite, creditAccount, calls, operation) {
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
)
|
|
1438
|
+
const marketSuite = this.sdk.marketRegister.findByCreditManager(
|
|
1439
|
+
suite.creditManager.address
|
|
1440
|
+
);
|
|
1441
|
+
const factory = await marketSuite.getKYCFactory();
|
|
1442
|
+
if (operation === "close") {
|
|
1443
|
+
if (factory) {
|
|
1444
|
+
throw new Error(
|
|
1445
|
+
"CloseOptions=close is not supported for KYC underlying credit accounts"
|
|
1446
|
+
);
|
|
1447
|
+
}
|
|
1448
|
+
return suite.creditFacade.closeCreditAccount(creditAccount, calls);
|
|
1261
1449
|
}
|
|
1262
|
-
|
|
1450
|
+
if (factory) {
|
|
1451
|
+
const tokensToRegister = [];
|
|
1452
|
+
return factory.multicall(creditAccount, calls, tokensToRegister);
|
|
1453
|
+
}
|
|
1454
|
+
return suite.creditFacade.multicall(creditAccount, calls);
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Returns all KYC credit account addresses for an investor across the given market suites.
|
|
1458
|
+
* Resolves KYC factory per suite, then multicalls each factory's getCreditAccounts(investor).
|
|
1459
|
+
* @param investor - Owner address to query
|
|
1460
|
+
* @param suites - Market suites (KYC factories are resolved for each; undefined entries are skipped)
|
|
1461
|
+
* @returns Flat array of credit account addresses from all KYC markets
|
|
1462
|
+
*/
|
|
1463
|
+
async getKYCCaOfInvestor(investor, suites) {
|
|
1464
|
+
if (suites.length === 0 || investor === ADDRESS_0X0) return [];
|
|
1465
|
+
const factories = await Promise.all(
|
|
1466
|
+
suites.map((suite) => suite ? suite.getKYCFactory() : void 0)
|
|
1467
|
+
);
|
|
1468
|
+
const safeFactories = factories.reduce(
|
|
1469
|
+
(acc, v) => {
|
|
1470
|
+
if (v) {
|
|
1471
|
+
acc.push(v);
|
|
1472
|
+
}
|
|
1473
|
+
return acc;
|
|
1474
|
+
},
|
|
1475
|
+
[]
|
|
1476
|
+
);
|
|
1477
|
+
const allResp = await this.client.multicall({
|
|
1478
|
+
contracts: [
|
|
1479
|
+
...safeFactories.map((factory) => {
|
|
1480
|
+
return {
|
|
1481
|
+
abi: factory.abi,
|
|
1482
|
+
address: factory.address,
|
|
1483
|
+
functionName: "getCreditAccounts",
|
|
1484
|
+
args: [investor]
|
|
1485
|
+
};
|
|
1486
|
+
})
|
|
1487
|
+
],
|
|
1488
|
+
allowFailure: true,
|
|
1489
|
+
batchSize: 0
|
|
1490
|
+
});
|
|
1491
|
+
const caLists = safeFactories.reduce((acc, _, index) => {
|
|
1492
|
+
const response = allResp[index];
|
|
1493
|
+
acc.push(...response.result || []);
|
|
1494
|
+
return acc;
|
|
1495
|
+
}, []);
|
|
1496
|
+
return caLists;
|
|
1263
1497
|
}
|
|
1264
1498
|
}
|
|
1499
|
+
const ierc4626AdapterAbi = [
|
|
1500
|
+
{
|
|
1501
|
+
inputs: [
|
|
1502
|
+
{ name: "assets", type: "uint256", internalType: "uint256" },
|
|
1503
|
+
{ name: "receiver", type: "address", internalType: "address" }
|
|
1504
|
+
],
|
|
1505
|
+
name: "deposit",
|
|
1506
|
+
outputs: [{ name: "useSafePrices", type: "bool", internalType: "bool" }],
|
|
1507
|
+
stateMutability: "nonpayable",
|
|
1508
|
+
type: "function"
|
|
1509
|
+
},
|
|
1510
|
+
{
|
|
1511
|
+
inputs: [
|
|
1512
|
+
{ name: "shares", type: "uint256", internalType: "uint256" },
|
|
1513
|
+
{ name: "receiver", type: "address", internalType: "address" },
|
|
1514
|
+
{ name: "owner", type: "address", internalType: "address" }
|
|
1515
|
+
],
|
|
1516
|
+
name: "redeem",
|
|
1517
|
+
outputs: [{ name: "useSafePrices", type: "bool", internalType: "bool" }],
|
|
1518
|
+
stateMutability: "nonpayable",
|
|
1519
|
+
type: "function"
|
|
1520
|
+
},
|
|
1521
|
+
{
|
|
1522
|
+
inputs: [
|
|
1523
|
+
{
|
|
1524
|
+
name: "leftoverAmount",
|
|
1525
|
+
type: "uint256",
|
|
1526
|
+
internalType: "uint256"
|
|
1527
|
+
}
|
|
1528
|
+
],
|
|
1529
|
+
name: "redeemDiff",
|
|
1530
|
+
outputs: [
|
|
1531
|
+
{
|
|
1532
|
+
name: "useSafePrices",
|
|
1533
|
+
type: "bool",
|
|
1534
|
+
internalType: "bool"
|
|
1535
|
+
}
|
|
1536
|
+
],
|
|
1537
|
+
stateMutability: "nonpayable",
|
|
1538
|
+
type: "function"
|
|
1539
|
+
},
|
|
1540
|
+
{
|
|
1541
|
+
inputs: [
|
|
1542
|
+
{
|
|
1543
|
+
name: "leftoverAmount",
|
|
1544
|
+
type: "uint256",
|
|
1545
|
+
internalType: "uint256"
|
|
1546
|
+
}
|
|
1547
|
+
],
|
|
1548
|
+
name: "depositDiff",
|
|
1549
|
+
outputs: [
|
|
1550
|
+
{
|
|
1551
|
+
name: "useSafePrices",
|
|
1552
|
+
type: "bool",
|
|
1553
|
+
internalType: "bool"
|
|
1554
|
+
}
|
|
1555
|
+
],
|
|
1556
|
+
stateMutability: "nonpayable",
|
|
1557
|
+
type: "function"
|
|
1558
|
+
}
|
|
1559
|
+
];
|
|
1265
1560
|
export {
|
|
1266
1561
|
AbstractCreditAccountService,
|
|
1267
1562
|
getWithdrawalCompressorAddress
|
|
@@ -90,11 +90,13 @@ 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
|
calls: [],
|
|
100
102
|
tokensToClaim,
|
|
@@ -107,8 +109,10 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
107
109
|
const calls = [
|
|
108
110
|
...operation === "close" ? [] : priceUpdates,
|
|
109
111
|
...this.prepareAddCollateral(ca.creditFacade, addCollateral, permits),
|
|
112
|
+
...wrapCalls,
|
|
110
113
|
...this.prepareDisableQuotas(ca),
|
|
111
114
|
...this.prepareDecreaseDebt(ca),
|
|
115
|
+
...unwrapCalls,
|
|
112
116
|
...claimPath.calls,
|
|
113
117
|
...this.prepareDisableTokens(ca),
|
|
114
118
|
...assetsToWithdraw.map(
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { iSecuritizeKYCFactoryAbi } from "../../../abi/310/iSecuritizeKYCFactory.js";
|
|
2
2
|
import { BaseContract } from "../../base/index.js";
|
|
3
|
+
import { AddressMap } from "../../index.js";
|
|
3
4
|
const abi = iSecuritizeKYCFactoryAbi;
|
|
4
5
|
class SecuritizeKYCFactory extends BaseContract {
|
|
6
|
+
investorCache;
|
|
5
7
|
constructor(options, address) {
|
|
6
8
|
super(options, {
|
|
7
9
|
addr: address,
|
|
@@ -18,6 +20,24 @@ class SecuritizeKYCFactory extends BaseContract {
|
|
|
18
20
|
async getWallet(creditAccount) {
|
|
19
21
|
return this.contract.read.getWallet([creditAccount]);
|
|
20
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns the investor address for a credit account.
|
|
25
|
+
* @param creditAccount - Credit account address
|
|
26
|
+
* @param fromCache - If true, use and update an in-memory cache (creditAccount -> investor). On cache miss, loads from contract and stores the result for future calls.
|
|
27
|
+
*/
|
|
28
|
+
async getInvestor(creditAccount, fromCache) {
|
|
29
|
+
if (fromCache && this.investorCache?.has(creditAccount)) {
|
|
30
|
+
return this.investorCache.get(creditAccount);
|
|
31
|
+
}
|
|
32
|
+
const investor = await this.contract.read.getInvestor([creditAccount]);
|
|
33
|
+
if (fromCache) {
|
|
34
|
+
if (!this.investorCache) {
|
|
35
|
+
this.investorCache = new AddressMap();
|
|
36
|
+
}
|
|
37
|
+
this.investorCache.upsert(creditAccount, investor);
|
|
38
|
+
}
|
|
39
|
+
return investor;
|
|
40
|
+
}
|
|
21
41
|
async getDSTokens() {
|
|
22
42
|
const tokens = await this.contract.read.getDSTokens();
|
|
23
43
|
return [...tokens];
|
|
@@ -24,6 +24,7 @@ class CreditAccountData_Legacy {
|
|
|
24
24
|
underlying;
|
|
25
25
|
expirationDate;
|
|
26
26
|
version;
|
|
27
|
+
investor;
|
|
27
28
|
enabledTokensMask;
|
|
28
29
|
healthFactor;
|
|
29
30
|
baseBorrowRateWithoutFee;
|
|
@@ -53,6 +54,7 @@ class CreditAccountData_Legacy {
|
|
|
53
54
|
this.underlying = payload.underlying.toLowerCase();
|
|
54
55
|
this.expirationDate = Number(payload.expirationDate);
|
|
55
56
|
this.version = Number(payload.cfVersion);
|
|
57
|
+
this.investor = payload.investor.toLowerCase();
|
|
56
58
|
this.healthFactor = Number(
|
|
57
59
|
(payload.healthFactor || 0n) * PERCENTAGE_FACTOR / WAD
|
|
58
60
|
);
|
|
@@ -2,10 +2,10 @@ import type { Address } from "viem";
|
|
|
2
2
|
import type { CreditAccountData } from "../base/index.js";
|
|
3
3
|
import { SDKConstruct } from "../base/index.js";
|
|
4
4
|
import type { GearboxSDK } from "../GearboxSDK.js";
|
|
5
|
-
import {
|
|
5
|
+
import type { CreditSuite, MarketSuite, OnDemandPriceUpdates, PriceUpdateV300, PriceUpdateV310, UpdatePriceFeedsResult } from "../market/index.js";
|
|
6
6
|
import { type Asset, type RouterCASlice } from "../router/index.js";
|
|
7
|
-
import type { MultiCall, RawTx } from "../types/index.js";
|
|
8
|
-
import type { AccountToCheck, AddCollateralProps, ChangeDeptProps, ClaimDelayedProps, CloseCreditAccountProps, CloseCreditAccountResult, CloseOptions, CreditAccountOperationResult, EnableTokensProps, ExecuteSwapProps, FullyLiquidateProps, FullyLiquidateResult, GetApprovalAddressProps, GetConnectedBotsResult, GetConnectedMigrationBotsResult, GetCreditAccountsOptions, GetPendingWithdrawalsProps, GetPendingWithdrawalsResult, OpenCAProps, PermitResult, PrepareUpdateQuotasProps, PreviewDelayedWithdrawalProps, PreviewDelayedWithdrawalResult, PriceUpdatesOptions, Rewards, StartDelayedWithdrawalProps, UpdateQuotasProps } from "./types.js";
|
|
7
|
+
import type { IPriceUpdateTx, MultiCall, RawTx } from "../types/index.js";
|
|
8
|
+
import type { AccountToCheck, AddCollateralProps, ChangeDeptProps, ClaimDelayedProps, CloseCreditAccountProps, CloseCreditAccountResult, CloseOptions, CreditAccountDataWithInvestor, CreditAccountOperationResult, EnableTokensProps, ExecuteSwapProps, FullyLiquidateProps, FullyLiquidateResult, GetApprovalAddressProps, GetConnectedBotsResult, GetConnectedMigrationBotsResult, GetCreditAccountsOptions, GetPendingWithdrawalsProps, GetPendingWithdrawalsResult, OpenCAProps, PermitResult, PrepareUpdateQuotasProps, PreviewDelayedWithdrawalProps, PreviewDelayedWithdrawalResult, PriceUpdatesOptions, Rewards, StartDelayedWithdrawalProps, UpdateQuotasProps } from "./types.js";
|
|
9
9
|
export interface CreditAccountServiceOptions {
|
|
10
10
|
batchSize?: number;
|
|
11
11
|
}
|
|
@@ -21,6 +21,14 @@ export declare abstract class AbstractCreditAccountService extends SDKConstruct
|
|
|
21
21
|
* @returns
|
|
22
22
|
*/
|
|
23
23
|
getCreditAccountData(account: Address, blockNumber?: bigint): Promise<CreditAccountData | undefined>;
|
|
24
|
+
/**
|
|
25
|
+
* Returns credit account data for a single account with the investor address resolved.
|
|
26
|
+
* Loads CA via getCreditAccountData; for KYC underlyings fetches the investor from the KYC factory's getInvestor(creditAccount), otherwise uses the account owner.
|
|
27
|
+
* @param account - Credit account address
|
|
28
|
+
* @param blockNumber - Optional block number for the read
|
|
29
|
+
* @returns CreditAccountDataWithInvestor (CA data + investor address), or undefined if the account is not found
|
|
30
|
+
*/
|
|
31
|
+
getCreditAccountDataWithInvestor(account: Address, blockNumber?: bigint): Promise<CreditAccountDataWithInvestor | undefined>;
|
|
24
32
|
/**
|
|
25
33
|
* Methods to get all credit accounts with some optional filtering
|
|
26
34
|
* Performs all necessary price feed updates under the hood
|
|
@@ -29,7 +37,31 @@ export declare abstract class AbstractCreditAccountService extends SDKConstruct
|
|
|
29
37
|
* @param blockNumber
|
|
30
38
|
* @returns returned credit accounts are sorted by health factor in ascending order
|
|
31
39
|
*/
|
|
32
|
-
getCreditAccounts(options?: GetCreditAccountsOptions, blockNumber?: bigint): Promise<Array<CreditAccountData>>;
|
|
40
|
+
getCreditAccounts(options?: GetCreditAccountsOptions, blockNumber?: bigint, priceUpdate?: UpdatePriceFeedsResult): Promise<Array<CreditAccountData>>;
|
|
41
|
+
/**
|
|
42
|
+
* Returns all credit accounts matching the filter, with investor set on each item.
|
|
43
|
+
* 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.
|
|
44
|
+
* @param options - Filter options (owner, creditManager, health factor, etc.)
|
|
45
|
+
* @param blockNumber - Optional block number for the read
|
|
46
|
+
* @returns Array of credit accounts (with investor field), sorted by health factor ascending
|
|
47
|
+
*/
|
|
48
|
+
getCreditAccountsWithInvestor(options?: GetCreditAccountsOptions, blockNumber?: bigint): Promise<Array<CreditAccountDataWithInvestor>>;
|
|
49
|
+
protected getKYCCreditAccountsOfOwner(owner: Address, priceUpdateTxs: IPriceUpdateTx<{
|
|
50
|
+
priceFeed: `0x${string}`;
|
|
51
|
+
timestamp: number;
|
|
52
|
+
}>[], blockNumber?: bigint): Promise<Array<CreditAccountDataWithInvestor>>;
|
|
53
|
+
/**
|
|
54
|
+
* Loads credit account data for the given addresses using simulateWithPriceUpdates.
|
|
55
|
+
* Applies the provided price update txs before reading, so returned data is consistent with up-to-date prices.
|
|
56
|
+
* @param accounts - Credit account addresses to load
|
|
57
|
+
* @param priceUpdateTxs - Price feed update txs to simulate before the read (e.g. from generatePriceFeedsUpdateTxs)
|
|
58
|
+
* @param blockNumber - Optional block number for the read
|
|
59
|
+
* @returns Array of CreditAccountData in the same order as accounts (throws if any getCreditAccountData call reverts)
|
|
60
|
+
*/
|
|
61
|
+
loadSpecifiedAccounts(accounts: Address[], priceUpdateTxs: IPriceUpdateTx<{
|
|
62
|
+
priceFeed: `0x${string}`;
|
|
63
|
+
timestamp: number;
|
|
64
|
+
}>[], blockNumber?: bigint): Promise<Array<CreditAccountData>>;
|
|
33
65
|
/**
|
|
34
66
|
* Method to get all claimable rewards for credit account (ex. stkUSDS SKY rewards)
|
|
35
67
|
Assosiates rewards by adapter + stakedPhantomToken
|
|
@@ -179,6 +211,33 @@ export declare abstract class AbstractCreditAccountService extends SDKConstruct
|
|
|
179
211
|
* @param ca
|
|
180
212
|
*/
|
|
181
213
|
getOptimalHFForPartialLiquidation(ca: CreditAccountData): bigint;
|
|
214
|
+
/**
|
|
215
|
+
* Returns multicall entries to redeem (unwrap) KYC ERC-4626 vault shares into underlying for the given credit manager.
|
|
216
|
+
* Used when withdrawing debt from a KYC market: redeems adapter vault shares so the underlying can be withdrawn.
|
|
217
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
218
|
+
* @param amount - Number of vault shares (adapter tokens) to redeem
|
|
219
|
+
* @param creditManager - Credit manager address
|
|
220
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
221
|
+
*/
|
|
222
|
+
getKYCUnwrapCalls(amount: bigint, creditManager: Address): Promise<Array<MultiCall> | undefined>;
|
|
223
|
+
/**
|
|
224
|
+
* Returns multicall entries to deposit (wrap) underlying into KYC ERC-4626 vault shares for the given credit manager.
|
|
225
|
+
* Used when adding debt on a KYC market: deposits underlying into the adapter vault so shares are minted on the account.
|
|
226
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
227
|
+
* @param amount - Amount of underlying assets to deposit into the vault (in underlying decimals)
|
|
228
|
+
* @param creditManager - Credit manager address
|
|
229
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
230
|
+
*/
|
|
231
|
+
getKYCWrapCalls(amount: bigint, creditManager: Address): Promise<Array<MultiCall> | undefined>;
|
|
232
|
+
/**
|
|
233
|
+
* Returns multicall entries to call redeemDiff on the KYC ERC-4626 adapter for the given credit manager.
|
|
234
|
+
* Redeems the leftover vault shares (e.g. after repaying debt) so the account does not hold excess KYC vault tokens.
|
|
235
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
236
|
+
* @param amount - Leftover vault share amount to redeem (in adapter/vault decimals)
|
|
237
|
+
* @param creditManager - Credit manager address
|
|
238
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
239
|
+
*/
|
|
240
|
+
getRedeemDiffCalls(amount: bigint, creditManager: Address): Promise<Array<MultiCall> | undefined>;
|
|
182
241
|
/**
|
|
183
242
|
* Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
|
|
184
243
|
*
|
|
@@ -242,4 +301,12 @@ export declare abstract class AbstractCreditAccountService extends SDKConstruct
|
|
|
242
301
|
* @returns
|
|
243
302
|
*/
|
|
244
303
|
protected closeCreditAccountTx(suite: CreditSuite, creditAccount: Address, calls: MultiCall[], operation: CloseOptions): Promise<RawTx>;
|
|
304
|
+
/**
|
|
305
|
+
* Returns all KYC credit account addresses for an investor across the given market suites.
|
|
306
|
+
* Resolves KYC factory per suite, then multicalls each factory's getCreditAccounts(investor).
|
|
307
|
+
* @param investor - Owner address to query
|
|
308
|
+
* @param suites - Market suites (KYC factories are resolved for each; undefined entries are skipped)
|
|
309
|
+
* @returns Flat array of credit account addresses from all KYC markets
|
|
310
|
+
*/
|
|
311
|
+
protected getKYCCaOfInvestor(investor: Address, suites: Array<MarketSuite | undefined>): Promise<`0x${string}`[]>;
|
|
245
312
|
}
|
|
@@ -12,7 +12,7 @@ export declare class CreditAccountServiceV310 extends AbstractCreditAccountServi
|
|
|
12
12
|
/**
|
|
13
13
|
* Implements {@link ICreditAccountsService.repayCreditAccount}
|
|
14
14
|
*/
|
|
15
|
-
repayCreditAccount({ operation, collateralAssets, assetsToWithdraw, creditAccount: ca, permits, to, tokensToClaim, }: RepayCreditAccountProps): Promise<CreditAccountOperationResult>;
|
|
15
|
+
repayCreditAccount({ operation, collateralAssets, assetsToWithdraw, creditAccount: ca, permits, to, tokensToClaim, calls: wrapCalls, }: RepayCreditAccountProps): Promise<CreditAccountOperationResult>;
|
|
16
16
|
/**
|
|
17
17
|
* Implements {@link ICreditAccountsService.repayAndLiquidateCreditAccount}
|
|
18
18
|
*/
|
|
@@ -5,7 +5,7 @@ import type { ConnectedBotData, Construct, CreditAccountData } from "../base/ind
|
|
|
5
5
|
import type { GearboxSDK } from "../GearboxSDK.js";
|
|
6
6
|
import type { CreditSuite, OnDemandPriceUpdates, PriceUpdateV300, PriceUpdateV310, UpdatePriceFeedsResult } from "../market/index.js";
|
|
7
7
|
import type { Asset, CreditAccountTokensSlice, RouterCASlice, RouterCloseResult } from "../router/index.js";
|
|
8
|
-
import type { MultiCall, RawTx } from "../types/index.js";
|
|
8
|
+
import type { IPriceUpdateTx, MultiCall, RawTx } from "../types/index.js";
|
|
9
9
|
export type GetCreditAccountsArgs = ContractFunctionArgs<typeof creditAccountCompressorAbi, "pure" | "view", "getCreditAccounts">;
|
|
10
10
|
export interface CreditAccountFilter {
|
|
11
11
|
owner: Address;
|
|
@@ -83,6 +83,10 @@ export interface CloseCreditAccountProps {
|
|
|
83
83
|
closePath?: RouterCloseResult;
|
|
84
84
|
}
|
|
85
85
|
export interface RepayCreditAccountProps extends RepayAndLiquidateCreditAccountProps {
|
|
86
|
+
/**
|
|
87
|
+
* Swap calls for repay
|
|
88
|
+
*/
|
|
89
|
+
calls?: Array<MultiCall>;
|
|
86
90
|
/**
|
|
87
91
|
* close or zeroDebt
|
|
88
92
|
*/
|
|
@@ -454,6 +458,9 @@ export type GetApprovalAddressProps = {
|
|
|
454
458
|
creditManager: Address;
|
|
455
459
|
creditAccount: Address;
|
|
456
460
|
};
|
|
461
|
+
export type CreditAccountDataWithInvestor = CreditAccountData & {
|
|
462
|
+
investor: Address;
|
|
463
|
+
};
|
|
457
464
|
export interface ICreditAccountsService extends Construct {
|
|
458
465
|
sdk: GearboxSDK;
|
|
459
466
|
/**
|
|
@@ -464,15 +471,41 @@ export interface ICreditAccountsService extends Construct {
|
|
|
464
471
|
* @returns
|
|
465
472
|
*/
|
|
466
473
|
getCreditAccountData(account: Address, blockNumber?: bigint): Promise<CreditAccountData | undefined>;
|
|
474
|
+
/**
|
|
475
|
+
* Returns credit account data for a single account with the investor address resolved (from KYC factory when applicable).
|
|
476
|
+
* @param account - Credit account address
|
|
477
|
+
* @param blockNumber - Optional block number for the read
|
|
478
|
+
* @returns CreditAccountDataWithInvestor, or undefined if the account is not found
|
|
479
|
+
*/
|
|
480
|
+
getCreditAccountDataWithInvestor(account: Address, blockNumber?: bigint): Promise<CreditAccountDataWithInvestor | undefined>;
|
|
467
481
|
/**
|
|
468
482
|
* Methods to get all credit accounts with some optional filtering
|
|
469
483
|
* Performs all necessary price feed updates under the hood
|
|
470
484
|
*
|
|
471
485
|
* @param options
|
|
472
486
|
* @param blockNumber
|
|
473
|
-
* @
|
|
487
|
+
* @param priceUpdate - Optional pre-computed price feed update (e.g. from generatePriceFeedsUpdateTxs)
|
|
488
|
+
* @returns Credit accounts sorted by health factor ascending
|
|
489
|
+
*/
|
|
490
|
+
getCreditAccounts(options?: GetCreditAccountsOptions, blockNumber?: bigint, priceUpdate?: UpdatePriceFeedsResult): Promise<Array<CreditAccountData>>;
|
|
491
|
+
/**
|
|
492
|
+
* Returns all credit accounts matching the filter with investor set on each; when options.owner is set, includes KYC CAs for that owner.
|
|
493
|
+
* @param options - Filter options (owner, creditManager, health factor, etc.)
|
|
494
|
+
* @param blockNumber - Optional block number for the read
|
|
495
|
+
* @returns Credit accounts (with investor) sorted by health factor ascending
|
|
496
|
+
*/
|
|
497
|
+
getCreditAccountsWithInvestor(options?: GetCreditAccountsOptions, blockNumber?: bigint): Promise<Array<CreditAccountDataWithInvestor>>;
|
|
498
|
+
/**
|
|
499
|
+
* Loads credit account data for the given addresses using simulateWithPriceUpdates (with price updates applied before the read).
|
|
500
|
+
* @param accounts - Credit account addresses to load
|
|
501
|
+
* @param priceUpdateTxs - Price feed update txs to simulate before the read (e.g. from generatePriceFeedsUpdateTxs)
|
|
502
|
+
* @param blockNumber - Optional block number for the read
|
|
503
|
+
* @returns Array of CreditAccountData in the same order as accounts
|
|
474
504
|
*/
|
|
475
|
-
|
|
505
|
+
loadSpecifiedAccounts(accounts: Address[], priceUpdateTxs: IPriceUpdateTx<{
|
|
506
|
+
priceFeed: `0x${string}`;
|
|
507
|
+
timestamp: number;
|
|
508
|
+
}>[], blockNumber?: bigint): Promise<Array<CreditAccountData>>;
|
|
476
509
|
/**
|
|
477
510
|
* Method to get all claimable rewards for credit account (ex. stkUSDS SKY rewards)
|
|
478
511
|
* Assosiates rewards by adapter + stakedPhantomToken
|
|
@@ -501,9 +534,9 @@ export interface ICreditAccountsService extends Construct {
|
|
|
501
534
|
/**
|
|
502
535
|
* Generates transaction to liquidate credit account
|
|
503
536
|
* @param props - {@link FullyLiquidateProps}
|
|
504
|
-
* @returns
|
|
537
|
+
* @returns Transaction data and optional loss policy data
|
|
505
538
|
*/
|
|
506
|
-
fullyLiquidate(props: FullyLiquidateProps): Promise<
|
|
539
|
+
fullyLiquidate(props: FullyLiquidateProps): Promise<FullyLiquidateResult>;
|
|
507
540
|
/**
|
|
508
541
|
* Closes credit account or closes credit account and keeps it open with zero debt.
|
|
509
542
|
* - Ca is closed in the following order: price update -> close path to swap all tokens into underlying ->
|
|
@@ -623,6 +656,33 @@ export interface ICreditAccountsService extends Construct {
|
|
|
623
656
|
* @returns
|
|
624
657
|
*/
|
|
625
658
|
getPriceUpdatesForFacade(options: PriceUpdatesOptions): Promise<Array<MultiCall>>;
|
|
659
|
+
/**
|
|
660
|
+
* Returns multicall entries to redeem (unwrap) KYC ERC-4626 vault shares into underlying for the given credit manager.
|
|
661
|
+
* Used when withdrawing debt from a KYC market: redeems adapter vault shares so the underlying can be withdrawn.
|
|
662
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
663
|
+
* @param amount - Number of vault shares (adapter tokens) to redeem
|
|
664
|
+
* @param creditManager - Credit manager address
|
|
665
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
666
|
+
*/
|
|
667
|
+
getKYCUnwrapCalls(amount: bigint, creditManager: Address): Promise<Array<MultiCall> | undefined>;
|
|
668
|
+
/**
|
|
669
|
+
* Returns multicall entries to deposit (wrap) underlying into KYC ERC-4626 vault shares for the given credit manager.
|
|
670
|
+
* Used when adding debt on a KYC market: deposits underlying into the adapter vault so shares are minted on the account.
|
|
671
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
672
|
+
* @param amount - Amount of underlying assets to deposit into the vault (in underlying decimals)
|
|
673
|
+
* @param creditManager - Credit manager address
|
|
674
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
675
|
+
*/
|
|
676
|
+
getKYCWrapCalls(amount: bigint, creditManager: Address): Promise<Array<MultiCall> | undefined>;
|
|
677
|
+
/**
|
|
678
|
+
* Returns multicall entries to call redeemDiff on the KYC ERC-4626 adapter for the given credit manager.
|
|
679
|
+
* Redeems the leftover vault shares (e.g. after repaying debt) so the account does not hold excess KYC vault tokens.
|
|
680
|
+
* Only applies when the credit manager's underlying is KYC-gated and has an ERC-4626 adapter configured.
|
|
681
|
+
* @param amount - Leftover vault share amount to redeem (in adapter/vault decimals)
|
|
682
|
+
* @param creditManager - Credit manager address
|
|
683
|
+
* @returns Array of MultiCall to pass to credit facade multicall, or undefined if underlying is not KYC or no adapter is configured
|
|
684
|
+
*/
|
|
685
|
+
getRedeemDiffCalls(amount: bigint, creditManager: Address): Promise<Array<MultiCall> | undefined>;
|
|
626
686
|
/**
|
|
627
687
|
* Withdraws a single collateral from credit account to wallet to and updates quotas;
|
|
628
688
|
* technically can withdraw several tokens at once
|
|
@@ -435,9 +435,16 @@ declare const abi: readonly [{
|
|
|
435
435
|
}];
|
|
436
436
|
type abi = typeof abi;
|
|
437
437
|
export declare class SecuritizeKYCFactory extends BaseContract<abi> {
|
|
438
|
+
private investorCache;
|
|
438
439
|
constructor(options: ConstructOptions, address: Address);
|
|
439
440
|
precomputeWalletAddress(creditManager: Address, investor: Address): Promise<Address>;
|
|
440
441
|
getWallet(creditAccount: Address): Promise<Address>;
|
|
442
|
+
/**
|
|
443
|
+
* Returns the investor address for a credit account.
|
|
444
|
+
* @param creditAccount - Credit account address
|
|
445
|
+
* @param fromCache - If true, use and update an in-memory cache (creditAccount -> investor). On cache miss, loads from contract and stores the result for future calls.
|
|
446
|
+
*/
|
|
447
|
+
getInvestor(creditAccount: Address, fromCache?: boolean): Promise<Address>;
|
|
441
448
|
getDSTokens(): Promise<Address[]>;
|
|
442
449
|
multicall(creditAccount: Address, calls: MultiCall[], tokensToRegister: Address[]): RawTx;
|
|
443
450
|
openCreditAccount(creditManager: Address, calls: MultiCall[], tokensToRegister: Address[]): RawTx;
|
|
@@ -103,6 +103,7 @@ export declare class CreditAccountData_Legacy {
|
|
|
103
103
|
readonly underlying: Address;
|
|
104
104
|
readonly expirationDate: number;
|
|
105
105
|
readonly version: number;
|
|
106
|
+
readonly investor: Address;
|
|
106
107
|
readonly enabledTokensMask: bigint;
|
|
107
108
|
readonly healthFactor: number;
|
|
108
109
|
readonly baseBorrowRateWithoutFee: number;
|