@gearbox-protocol/sdk 17.2.1 → 17.3.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/dev/index.js +1 -0
- package/dist/cjs/dev/isRateLimitError.js +20 -5
- package/dist/cjs/dev/resilientTransport.js +31 -8
- package/dist/cjs/onchain/accounts/intents/leverage-band.js +1 -1
- package/dist/cjs/onchain/accounts/intents/maxBorrow.js +15 -11
- package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +5 -2
- package/dist/cjs/onchain/chain/chains.js +1 -2
- package/dist/cjs/onchain/index.js +2 -0
- package/dist/cjs/onchain/market/MarketSuite.js +11 -4
- package/dist/cjs/onchain/market/credit/CreditSuite.js +25 -138
- package/dist/cjs/onchain/market/credit/CreditSuiteStrategy.js +179 -0
- package/dist/cjs/onchain/market/credit/index.js +2 -0
- package/dist/cjs/onchain/market/index.js +2 -0
- package/dist/cjs/onchain/market/pool/PoolQuotaKeeperV310Contract.js +4 -1
- package/dist/cjs/onchain/opportunities/OpportunitiesService.js +7 -9
- package/dist/cjs/sdk/prepare/PrepareApi.js +1 -1
- package/dist/esm/dev/index.js +2 -2
- package/dist/esm/dev/isRateLimitError.js +20 -5
- package/dist/esm/dev/resilientTransport.js +31 -9
- package/dist/esm/onchain/accounts/intents/leverage-band.js +1 -1
- package/dist/esm/onchain/accounts/intents/maxBorrow.js +15 -11
- package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +5 -2
- package/dist/esm/onchain/chain/chains.js +1 -2
- package/dist/esm/onchain/index.js +2 -1
- package/dist/esm/onchain/market/MarketSuite.js +11 -4
- package/dist/esm/onchain/market/credit/CreditSuite.js +27 -140
- package/dist/esm/onchain/market/credit/CreditSuiteStrategy.js +178 -0
- package/dist/esm/onchain/market/credit/index.js +2 -1
- package/dist/esm/onchain/market/index.js +2 -1
- package/dist/esm/onchain/market/pool/PoolQuotaKeeperV310Contract.js +4 -1
- package/dist/esm/onchain/opportunities/OpportunitiesService.js +7 -9
- package/dist/esm/sdk/prepare/PrepareApi.js +1 -1
- package/dist/types/dev/index.d.ts +2 -2
- package/dist/types/dev/isRateLimitError.d.ts +2 -1
- package/dist/types/dev/resilientTransport.d.ts +18 -2
- package/dist/types/model/errors/operation-errors.d.ts +6 -1
- package/dist/types/onchain/accounts/intents/maxBorrow.d.ts +12 -10
- package/dist/types/onchain/index.d.ts +2 -1
- package/dist/types/onchain/market/MarketSuite.d.ts +6 -0
- package/dist/types/onchain/market/credit/CreditSuite.d.ts +18 -52
- package/dist/types/onchain/market/credit/CreditSuiteStrategy.d.ts +78 -0
- package/dist/types/onchain/market/credit/index.d.ts +2 -1
- package/dist/types/onchain/market/credit/types.d.ts +3 -1
- package/dist/types/onchain/market/index.d.ts +2 -1
- package/dist/types/onchain/market/pool/PoolQuotaKeeperV310Contract.d.ts +2 -0
- package/package.json +1 -1
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { AddressMap } from "../../utils/AddressMap.js";
|
|
2
|
-
import { getAccountTargetCollateral, getLegacyStrategyTarget
|
|
2
|
+
import { getAccountTargetCollateral, getLegacyStrategyTarget } from "../../chain/chains.js";
|
|
3
3
|
import "../../constants/addresses.js";
|
|
4
4
|
import { PERCENTAGE_FACTOR, RAY } from "../../constants/math.js";
|
|
5
5
|
import "../../constants/index.js";
|
|
6
6
|
import "../../utils/index.js";
|
|
7
7
|
import { SDKConstruct } from "../../base/SDKConstruct.js";
|
|
8
8
|
import "../../base/index.js";
|
|
9
|
-
import {
|
|
9
|
+
import { minSeizedAmount, optimalHFForPartialLiquidation, optimalRepaidAmount } from "../math.js";
|
|
10
10
|
import { createDegenNFT } from "../rwa/createDegenNFT.js";
|
|
11
11
|
import { strategyName } from "../strategyName.js";
|
|
12
|
+
import { CreditSuiteStrategy } from "./CreditSuiteStrategy.js";
|
|
12
13
|
import { dominantCollateral, isStrategyCollateral, pickStrategyTargetCollateral } from "./collateralUtils.js";
|
|
13
14
|
import createCreditConfigurator from "./createCreditConfigurator.js";
|
|
14
15
|
import createCreditFacade from "./createCreditFacade.js";
|
|
@@ -16,13 +17,6 @@ import createCreditManager from "./createCreditManager.js";
|
|
|
16
17
|
import { isAddressEqual } from "viem";
|
|
17
18
|
//#region src/onchain/market/credit/CreditSuite.ts
|
|
18
19
|
/**
|
|
19
|
-
* Amount of underlying seeded into each pool at market creation to protect
|
|
20
|
-
* from inflation attacks, in raw token units. A suite whose
|
|
21
|
-
* {@link CreditSuite.maxBorrowAmount} is at or below this is treated as
|
|
22
|
-
* having nothing left to lend.
|
|
23
|
-
**/
|
|
24
|
-
const MIN_STRATEGY_BORROW_AMOUNT = 100000n;
|
|
25
|
-
/**
|
|
26
20
|
* SDK aggregate for one credit-manager branch inside a market.
|
|
27
21
|
*
|
|
28
22
|
* @remarks
|
|
@@ -129,31 +123,6 @@ var CreditSuite = class extends SDKConstruct {
|
|
|
129
123
|
return this.#degenNFT;
|
|
130
124
|
}
|
|
131
125
|
/**
|
|
132
|
-
* The KYC gate of this suite's strategy; `null` when there is none.
|
|
133
|
-
* Wallet-independent.
|
|
134
|
-
*/
|
|
135
|
-
async kycRequirement(targetCollateral) {
|
|
136
|
-
const nft = await this.degenNFT();
|
|
137
|
-
if (!nft) return null;
|
|
138
|
-
const tokens = await nft.getTokens();
|
|
139
|
-
const token = tokens.find((t) => isAddressEqual(t, targetCollateral)) ?? tokens[0];
|
|
140
|
-
return {
|
|
141
|
-
protocol: nft.protocol,
|
|
142
|
-
token: token ? this.tokensMeta.getToken(token) : void 0,
|
|
143
|
-
registrationLink: nft.registrationLink
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Whether `wallet` may open this suite's strategy today; `true` when there
|
|
148
|
-
* is no KYC gate.
|
|
149
|
-
*/
|
|
150
|
-
async isEligibleForStrategy(wallet, targetCollateral) {
|
|
151
|
-
const nft = await this.degenNFT();
|
|
152
|
-
if (!nft) return true;
|
|
153
|
-
const requirements = await nft.getOpenAccountRequirements(wallet, { tokenOutAddress: targetCollateral });
|
|
154
|
-
return nft.isRegistered(requirements);
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
126
|
* Builds a transaction that executes a multicall on one of this suite's
|
|
158
127
|
* credit accounts.
|
|
159
128
|
*
|
|
@@ -246,13 +215,14 @@ var CreditSuite = class extends SDKConstruct {
|
|
|
246
215
|
* row all spread it, so the five fields are filled in one place and cannot
|
|
247
216
|
* drift apart between the halves of the SDK.
|
|
248
217
|
*
|
|
249
|
-
* The curator comes from the same getter
|
|
218
|
+
* The curator comes from the same getter
|
|
219
|
+
* {@link CreditSuiteStrategy.opportunity} reads, so
|
|
250
220
|
* a result and the opportunity beside it name one entity.
|
|
251
221
|
*/
|
|
252
222
|
creditOperationMarket() {
|
|
253
223
|
return {
|
|
254
224
|
creditManager: this.creditManager.address,
|
|
255
|
-
name: this.
|
|
225
|
+
name: this.strategy?.name ?? this.underlyingToken.symbol,
|
|
256
226
|
underlyingToken: this.underlyingToken,
|
|
257
227
|
curator: this.market.curator,
|
|
258
228
|
liquidationDiscount: this.totalLiquidationDiscount()
|
|
@@ -281,15 +251,14 @@ var CreditSuite = class extends SDKConstruct {
|
|
|
281
251
|
return this.forbiddenTokens.some((f) => isAddressEqual(f, token));
|
|
282
252
|
}
|
|
283
253
|
/**
|
|
284
|
-
* Largest debt
|
|
285
|
-
* and which limit set that number.
|
|
254
|
+
* Largest debt this credit manager allows to borrow, and which limit set that number.
|
|
286
255
|
*
|
|
287
256
|
* Minimum of:
|
|
288
257
|
* - the pool's available liquidity,
|
|
289
258
|
* - this manager's remaining debt allowance, and
|
|
290
259
|
* - the facade's per-account `maxDebt`.
|
|
291
|
-
*
|
|
292
|
-
*
|
|
260
|
+
*
|
|
261
|
+
* If the credit manager allows no debt at all, the answer is `0`.
|
|
293
262
|
*/
|
|
294
263
|
maxBorrowAmount() {
|
|
295
264
|
const { pool } = this.market.pool;
|
|
@@ -319,32 +288,25 @@ var CreditSuite = class extends SDKConstruct {
|
|
|
319
288
|
};
|
|
320
289
|
}
|
|
321
290
|
/**
|
|
322
|
-
*
|
|
323
|
-
*
|
|
291
|
+
* This suite's leveraged strategy, or `undefined` when no target collateral
|
|
292
|
+
* can be resolved.
|
|
324
293
|
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
* {@link isStrategyCollateral} accepts with quota required;
|
|
332
|
-
* 3. the biggest-index collateral that {@link isStrategyCollateral} accepts
|
|
333
|
-
* without quota.
|
|
334
|
-
*/
|
|
335
|
-
get strategyTargetCollateral() {
|
|
294
|
+
* The strategy exists whether or not it is offered today, because its
|
|
295
|
+
* target also names existing positions; see
|
|
296
|
+
* {@link CreditSuiteStrategy.isListed} for whether it is listed as an
|
|
297
|
+
* opportunity.
|
|
298
|
+
*/
|
|
299
|
+
get strategy() {
|
|
336
300
|
const legacy = getLegacyStrategyTarget(this.creditManager.address, this.chainId);
|
|
337
|
-
|
|
338
|
-
return
|
|
301
|
+
const target = legacy && this.creditManager.liquidationThresholds.has(legacy) ? legacy : pickStrategyTargetCollateral(this.creditManager.collateralTokens.map((token) => this.#strategyCollateralProps(token)));
|
|
302
|
+
return target ? new CreditSuiteStrategy(this, target) : void 0;
|
|
339
303
|
}
|
|
340
304
|
/**
|
|
341
|
-
*
|
|
342
|
-
*
|
|
305
|
+
* Whether `token` can be this suite's strategy target; see
|
|
306
|
+
* {@link isStrategyCollateral}.
|
|
343
307
|
*/
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if (!collateral) return;
|
|
347
|
-
return strategyName(this.tokensMeta.mustGetToken(collateral), this.underlyingToken);
|
|
308
|
+
isStrategyCollateral(token, requireQuota = false) {
|
|
309
|
+
return isStrategyCollateral(this.#strategyCollateralProps(token), requireQuota);
|
|
348
310
|
}
|
|
349
311
|
/**
|
|
350
312
|
* Collateral token an existing credit account in this suite is a strategy
|
|
@@ -352,12 +314,13 @@ var CreditSuite = class extends SDKConstruct {
|
|
|
352
314
|
*
|
|
353
315
|
* Resolution, in order:
|
|
354
316
|
* 1. a hardcoded per-account override, when present;
|
|
355
|
-
* 2. {@link
|
|
317
|
+
* 2. the target of {@link strategy};
|
|
356
318
|
* 3. `null` when neither can be resolved.
|
|
357
319
|
*/
|
|
358
320
|
accountTargetCollateral(creditAccount) {
|
|
359
|
-
const
|
|
360
|
-
|
|
321
|
+
const override = getAccountTargetCollateral(creditAccount, this.chainId);
|
|
322
|
+
if (override) return this.tokensMeta.mustGetToken(override);
|
|
323
|
+
return this.strategy?.token ?? null;
|
|
361
324
|
}
|
|
362
325
|
/**
|
|
363
326
|
* Display name of an existing credit account in this suite, e.g.
|
|
@@ -371,61 +334,6 @@ var CreditSuite = class extends SDKConstruct {
|
|
|
371
334
|
return target ? strategyName(target, this.underlyingToken) : this.underlyingToken.symbol;
|
|
372
335
|
}
|
|
373
336
|
/**
|
|
374
|
-
* Describes this suite's leveraged strategy as the shared read model does,
|
|
375
|
-
* or `undefined` when credit suite does not offer a strategy opportunity.
|
|
376
|
-
*/
|
|
377
|
-
strategyOpportunity() {
|
|
378
|
-
const maxBorrowAmount = this.maxBorrowAmount().amount.value;
|
|
379
|
-
if (maxBorrowAmount <= MIN_STRATEGY_BORROW_AMOUNT) return;
|
|
380
|
-
const collateral = this.strategyTargetCollateral;
|
|
381
|
-
if (!collateral) return;
|
|
382
|
-
if (!isStrategyCollateral(this.#strategyCollateralProps(collateral), true)) return;
|
|
383
|
-
const { market, creditManager: cm } = this;
|
|
384
|
-
const { pool } = market.pool;
|
|
385
|
-
const oracle = market.priceOracle;
|
|
386
|
-
const liquidationThreshold = cm.liquidationThresholds.mustGet(collateral);
|
|
387
|
-
const maxLeverage = cm.maxLeverage(collateral);
|
|
388
|
-
const debtParams = pool.creditManagerDebtParams.get(cm.address);
|
|
389
|
-
const borrowed = debtParams?.borrowed ?? 0n;
|
|
390
|
-
return {
|
|
391
|
-
kind: "strategy",
|
|
392
|
-
chainId: this.chainId,
|
|
393
|
-
creditManager: cm.address,
|
|
394
|
-
targetCollateral: this.tokensMeta.mustGetToken(collateral),
|
|
395
|
-
name: this.strategyName ?? this.underlyingToken.symbol,
|
|
396
|
-
curator: market.curator,
|
|
397
|
-
underlyingToken: this.underlyingToken,
|
|
398
|
-
totalBorrowed: oracle.toAmount(pool.underlying, borrowed),
|
|
399
|
-
allowedDepositTokens: this.allowedDepositTokens(collateral),
|
|
400
|
-
paused: this.isPaused,
|
|
401
|
-
rwa: market.rwa,
|
|
402
|
-
sunset: market.sunset || isSunsetStrategy(cm.address, this.sdk.networkType),
|
|
403
|
-
liquidationThreshold,
|
|
404
|
-
liquidationPremium: cm.liquidationPremium,
|
|
405
|
-
liquidationFee: cm.feeLiquidation,
|
|
406
|
-
expirationDate: this.expirationDate,
|
|
407
|
-
borrowApy: calcBorrowApy(pool.baseInterestRate, cm.feeInterest),
|
|
408
|
-
quotaRate: calcQuotaRate(market.pool.pqk.quotaRate(collateral), cm.feeInterest),
|
|
409
|
-
availableLiquidity: oracle.toAmount(pool.underlying, pool.availableLiquidity),
|
|
410
|
-
minDebt: oracle.toAmount(pool.underlying, this.creditFacade.minDebt),
|
|
411
|
-
totalDebtLimit: oracle.toAmount(pool.underlying, debtParams?.limit ?? 0n),
|
|
412
|
-
maxBorrowAmount: oracle.toAmount(pool.underlying, maxBorrowAmount),
|
|
413
|
-
maxLeverage
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* {@link strategyOpportunity} plus the data only its detail screen needs.
|
|
418
|
-
*/
|
|
419
|
-
strategyOpportunityDetail() {
|
|
420
|
-
const opportunity = this.strategyOpportunity();
|
|
421
|
-
if (!opportunity) return;
|
|
422
|
-
return {
|
|
423
|
-
...opportunity,
|
|
424
|
-
rateCurve: this.market.pool.rateCurve,
|
|
425
|
-
priceFeeds: this.market.priceFeedSummary(opportunity.targetCollateral.address)
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
337
|
* Everything a partial liquidation of credit account needs, with any parameter the
|
|
430
338
|
* caller pinned down taken as given and the rest derived from current state.
|
|
431
339
|
*
|
|
@@ -465,27 +373,6 @@ var CreditSuite = class extends SDKConstruct {
|
|
|
465
373
|
return collateral;
|
|
466
374
|
}
|
|
467
375
|
/**
|
|
468
|
-
* Tokens a user can transfer from their wallet when opening an account in
|
|
469
|
-
* this suite:
|
|
470
|
-
*
|
|
471
|
-
* 1. unwrapped underlying (USDC, never dcUSDC)
|
|
472
|
-
* 2. target collateral
|
|
473
|
-
* 3. remaining CM collaterals in manager order, excluding phantom tokens
|
|
474
|
-
* and tokens without price
|
|
475
|
-
*/
|
|
476
|
-
allowedDepositTokens(targetCollateral) {
|
|
477
|
-
const unwrappedUnderlying = this.market.unwrappedUnderlying;
|
|
478
|
-
const { mainPrices, reservePrices } = this.market.priceOracle;
|
|
479
|
-
return [
|
|
480
|
-
unwrappedUnderlying,
|
|
481
|
-
targetCollateral,
|
|
482
|
-
...this.creditManager.collateralTokens.filter((token) => {
|
|
483
|
-
const contractType = this.tokensMeta.mustGet(token).contractType;
|
|
484
|
-
return !this.market.isUnderlyingLike(token) && !isAddressEqual(token, targetCollateral) && !contractType?.startsWith("PHANTOM_TOKEN::") && (!!mainPrices.get(token)?.price || !!reservePrices.get(token)?.price);
|
|
485
|
-
})
|
|
486
|
-
].map((token) => this.tokensMeta.mustGetToken(token));
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
376
|
* Shared inputs of {@link isStrategyCollateral} for one of this suite's
|
|
490
377
|
* collateral tokens.
|
|
491
378
|
*/
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { isSunsetStrategy } from "../../chain/chains.js";
|
|
2
|
+
import { calcBorrowApy, calcQuotaRate } from "../math.js";
|
|
3
|
+
import { strategyName } from "../strategyName.js";
|
|
4
|
+
import { isAddressEqual } from "viem";
|
|
5
|
+
//#region src/onchain/market/credit/CreditSuiteStrategy.ts
|
|
6
|
+
/**
|
|
7
|
+
* Amount of underlying seeded into each pool at market creation to protect
|
|
8
|
+
* from inflation attacks, in raw token units. A strategy whose
|
|
9
|
+
* {@link CreditSuiteStrategy.maxBorrowAmount} is at or below this is treated
|
|
10
|
+
* as having nothing left to lend.
|
|
11
|
+
**/
|
|
12
|
+
const MIN_STRATEGY_BORROW_AMOUNT = 100000n;
|
|
13
|
+
/**
|
|
14
|
+
* The leveraged strategy a credit suite runs: one target collateral bought
|
|
15
|
+
* with underlying borrowed from the pool.
|
|
16
|
+
*
|
|
17
|
+
* A view over live suite state, see {@link CreditSuite.strategy}.
|
|
18
|
+
*/
|
|
19
|
+
var CreditSuiteStrategy = class {
|
|
20
|
+
/**
|
|
21
|
+
* Credit suite this strategy borrows through.
|
|
22
|
+
*/
|
|
23
|
+
suite;
|
|
24
|
+
/**
|
|
25
|
+
* Collateral token a position in this strategy is built to hold.
|
|
26
|
+
*/
|
|
27
|
+
targetCollateral;
|
|
28
|
+
constructor(suite, targetCollateral) {
|
|
29
|
+
this.suite = suite;
|
|
30
|
+
this.targetCollateral = targetCollateral;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* {@link targetCollateral} as the shared read model describes it.
|
|
34
|
+
*/
|
|
35
|
+
get token() {
|
|
36
|
+
return this.suite.sdk.tokensMeta.mustGetToken(this.targetCollateral);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Display name of this strategy, e.g. `"wstETH / WETH"`.
|
|
40
|
+
*/
|
|
41
|
+
get name() {
|
|
42
|
+
return strategyName(this.token, this.suite.underlyingToken);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Tokens a user can transfer from their wallet when opening a position in
|
|
46
|
+
* this strategy:
|
|
47
|
+
*
|
|
48
|
+
* 1. unwrapped underlying (USDC, never dcUSDC)
|
|
49
|
+
* 2. target collateral
|
|
50
|
+
* 3. remaining CM collaterals in manager order, excluding phantom tokens
|
|
51
|
+
* and tokens without price
|
|
52
|
+
*/
|
|
53
|
+
get allowedDepositTokens() {
|
|
54
|
+
const { market, creditManager, sdk } = this.suite;
|
|
55
|
+
const { tokensMeta } = sdk;
|
|
56
|
+
const { targetCollateral } = this;
|
|
57
|
+
const { mainPrices, reservePrices } = market.priceOracle;
|
|
58
|
+
const rest = creditManager.collateralTokens.filter((token) => {
|
|
59
|
+
const contractType = tokensMeta.mustGet(token).contractType;
|
|
60
|
+
return !market.isUnderlyingLike(token) && !isAddressEqual(token, targetCollateral) && !contractType?.startsWith("PHANTOM_TOKEN::") && (!!mainPrices.get(token)?.price || !!reservePrices.get(token)?.price);
|
|
61
|
+
});
|
|
62
|
+
return [
|
|
63
|
+
market.unwrappedUnderlying,
|
|
64
|
+
targetCollateral,
|
|
65
|
+
...rest
|
|
66
|
+
].map((token) => tokensMeta.mustGetToken(token));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Largest debt one new position can take right now, and which limit set
|
|
70
|
+
* that number.
|
|
71
|
+
*
|
|
72
|
+
* `amount` is `0` whenever no position can be opened right now,
|
|
73
|
+
* and `limit` explains why.
|
|
74
|
+
*
|
|
75
|
+
*/
|
|
76
|
+
maxBorrowAmount() {
|
|
77
|
+
const { suite } = this;
|
|
78
|
+
const lends = suite.maxBorrowAmount();
|
|
79
|
+
if (lends.limit === "debtPerBlockLimit") return lends;
|
|
80
|
+
let value = lends.amount.value;
|
|
81
|
+
let limit = lends.limit;
|
|
82
|
+
const quota = suite.market.pool.pqk.quotaAvailable(this.targetCollateral);
|
|
83
|
+
if (quota < value) {
|
|
84
|
+
value = quota;
|
|
85
|
+
limit = "quotaAvailable";
|
|
86
|
+
}
|
|
87
|
+
if (value < suite.creditFacade.minDebt) return {
|
|
88
|
+
amount: suite.market.toUnderlyingAmount(0n),
|
|
89
|
+
limit: "minDebt"
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
amount: suite.market.toUnderlyingAmount(value),
|
|
93
|
+
limit
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Whether this strategy is offered as an opportunity right now: it lends
|
|
98
|
+
* more than the pool's seed amount, and its target can be opened today.
|
|
99
|
+
*/
|
|
100
|
+
get isListed() {
|
|
101
|
+
return this.maxBorrowAmount().amount.value > MIN_STRATEGY_BORROW_AMOUNT && this.suite.isStrategyCollateral(this.targetCollateral, true);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Describes this strategy as the shared read model does. Whether it is
|
|
105
|
+
* listed at all is {@link isListed}.
|
|
106
|
+
*/
|
|
107
|
+
opportunity() {
|
|
108
|
+
const { suite, targetCollateral } = this;
|
|
109
|
+
const { market, creditManager: cm } = suite;
|
|
110
|
+
const { pool } = market.pool;
|
|
111
|
+
const oracle = market.priceOracle;
|
|
112
|
+
const debtParams = pool.creditManagerDebtParams.get(cm.address);
|
|
113
|
+
const borrowed = debtParams?.borrowed ?? 0n;
|
|
114
|
+
return {
|
|
115
|
+
kind: "strategy",
|
|
116
|
+
chainId: suite.chainId,
|
|
117
|
+
creditManager: cm.address,
|
|
118
|
+
targetCollateral: this.token,
|
|
119
|
+
name: this.name,
|
|
120
|
+
curator: market.curator,
|
|
121
|
+
underlyingToken: suite.underlyingToken,
|
|
122
|
+
totalBorrowed: oracle.toAmount(pool.underlying, borrowed),
|
|
123
|
+
allowedDepositTokens: this.allowedDepositTokens,
|
|
124
|
+
paused: suite.isPaused,
|
|
125
|
+
rwa: market.rwa,
|
|
126
|
+
sunset: market.sunset || isSunsetStrategy(cm.address, suite.sdk.networkType),
|
|
127
|
+
liquidationThreshold: cm.liquidationThresholds.mustGet(targetCollateral),
|
|
128
|
+
liquidationPremium: cm.liquidationPremium,
|
|
129
|
+
liquidationFee: cm.feeLiquidation,
|
|
130
|
+
expirationDate: suite.expirationDate,
|
|
131
|
+
borrowApy: calcBorrowApy(pool.baseInterestRate, cm.feeInterest),
|
|
132
|
+
quotaRate: calcQuotaRate(market.pool.pqk.quotaRate(targetCollateral), cm.feeInterest),
|
|
133
|
+
availableLiquidity: oracle.toAmount(pool.underlying, pool.availableLiquidity),
|
|
134
|
+
minDebt: oracle.toAmount(pool.underlying, suite.creditFacade.minDebt),
|
|
135
|
+
totalDebtLimit: oracle.toAmount(pool.underlying, debtParams?.limit ?? 0n),
|
|
136
|
+
maxBorrowAmount: oracle.toAmount(pool.underlying, this.maxBorrowAmount().amount.value),
|
|
137
|
+
maxLeverage: cm.maxLeverage(targetCollateral)
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* {@link opportunity} plus the data only its detail screen needs.
|
|
142
|
+
*/
|
|
143
|
+
opportunityDetail() {
|
|
144
|
+
const { market } = this.suite;
|
|
145
|
+
return {
|
|
146
|
+
...this.opportunity(),
|
|
147
|
+
rateCurve: market.pool.rateCurve,
|
|
148
|
+
priceFeeds: market.priceFeedSummary(this.targetCollateral)
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The KYC gate of this strategy; `null` when there is none.
|
|
153
|
+
* Wallet-independent.
|
|
154
|
+
*/
|
|
155
|
+
async kycRequirement() {
|
|
156
|
+
const nft = await this.suite.degenNFT();
|
|
157
|
+
if (!nft) return null;
|
|
158
|
+
const tokens = await nft.getTokens();
|
|
159
|
+
const token = tokens.find((t) => isAddressEqual(t, this.targetCollateral)) ?? tokens[0];
|
|
160
|
+
return {
|
|
161
|
+
protocol: nft.protocol,
|
|
162
|
+
token: token ? this.suite.sdk.tokensMeta.getToken(token) : void 0,
|
|
163
|
+
registrationLink: nft.registrationLink
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Whether `wallet` may open this strategy today; `true` when there is no
|
|
168
|
+
* KYC gate.
|
|
169
|
+
*/
|
|
170
|
+
async isEligible(wallet) {
|
|
171
|
+
const nft = await this.suite.degenNFT();
|
|
172
|
+
if (!nft) return true;
|
|
173
|
+
const requirements = await nft.getOpenAccountRequirements(wallet, { tokenOutAddress: this.targetCollateral });
|
|
174
|
+
return nft.isRegistered(requirements);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
//#endregion
|
|
178
|
+
export { CreditSuiteStrategy };
|
|
@@ -2,8 +2,9 @@ import { CreditConfiguratorV310Contract } from "./CreditConfiguratorV310Contract
|
|
|
2
2
|
import { CreditFacadeV310BaseContract, creditFacadeV310Abi as abi } from "./CreditFacadeV310BaseContract.js";
|
|
3
3
|
import { CreditFacadeV310Contract } from "./CreditFacadeV310Contract.js";
|
|
4
4
|
import { CreditManagerV310Contract } from "./CreditManagerV310Contract.js";
|
|
5
|
+
import { CreditSuiteStrategy } from "./CreditSuiteStrategy.js";
|
|
5
6
|
import { dominantCollateral, isStrategyCollateral, pickStrategyTargetCollateral } from "./collateralUtils.js";
|
|
6
7
|
import { CreditSuite } from "./CreditSuite.js";
|
|
7
8
|
import { expectedBalanceDeltas } from "./expectedBalanceDeltas.js";
|
|
8
9
|
import "./types.js";
|
|
9
|
-
export { CreditConfiguratorV310Contract, CreditFacadeV310BaseContract, CreditFacadeV310Contract, CreditManagerV310Contract, CreditSuite, abi as creditFacadeV310Abi, dominantCollateral, expectedBalanceDeltas, isStrategyCollateral, pickStrategyTargetCollateral };
|
|
10
|
+
export { CreditConfiguratorV310Contract, CreditFacadeV310BaseContract, CreditFacadeV310Contract, CreditManagerV310Contract, CreditSuite, CreditSuiteStrategy, abi as creditFacadeV310Abi, dominantCollateral, expectedBalanceDeltas, isStrategyCollateral, pickStrategyTargetCollateral };
|
|
@@ -93,6 +93,7 @@ import { DEGEN_NFT_MIDAS, PHANTOM_TOKEN_MIDAS_REDEMPTION, RWA_LIQUIDATOR_MIDAS }
|
|
|
93
93
|
import { MidasDegenNFT } from "./rwa/midas/MidasDegenNFT.js";
|
|
94
94
|
import { DEGEN_NFT_SECURITIZE, PHANTOM_TOKEN_SECURITIZE_REDEMPTION, RWA_LIQUIDATOR_SECURITIZE } from "./rwa/securitize/constants.js";
|
|
95
95
|
import { strategyName } from "./strategyName.js";
|
|
96
|
+
import { CreditSuiteStrategy } from "./credit/CreditSuiteStrategy.js";
|
|
96
97
|
import { dominantCollateral, isStrategyCollateral, pickStrategyTargetCollateral } from "./credit/collateralUtils.js";
|
|
97
98
|
import { CreditSuite } from "./credit/CreditSuite.js";
|
|
98
99
|
import { expectedBalanceDeltas } from "./credit/expectedBalanceDeltas.js";
|
|
@@ -148,4 +149,4 @@ import { RWARegistry, RWA_COMPRESSOR_ADDRESS } from "./rwa/RWARegistry.js";
|
|
|
148
149
|
import { isRWAFactory } from "./rwa/types.js";
|
|
149
150
|
import "./rwa/index.js";
|
|
150
151
|
import "./types.js";
|
|
151
|
-
export { AbstractAdapterContract, AbstractLPPriceFeedContract, AbstractPriceFeedContract, AccountMigratorAdapterContract, AdapterType, BalancerStablePriceFeedContract, BalancerV3PoolStatus, BalancerV3RouterAdapterContract, BalancerV3WrapperAdapterContract, BalancerWeightedPriceFeedContract, BoundedPriceFeedContract, CamelotV3AdapterContract, CompositePriceFeedContract, ConstantPriceFeedContract, ConvexV1BaseRewardPoolAdapterContract, ConvexV1BoosterAdapterContract, CreditConfiguratorV310Contract, CreditFacadeV310BaseContract, CreditFacadeV310Contract, CreditManagerV310Contract, CreditSuite, Curve2AssetsAdapterContract, Curve3AssetsAdapterContract, Curve4AssetsAdapterContract, CurveCryptoPriceFeedContract, CurveStablePriceFeedContract, CurveUSDPriceFeedContract, CurveV1AdapterStETHContract, CurveV1StableNGAdapterContract, DEFAULT_QUOTA_BUFFER_BPS, DEGEN_NFT_MIDAS, DEGEN_NFT_SECURITIZE, DaiUsdsAdapterContract, ERC4626AdapterContract, ERC4626ReferralAdapterContract, Erc4626PriceFeedContract, ExternalPriceFeedContract, FluidDexAdapterContract, GaugeContract, IERC20ZapperContract, IETHZapperContract, InfinifiGatewayAdapterContract, InfinifiUnwindingGatewayAdapterContract, KelpLRTDepositPoolAdapterContract, KelpLRTWithdrawalManagerAdapterContract, LidoV1AdapterContract, LinearInterestRateModelContract, MAX_LEVERAGE_BUFFER_BPS, MarketRegister, MarketSuite, MellowClaimerAdapterContract, MellowDVVAdapterContract, MellowERC4626VaultAdapterContract, MellowLRTPriceFeedContract, MellowWrapperAdapterContract, MidasDegenNFT, MidasGatewayAdapterContract, MidasIssuanceVaultAdapterContract, MidasLiquidatorContract, MidasRedemptionVaultAdapterContract, PARTIAL_LIQUIDATION_BUFFER_BPS, PHANTOM_TOKEN_MIDAS_REDEMPTION, PHANTOM_TOKEN_SECURITIZE_REDEMPTION, PartialPriceFeedInitError, PendlePairStatus, PendleRouterAdapterContract, PendleTWAPPTPriceFeed, PendleTokenType, PoolSuite, PoolV310Contract, PriceFeedRef, PriceFeedRegistry, PriceOracleV310Contract, PriceUpdatesCache, PythPriceFeed, RWARegistry, RWA_COMPRESSOR_ADDRESS, RWA_LIQUIDATOR_MIDAS, RWA_LIQUIDATOR_SECURITIZE, RedstonePriceFeedContract, SecuritizeDegenNFT, SecuritizeLiquidatorContract, SecuritizeOnRampAdapterContract, SecuritizeRWAFactory, SecuritizeRedemptionGatewayAdapterContract, StakingRewardsAdapterContract, TraderJoePoolVersion, TraderJoeRouterAdapterContract, UniswapV2AdapterContract, UniswapV3AdapterContract, UniswapV4AdapterContract, UpdatablePriceFeedRegistry, UpshiftVaultAdapterContract, VelodromeV2RouterAdapterContract, WstETHPriceFeedContract, WstETHV1AdapterContract, YearnPriceFeedContract, ZapperContract, ZeroPriceFeedContract, adapterActionAbi, adapterActionSelectors, adapterActionSignatures, adapterConstructorAbi, allTransfersAsTokenAmounts, bpsToRay, calcBorrowApy, calcEffectiveBorrowApy, calcMaxLeverage, calcNetStrategyApy, calcPositionLeverage, calcQuotaRate, calcUtilization, calcUtilizationRaw, classifyCurveOperation, collateralPriceInUnderlying, createAdapter, createPriceOracle, createZapper, abi as creditFacadeV310Abi, curveAddLiquidityFromTransfers, curveRemoveLiquidityFromTransfers, dominantCollateral, erc4626ReferralAdapterAbi, expectedBalanceDeltas, fnSigToName, getAdapterActionAbi, getAdapterDeployParamsAbi, getAdapterType, getRawPriceUpdates, hasAdapterDeployParamsAbi, healthFactorBps, iBalancerV3RouterAbi, iBalancerV3RouterAdapterAbi, iBalancerV3WrapperAbi, iBalancerV3WrapperAdapterAbi, iBaseOnRampAbi, iBaseRewardPoolAbi, iBoosterAbi, iCamelotV3AdapterAbi, iCamelotV3RouterAbi, iConvexV1BaseRewardPoolAdapterAbi, iConvexV1BoosterAdapterAbi, iCurvePoolAbi, iCurvePoolStableNGAbi, iCurvePool_2Abi, iCurvePool_3Abi, iCurvePool_4Abi, iCurveV1StableNgAdapterAbi, iCurveV1_2AssetsAdapterAbi, iCurveV1_3AssetsAdapterAbi, iCurveV1_4AssetsAdapterAbi, iDaiUsdsAbi, iDaiUsdsAdapterAbi, iERC4626Abi, iERC4626ReferralAbi, iFluidDexAbi, iFluidDexAdapterAbi, iInfinifiGatewayAbi, iInfinifiGatewayAdapterAbi, iInfinifiUnwindingGatewayAbi, iInfinifiUnwindingGatewayAdapterAbi, iKelpLRTDepositPoolGatewayAbi, iKelpLRTWithdrawalManagerGatewayAbi, iKelpLrtDepositPoolAdapterAbi, iKelpLrtDepositPoolGatewayAbi, iKelpLrtWithdrawalManagerAdapterAbi, iKelpLrtWithdrawalManagerGatewayAbi, iLidoV1AdapterAbi, iMellow4626VaultAdapterAbi, iMellowClaimerAbi, iMellowClaimerAdapterAbi, iMellowWrapperAbi, iMellowWrapperAdapterAbi, iMidasGatewayAdapterV311Abi, iMidasGatewayV311Abi, iMidasIssuanceVaultAdapterV310Abi, iMidasIssuanceVaultV310Abi, iMidasRedemptionVaultAdapterV310Abi, iMidasRedemptionVaultGatewayV310Abi, iPendleRouterAbi, iPendleRouterAdapterAbi, iSecuritizeOnRampAbi, iSecuritizeOnRampAdapterV310Abi, iSecuritizeRedemptionGatewayAdapterV311Abi, iSecuritizeRedemptionGatewayV311Abi, iStakingRewardsAbi, iStakingRewardsAdapterAbi, iTraderJoeRouterAbi, iTraderJoeRouterAdapterAbi, iUniswapV2AdapterAbi, iUniswapV2Router02Abi, iUniswapV3Abi, iUniswapV3AdapterAbi, iUniswapV4AdapterAbi, iUniswapV4GatewayAbi, iUpshiftVaultAdapterAbi, iUpshiftVaultGatewayAbi, iVelodromeV2RouterAbi, iVelodromeV2RouterAdapterAbi, isLPPriceFeed, isRWAFactory, isStrategyCollateral, isUpdatablePriceFeed, iwstETHAbi, iwstEthv1AdapterAbi, lidoV1_WETHGatewayAbi, mellowDvvAdapterAbi, minSeizedAmount, optimalHFForPartialLiquidation, optimalRepaidAmount, parseAdapterAction, parseAdapterDeployParams, parsePosNegAmount, pickStrategyTargetCollateral, rayToBps, rewardsFromTransfers, strategyName, swapFromTransfers, toNetTransfers, updatableDependencies, usdToNumber };
|
|
152
|
+
export { AbstractAdapterContract, AbstractLPPriceFeedContract, AbstractPriceFeedContract, AccountMigratorAdapterContract, AdapterType, BalancerStablePriceFeedContract, BalancerV3PoolStatus, BalancerV3RouterAdapterContract, BalancerV3WrapperAdapterContract, BalancerWeightedPriceFeedContract, BoundedPriceFeedContract, CamelotV3AdapterContract, CompositePriceFeedContract, ConstantPriceFeedContract, ConvexV1BaseRewardPoolAdapterContract, ConvexV1BoosterAdapterContract, CreditConfiguratorV310Contract, CreditFacadeV310BaseContract, CreditFacadeV310Contract, CreditManagerV310Contract, CreditSuite, CreditSuiteStrategy, Curve2AssetsAdapterContract, Curve3AssetsAdapterContract, Curve4AssetsAdapterContract, CurveCryptoPriceFeedContract, CurveStablePriceFeedContract, CurveUSDPriceFeedContract, CurveV1AdapterStETHContract, CurveV1StableNGAdapterContract, DEFAULT_QUOTA_BUFFER_BPS, DEGEN_NFT_MIDAS, DEGEN_NFT_SECURITIZE, DaiUsdsAdapterContract, ERC4626AdapterContract, ERC4626ReferralAdapterContract, Erc4626PriceFeedContract, ExternalPriceFeedContract, FluidDexAdapterContract, GaugeContract, IERC20ZapperContract, IETHZapperContract, InfinifiGatewayAdapterContract, InfinifiUnwindingGatewayAdapterContract, KelpLRTDepositPoolAdapterContract, KelpLRTWithdrawalManagerAdapterContract, LidoV1AdapterContract, LinearInterestRateModelContract, MAX_LEVERAGE_BUFFER_BPS, MarketRegister, MarketSuite, MellowClaimerAdapterContract, MellowDVVAdapterContract, MellowERC4626VaultAdapterContract, MellowLRTPriceFeedContract, MellowWrapperAdapterContract, MidasDegenNFT, MidasGatewayAdapterContract, MidasIssuanceVaultAdapterContract, MidasLiquidatorContract, MidasRedemptionVaultAdapterContract, PARTIAL_LIQUIDATION_BUFFER_BPS, PHANTOM_TOKEN_MIDAS_REDEMPTION, PHANTOM_TOKEN_SECURITIZE_REDEMPTION, PartialPriceFeedInitError, PendlePairStatus, PendleRouterAdapterContract, PendleTWAPPTPriceFeed, PendleTokenType, PoolSuite, PoolV310Contract, PriceFeedRef, PriceFeedRegistry, PriceOracleV310Contract, PriceUpdatesCache, PythPriceFeed, RWARegistry, RWA_COMPRESSOR_ADDRESS, RWA_LIQUIDATOR_MIDAS, RWA_LIQUIDATOR_SECURITIZE, RedstonePriceFeedContract, SecuritizeDegenNFT, SecuritizeLiquidatorContract, SecuritizeOnRampAdapterContract, SecuritizeRWAFactory, SecuritizeRedemptionGatewayAdapterContract, StakingRewardsAdapterContract, TraderJoePoolVersion, TraderJoeRouterAdapterContract, UniswapV2AdapterContract, UniswapV3AdapterContract, UniswapV4AdapterContract, UpdatablePriceFeedRegistry, UpshiftVaultAdapterContract, VelodromeV2RouterAdapterContract, WstETHPriceFeedContract, WstETHV1AdapterContract, YearnPriceFeedContract, ZapperContract, ZeroPriceFeedContract, adapterActionAbi, adapterActionSelectors, adapterActionSignatures, adapterConstructorAbi, allTransfersAsTokenAmounts, bpsToRay, calcBorrowApy, calcEffectiveBorrowApy, calcMaxLeverage, calcNetStrategyApy, calcPositionLeverage, calcQuotaRate, calcUtilization, calcUtilizationRaw, classifyCurveOperation, collateralPriceInUnderlying, createAdapter, createPriceOracle, createZapper, abi as creditFacadeV310Abi, curveAddLiquidityFromTransfers, curveRemoveLiquidityFromTransfers, dominantCollateral, erc4626ReferralAdapterAbi, expectedBalanceDeltas, fnSigToName, getAdapterActionAbi, getAdapterDeployParamsAbi, getAdapterType, getRawPriceUpdates, hasAdapterDeployParamsAbi, healthFactorBps, iBalancerV3RouterAbi, iBalancerV3RouterAdapterAbi, iBalancerV3WrapperAbi, iBalancerV3WrapperAdapterAbi, iBaseOnRampAbi, iBaseRewardPoolAbi, iBoosterAbi, iCamelotV3AdapterAbi, iCamelotV3RouterAbi, iConvexV1BaseRewardPoolAdapterAbi, iConvexV1BoosterAdapterAbi, iCurvePoolAbi, iCurvePoolStableNGAbi, iCurvePool_2Abi, iCurvePool_3Abi, iCurvePool_4Abi, iCurveV1StableNgAdapterAbi, iCurveV1_2AssetsAdapterAbi, iCurveV1_3AssetsAdapterAbi, iCurveV1_4AssetsAdapterAbi, iDaiUsdsAbi, iDaiUsdsAdapterAbi, iERC4626Abi, iERC4626ReferralAbi, iFluidDexAbi, iFluidDexAdapterAbi, iInfinifiGatewayAbi, iInfinifiGatewayAdapterAbi, iInfinifiUnwindingGatewayAbi, iInfinifiUnwindingGatewayAdapterAbi, iKelpLRTDepositPoolGatewayAbi, iKelpLRTWithdrawalManagerGatewayAbi, iKelpLrtDepositPoolAdapterAbi, iKelpLrtDepositPoolGatewayAbi, iKelpLrtWithdrawalManagerAdapterAbi, iKelpLrtWithdrawalManagerGatewayAbi, iLidoV1AdapterAbi, iMellow4626VaultAdapterAbi, iMellowClaimerAbi, iMellowClaimerAdapterAbi, iMellowWrapperAbi, iMellowWrapperAdapterAbi, iMidasGatewayAdapterV311Abi, iMidasGatewayV311Abi, iMidasIssuanceVaultAdapterV310Abi, iMidasIssuanceVaultV310Abi, iMidasRedemptionVaultAdapterV310Abi, iMidasRedemptionVaultGatewayV310Abi, iPendleRouterAbi, iPendleRouterAdapterAbi, iSecuritizeOnRampAbi, iSecuritizeOnRampAdapterV310Abi, iSecuritizeRedemptionGatewayAdapterV311Abi, iSecuritizeRedemptionGatewayV311Abi, iStakingRewardsAbi, iStakingRewardsAdapterAbi, iTraderJoeRouterAbi, iTraderJoeRouterAdapterAbi, iUniswapV2AdapterAbi, iUniswapV2Router02Abi, iUniswapV3Abi, iUniswapV3AdapterAbi, iUniswapV4AdapterAbi, iUniswapV4GatewayAbi, iUpshiftVaultAdapterAbi, iUpshiftVaultGatewayAbi, iVelodromeV2RouterAbi, iVelodromeV2RouterAdapterAbi, isLPPriceFeed, isRWAFactory, isStrategyCollateral, isUpdatablePriceFeed, iwstETHAbi, iwstEthv1AdapterAbi, lidoV1_WETHGatewayAbi, mellowDvvAdapterAbi, minSeizedAmount, optimalHFForPartialLiquidation, optimalRepaidAmount, parseAdapterAction, parseAdapterDeployParams, parsePosNegAmount, pickStrategyTargetCollateral, rayToBps, rewardsFromTransfers, strategyName, swapFromTransfers, toNetTransfers, updatableDependencies, usdToNumber };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { iPoolQuotaKeeperV310Abi } from "../../../abi/310/generated.js";
|
|
2
2
|
import { AddressMap } from "../../utils/AddressMap.js";
|
|
3
|
+
import { BigIntMath } from "../../utils/bigint-math.js";
|
|
3
4
|
import { formatBNvalue, percentFmt } from "../../utils/formatter.js";
|
|
4
5
|
import "../../utils/index.js";
|
|
5
6
|
import { BaseContract } from "../../base/BaseContract.js";
|
|
@@ -40,10 +41,12 @@ var PoolQuotaKeeperV310Contract = class extends BaseContract {
|
|
|
40
41
|
/**
|
|
41
42
|
* How much more quota the market will take for a token, in the underlying.
|
|
42
43
|
* `0n` when the market has no quota entry; not the same as {@link hasActiveQuota}.
|
|
44
|
+
* Never negative: a limit lowered under what is already quoted leaves no
|
|
45
|
+
* room, not a debt.
|
|
43
46
|
*/
|
|
44
47
|
quotaAvailable(token) {
|
|
45
48
|
const quota = this.quotas.get(token);
|
|
46
|
-
return quota ? quota.limit - quota.totalQuoted : 0n;
|
|
49
|
+
return quota ? BigIntMath.max(0n, quota.limit - quota.totalQuoted) : 0n;
|
|
47
50
|
}
|
|
48
51
|
/**
|
|
49
52
|
* Annual quota rate paid on a quoted token, in basis points, or `0` when the
|
|
@@ -42,12 +42,11 @@ var OpportunitiesService = class extends SDKConstruct {
|
|
|
42
42
|
* strategy.
|
|
43
43
|
**/
|
|
44
44
|
async getStrategy(key) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const kyc = await suite.kycRequirement(detail.targetCollateral.address);
|
|
45
|
+
const strategy = this.sdk.marketRegister.findCreditManager(key.creditManager).strategy;
|
|
46
|
+
if (!strategy?.isListed) throw new Error(`credit manager ${key.creditManager} does not currently offer a strategy`);
|
|
47
|
+
const kyc = await strategy.kycRequirement();
|
|
49
48
|
return {
|
|
50
|
-
...
|
|
49
|
+
...strategy.opportunityDetail(),
|
|
51
50
|
kyc
|
|
52
51
|
};
|
|
53
52
|
}
|
|
@@ -59,10 +58,9 @@ var OpportunitiesService = class extends SDKConstruct {
|
|
|
59
58
|
* strategy.
|
|
60
59
|
**/
|
|
61
60
|
async isEligibleForStrategy(key, wallet) {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return suite.isEligibleForStrategy(wallet, opportunity.targetCollateral.address);
|
|
61
|
+
const strategy = this.sdk.marketRegister.findCreditManager(key.creditManager).strategy;
|
|
62
|
+
if (!strategy?.isListed) throw new Error(`credit manager ${key.creditManager} does not currently offer a strategy`);
|
|
63
|
+
return strategy.isEligible(wallet);
|
|
66
64
|
}
|
|
67
65
|
};
|
|
68
66
|
//#endregion
|
|
@@ -230,7 +230,7 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
230
230
|
const sdk = await this.#chain(strategy.chainId);
|
|
231
231
|
const at = stateBlock(sdk);
|
|
232
232
|
Object.assign(state, marketOf(sdk, strategy.creditManager));
|
|
233
|
-
const targetToken = params.targetToken ?? sdk.marketRegister.findCreditManager(strategy.creditManager).
|
|
233
|
+
const targetToken = params.targetToken ?? sdk.marketRegister.findCreditManager(strategy.creditManager).strategy?.targetCollateral;
|
|
234
234
|
if (!targetToken) return refused(noStrategyTargetCollateral(strategy.creditManager), state);
|
|
235
235
|
const reused = await reusable(sdk, strategy, params.creditAccount);
|
|
236
236
|
if (reused && "error" in reused) return refused(reused.error, state);
|
|
@@ -21,9 +21,9 @@ import { createMinter } from "./mint/factory.js";
|
|
|
21
21
|
import "./mint/index.js";
|
|
22
22
|
import { RpcProvider, SUPPORTED_RPC_PROVIDERS, getAlchemyUrl, getAnkrUrl, getDrpcUrl, getErpcKey, getRpcProviderUrl, getThirdWebUrl, rpcProvidersSchema } from "./providers.js";
|
|
23
23
|
import { ReplaceStorageParams, replaceStorage } from "./replaceStorage.js";
|
|
24
|
-
import { ResilientTransportOptions, resilientTransport, resilientTransportOptionsSchema } from "./resilientTransport.js";
|
|
24
|
+
import { RateLimitOptions, ResilientTransportOptions, rateLimitOptionsSchema, resilientTransport, resilientTransportOptionsSchema } from "./resilientTransport.js";
|
|
25
25
|
import { EnableDSTokenBackDatingProps, RestoreDSTokenBackDating, claimDSToken, claimDSTokens, enableDSTokenBackDating } from "./securitizeUtils.js";
|
|
26
26
|
import { httpTransportOptionsSchema } from "./transports.js";
|
|
27
27
|
import { ONCHAIN_EXECUTION_ID_ADDRESS, VerifyTestnetParams, verifyTestnet } from "./verifyTestnet.js";
|
|
28
28
|
import { MakePendingWithdrawalsClaimableOptions, makePendingWithdrawalsClaimable } from "./withdrawalUtils.js";
|
|
29
|
-
export { AccountOpener, AccountOpenerOptions, AnvilActions, AnvilClient, AnvilClientConfig, AnvilDealParameters, AnvilNodeInfo, AnvilRPCSchema, CheckMulticallFn, Create2Deployer, Create2Parameters, DEFAULT_CREATE2_SALT, DEFAULT_MIDAS_ADMIN, DetectedCall, EnableDSTokenBackDatingProps, EnsureExistsUsingPublicCreate2ReturnType, EthCallMethod, EthCallRequest, EthCallSpy, GetCreate2AddressParameters, GreenlistMidasGatewayProps, IMinter, type LogSplitterTransportOptions, MakePendingWithdrawalsClaimableOptions, MidasCreditSuite, NoAvailableTransportsError, ONCHAIN_EXECUTION_ID_ADDRESS, OpenAccountHumanizedPreview, OpenAccountResult, OpenAccountsResult, OpenTxRevertedError, PUBLIC_CREATE2_FACTORY, PoolDepositResult, ProviderConfig, ProviderStatus, RWAKycFailure, RegisterMidasInvestorProps, RegisterRWAInvestorProps, RegisterRWAInvestorResult, RegisterSecuritizeInvestorProps, ReplaceStorageParams, ResilientTransportOptions, RestoreDSTokenBackDating, RestoreMidasIssuanceVaultPause, RevolverTransport, RevolverTransportConfig, RevolverTransportValue, RpcErrorResult, RpcProvider, RpcResponse, RpcSuccessResult, SUPPORTED_RPC_PROVIDERS, SelectionStrategy, TargetAccount, UnpauseMidasIssuanceVaultProps, VerifyTestnetParams, anvilNodeInfo, calcLiquidatableLTs, claimDSToken, claimDSTokens, claimFromFaucet, createAnvilClient, createMinter, deployUsingPublicCreate2, detectChain, discoverMidasCreditSuites, discoverMidasGateways, discoverMidasMTokens, enableDSTokenBackDating, evmMineDetailed, extendAnvilClient, getAlchemyUrl, getAnkrUrl, getDrpcUrl, getErpcKey, getPublicCreate2Address, getRpcProviderUrl, getSecuritizeAdmin, getThirdWebUrl, greenlistMidasGateway, httpTransportOptionsSchema, iDegenNftv2Abi, iFaucetAbi, iOnchainExecutionIdAbi, iOwnableAbi, iaclTraitAbi, isAnvil, isDeployedUsingPublicCreate2, isOutOfSyncError, isRangeError, isRateLimitError, isTransientError, logSplitterTransport, makePendingWithdrawalsClaimable, migrateFaucet, providerConfigSchema, registerMidasInvestor, registerRWAInvestor, registerSecuritizeInvestor, replaceStorage, resilientTransport, resilientTransportOptionsSchema, revolverTransportConfigBaseSchema, revolverTransportConfigSchema, rpcProvidersSchema, setLTZero, setLTs, unpauseMidasIssuanceVault, verifyTestnet, writeContractSync };
|
|
29
|
+
export { AccountOpener, AccountOpenerOptions, AnvilActions, AnvilClient, AnvilClientConfig, AnvilDealParameters, AnvilNodeInfo, AnvilRPCSchema, CheckMulticallFn, Create2Deployer, Create2Parameters, DEFAULT_CREATE2_SALT, DEFAULT_MIDAS_ADMIN, DetectedCall, EnableDSTokenBackDatingProps, EnsureExistsUsingPublicCreate2ReturnType, EthCallMethod, EthCallRequest, EthCallSpy, GetCreate2AddressParameters, GreenlistMidasGatewayProps, IMinter, type LogSplitterTransportOptions, MakePendingWithdrawalsClaimableOptions, MidasCreditSuite, NoAvailableTransportsError, ONCHAIN_EXECUTION_ID_ADDRESS, OpenAccountHumanizedPreview, OpenAccountResult, OpenAccountsResult, OpenTxRevertedError, PUBLIC_CREATE2_FACTORY, PoolDepositResult, ProviderConfig, ProviderStatus, RWAKycFailure, RateLimitOptions, RegisterMidasInvestorProps, RegisterRWAInvestorProps, RegisterRWAInvestorResult, RegisterSecuritizeInvestorProps, ReplaceStorageParams, ResilientTransportOptions, RestoreDSTokenBackDating, RestoreMidasIssuanceVaultPause, RevolverTransport, RevolverTransportConfig, RevolverTransportValue, RpcErrorResult, RpcProvider, RpcResponse, RpcSuccessResult, SUPPORTED_RPC_PROVIDERS, SelectionStrategy, TargetAccount, UnpauseMidasIssuanceVaultProps, VerifyTestnetParams, anvilNodeInfo, calcLiquidatableLTs, claimDSToken, claimDSTokens, claimFromFaucet, createAnvilClient, createMinter, deployUsingPublicCreate2, detectChain, discoverMidasCreditSuites, discoverMidasGateways, discoverMidasMTokens, enableDSTokenBackDating, evmMineDetailed, extendAnvilClient, getAlchemyUrl, getAnkrUrl, getDrpcUrl, getErpcKey, getPublicCreate2Address, getRpcProviderUrl, getSecuritizeAdmin, getThirdWebUrl, greenlistMidasGateway, httpTransportOptionsSchema, iDegenNftv2Abi, iFaucetAbi, iOnchainExecutionIdAbi, iOwnableAbi, iaclTraitAbi, isAnvil, isDeployedUsingPublicCreate2, isOutOfSyncError, isRangeError, isRateLimitError, isTransientError, logSplitterTransport, makePendingWithdrawalsClaimable, migrateFaucet, providerConfigSchema, rateLimitOptionsSchema, registerMidasInvestor, registerRWAInvestor, registerSecuritizeInvestor, replaceStorage, resilientTransport, resilientTransportOptionsSchema, revolverTransportConfigBaseSchema, revolverTransportConfigSchema, rpcProvidersSchema, setLTZero, setLTs, unpauseMidasIssuanceVault, verifyTestnet, writeContractSync };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
//#region src/dev/isRateLimitError.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Whether the error indicates rate limiting. Returns `retryAfterMs` from the `Retry-After` header when available
|
|
3
|
+
* Whether the error indicates rate limiting. Returns `retryAfterMs` from the `Retry-After` header when available,
|
|
4
|
+
* otherwise from a retry hint in the error message (e.g. "retry in 10s").
|
|
4
5
|
*/
|
|
5
6
|
declare function isRateLimitError(e: Error): [checkResult: boolean, retryAfterMs?: number | undefined];
|
|
6
7
|
//#endregion
|
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
import { Transport } from "viem";
|
|
2
2
|
import { z } from "zod/v4";
|
|
3
3
|
//#region src/dev/resilientTransport.d.ts
|
|
4
|
+
/** Schema for {@link RateLimitOptions}. */
|
|
5
|
+
declare const rateLimitOptionsSchema: z.ZodObject<{
|
|
6
|
+
retryCount: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
maxDelay: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
/** Rate-limit retry settings accepted by `handleRateLimit`. */
|
|
10
|
+
type RateLimitOptions = z.input<typeof rateLimitOptionsSchema>;
|
|
4
11
|
/** Schema for {@link ResilientTransportOptions}. */
|
|
5
12
|
declare const resilientTransportOptionsSchema: z.ZodObject<{
|
|
6
13
|
retryCount: z.ZodDefault<z.ZodNumber>;
|
|
7
14
|
delay: z.ZodDefault<z.ZodNumber>;
|
|
8
15
|
maxDelay: z.ZodDefault<z.ZodNumber>;
|
|
9
16
|
jitter: z.ZodDefault<z.ZodNumber>;
|
|
10
|
-
handleRateLimit: z.
|
|
17
|
+
handleRateLimit: z.ZodPrefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
|
|
18
|
+
retryCount: z.ZodDefault<z.ZodNumber>;
|
|
19
|
+
maxDelay: z.ZodDefault<z.ZodNumber>;
|
|
20
|
+
}, z.core.$strip>]>, z.ZodTransform<false | {
|
|
21
|
+
retryCount: number;
|
|
22
|
+
maxDelay: number;
|
|
23
|
+
}, boolean | {
|
|
24
|
+
retryCount: number;
|
|
25
|
+
maxDelay: number;
|
|
26
|
+
}>>>;
|
|
11
27
|
handleTransient: z.ZodDefault<z.ZodBoolean>;
|
|
12
28
|
handleOutOfSync: z.ZodDefault<z.ZodBoolean>;
|
|
13
29
|
}, z.core.$strip>;
|
|
@@ -19,4 +35,4 @@ type ResilientTransportOptions = z.input<typeof resilientTransportOptionsSchema>
|
|
|
19
35
|
*/
|
|
20
36
|
declare function resilientTransport(underlyingTransport: Transport, options?: ResilientTransportOptions): Transport;
|
|
21
37
|
//#endregion
|
|
22
|
-
export { ResilientTransportOptions, resilientTransport, resilientTransportOptionsSchema };
|
|
38
|
+
export { RateLimitOptions, ResilientTransportOptions, rateLimitOptionsSchema, resilientTransport, resilientTransportOptionsSchema };
|
|
@@ -11,11 +11,16 @@ import { Address } from "viem";
|
|
|
11
11
|
* - `poolAvailableLiquidity` — the pool's available liquidity
|
|
12
12
|
* - `managerDebtAvailable` — this credit manager's remaining debt allowance
|
|
13
13
|
* - `maxDebt` — the facade's per-account `debtLimits.maxDebt`
|
|
14
|
+
* - `quotaAvailable` — remaining quota the market takes for the suite's
|
|
15
|
+
* strategy target collateral (`limit - totalQuoted`, floored at 0); only an
|
|
16
|
+
* account being opened is held to it
|
|
17
|
+
* - `minDebt` — every other limit left less than the facade's `minDebt`, so
|
|
18
|
+
* no account can be opened; the amount is 0
|
|
14
19
|
* - `debtPerBlockLimit` — facade takes no new debt this block; in practice
|
|
15
20
|
* `maxDebtPerBlockMultiplier == 0` after a with-loss liquidation
|
|
16
21
|
* - `poolDebtLimit` — pool-wide debt cap; used on account-opening only
|
|
17
22
|
**/
|
|
18
|
-
type BorrowLimitCause = "poolAvailableLiquidity" | "managerDebtAvailable" | "maxDebt" | "debtPerBlockLimit" | "poolDebtLimit";
|
|
23
|
+
type BorrowLimitCause = "poolAvailableLiquidity" | "managerDebtAvailable" | "maxDebt" | "quotaAvailable" | "minDebt" | "debtPerBlockLimit" | "poolDebtLimit";
|
|
19
24
|
/**
|
|
20
25
|
* The credit manager is paused and takes no multicall at all.
|
|
21
26
|
**/
|