@gearbox-protocol/sdk 16.0.0-next.46 → 16.0.0-next.48
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/onchain/accounts/intents/testing/sdk-mock.js +2 -0
- package/dist/cjs/onchain/index.js +0 -2
- package/dist/cjs/onchain/market/MarketSuite.js +37 -1
- package/dist/cjs/onchain/market/credit/CreditSuite.js +1 -2
- package/dist/cjs/onchain/market/pool/PoolV310Contract.js +25 -0
- package/dist/cjs/onchain/pools/PoolService.js +5 -56
- package/dist/cjs/onchain/pools/index.js +0 -2
- package/dist/cjs/onchain/positions/PositionsService.js +4 -2
- package/dist/cjs/preview/index.js +2 -0
- package/dist/cjs/preview/preview/buildDelayedStrategyPositionOperationPreview.js +20 -20
- package/dist/cjs/preview/preview/errors.js +16 -0
- package/dist/cjs/preview/preview/index.js +2 -1
- package/dist/cjs/preview/preview/previewAdjustStrategyPosition.js +4 -12
- package/dist/cjs/preview/preview/previewExitOrRepayStrategyPosition.js +15 -5
- package/dist/cjs/preview/preview/previewPoolPositionOperation.js +31 -12
- package/dist/cjs/preview/simulate/index.js +1 -1
- package/dist/cjs/preview/simulate/simulateOperation.js +1 -1
- package/dist/cjs/preview/simulate/simulatePoolOperation.js +2 -0
- package/dist/cjs/sdk/prepare/PrepareApi.js +5 -6
- package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +2 -0
- package/dist/esm/onchain/index.js +2 -2
- package/dist/esm/onchain/market/MarketSuite.js +37 -1
- package/dist/esm/onchain/market/credit/CreditSuite.js +1 -2
- package/dist/esm/onchain/market/pool/PoolV310Contract.js +25 -0
- package/dist/esm/onchain/pools/PoolService.js +7 -56
- package/dist/esm/onchain/pools/index.js +2 -2
- package/dist/esm/onchain/positions/PositionsService.js +4 -2
- package/dist/esm/preview/index.js +2 -1
- package/dist/esm/preview/preview/buildDelayedStrategyPositionOperationPreview.js +21 -21
- package/dist/esm/preview/preview/errors.js +16 -1
- package/dist/esm/preview/preview/index.js +2 -2
- package/dist/esm/preview/preview/previewAdjustStrategyPosition.js +5 -13
- package/dist/esm/preview/preview/previewExitOrRepayStrategyPosition.js +15 -5
- package/dist/esm/preview/preview/previewPoolPositionOperation.js +33 -14
- package/dist/esm/preview/simulate/index.js +1 -1
- package/dist/esm/preview/simulate/simulateOperation.js +1 -1
- package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
- package/dist/esm/sdk/prepare/PrepareApi.js +5 -6
- package/dist/types/model/positions.d.ts +4 -1
- package/dist/types/model/previews.d.ts +34 -23
- package/dist/types/onchain/index.d.ts +4 -4
- package/dist/types/onchain/market/MarketSuite.d.ts +35 -2
- package/dist/types/onchain/market/index.d.ts +2 -2
- package/dist/types/onchain/market/pool/PoolV310Contract.d.ts +12 -0
- package/dist/types/onchain/market/pool/types.d.ts +18 -0
- package/dist/types/onchain/pools/PoolService.d.ts +2 -29
- package/dist/types/onchain/pools/index.d.ts +3 -3
- package/dist/types/onchain/pools/types.d.ts +1 -40
- package/dist/types/preview/index.d.ts +2 -2
- package/dist/types/preview/preview/buildDelayedStrategyPositionOperationPreview.d.ts +3 -2
- package/dist/types/preview/preview/errors.d.ts +9 -1
- package/dist/types/preview/preview/index.d.ts +2 -2
- package/dist/types/preview/simulate/simulatePoolOperation.d.ts +18 -1
- package/dist/types/preview/simulate/types.d.ts +12 -4
- package/dist/types/sdk/prepare/types.d.ts +6 -4
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ require("../../../constants/math.js");
|
|
|
2
2
|
require("../../../constants/index.js");
|
|
3
3
|
const require_onchain_market_math = require("../../../market/math.js");
|
|
4
4
|
const require_onchain_market_credit_CreditSuite = require("../../../market/credit/CreditSuite.js");
|
|
5
|
+
const require_onchain_market_MarketSuite = require("../../../market/MarketSuite.js");
|
|
5
6
|
const require_onchain_positions_PositionsService = require("../../../positions/PositionsService.js");
|
|
6
7
|
let vitest = require("vitest");
|
|
7
8
|
//#region src/onchain/accounts/intents/testing/sdk-mock.ts
|
|
@@ -221,6 +222,7 @@ function buildMockSdk(args) {
|
|
|
221
222
|
underlying: args.underlying
|
|
222
223
|
}
|
|
223
224
|
};
|
|
225
|
+
Object.assign(market, { valueInUnderlying: require_onchain_market_MarketSuite.MarketSuite.prototype.valueInUnderlying });
|
|
224
226
|
const collateralTokens = [args.underlying.toLowerCase(), ...Object.keys(args.liquidationThresholds).map((t) => t.toLowerCase()).filter((t) => t !== args.underlying.toLowerCase())];
|
|
225
227
|
const forbidden = new Set((args.forbiddenTokens ?? []).map((t) => t.toLowerCase()));
|
|
226
228
|
const forbiddenTokensMask = collateralTokens.reduce((mask, token, i) => forbidden.has(token) ? mask | 1n << BigInt(i) : mask, 0n);
|
|
@@ -704,8 +704,6 @@ exports.toCreditAccountSlice = require_onchain_accounts_intents_utils_credit_acc
|
|
|
704
704
|
exports.toNetTransfers = require_onchain_market_adapters_transferHelpers.toNetTransfers;
|
|
705
705
|
exports.toPendingWithdrawal = require_onchain_accounts_withdrawal_compressor_AbstractWithdrawalCompressorContract.toPendingWithdrawal;
|
|
706
706
|
exports.toRequestableWithdrawal = require_onchain_accounts_withdrawal_compressor_AbstractWithdrawalCompressorContract.toRequestableWithdrawal;
|
|
707
|
-
exports.toShares = require_onchain_pools_PoolService.toShares;
|
|
708
|
-
exports.toSharesUp = require_onchain_pools_PoolService.toSharesUp;
|
|
709
707
|
exports.toSignificant = require_onchain_utils_formatter.toSignificant;
|
|
710
708
|
exports.toToken = require_onchain_validation_token.toToken;
|
|
711
709
|
exports.toTokenAmount = require_onchain_validation_token.toTokenAmount;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_onchain_utils_AddressMap = require("../utils/AddressMap.js");
|
|
3
3
|
const require_onchain_chain_chains = require("../chain/chains.js");
|
|
4
|
+
const require_onchain_constants_math = require("../constants/math.js");
|
|
5
|
+
require("../constants/index.js");
|
|
4
6
|
require("../utils/index.js");
|
|
5
7
|
const require_onchain_base_SDKConstruct = require("../base/SDKConstruct.js");
|
|
6
8
|
require("../base/index.js");
|
|
@@ -128,6 +130,14 @@ var MarketSuite = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
128
130
|
};
|
|
129
131
|
}
|
|
130
132
|
/**
|
|
133
|
+
* Whether `token` is this market's pool underlying or the asset it wraps
|
|
134
|
+
* (dcUSDC or USDC on an RWA pool). Amounts in either unit are 1:1 with the
|
|
135
|
+
* figure {@link toUnderlyingAmount} reports.
|
|
136
|
+
*/
|
|
137
|
+
isUnderlyingLike(token) {
|
|
138
|
+
return (0, viem.isAddressEqual)(token, this.underlying) || (0, viem.isAddressEqual)(token, this.unwrappedUnderlying);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
131
141
|
* Prices a figure already denominated in this market's underlying — a debt,
|
|
132
142
|
* a TVL, a payout — as the read model reports one.
|
|
133
143
|
*
|
|
@@ -143,6 +153,32 @@ var MarketSuite = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
143
153
|
...this.priceOracle.toAmount(this.underlying, value)
|
|
144
154
|
});
|
|
145
155
|
/**
|
|
156
|
+
* Sums `assets` in this market's underlying at latest oracle prices.
|
|
157
|
+
*
|
|
158
|
+
* Balances at or below `minBalance` are ignored. A token the oracle cannot
|
|
159
|
+
* price contributes nothing; the first such token is {@link ValueInUnderlying.unpriceable}.
|
|
160
|
+
*
|
|
161
|
+
* The counterpart of {@link toUnderlyingAmount}: that method labels a figure
|
|
162
|
+
* already in underlying, this one produces the figure from mixed holdings.
|
|
163
|
+
**/
|
|
164
|
+
valueInUnderlying(assets, minBalance = require_onchain_constants_math.DUST_THRESHOLD) {
|
|
165
|
+
let unpriceable;
|
|
166
|
+
let value = 0n;
|
|
167
|
+
for (const { token, balance } of assets) {
|
|
168
|
+
if (balance <= minBalance) continue;
|
|
169
|
+
const converted = this.priceOracle.safeConvert(token, this.underlying, balance);
|
|
170
|
+
if (converted === null) {
|
|
171
|
+
unpriceable ??= token;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
value += converted;
|
|
175
|
+
}
|
|
176
|
+
return unpriceable === void 0 ? { value } : {
|
|
177
|
+
value,
|
|
178
|
+
unpriceable
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
146
182
|
* Display name of this market's pool, e.g. `"USDC Pool"`.
|
|
147
183
|
*/
|
|
148
184
|
get poolName() {
|
|
@@ -166,7 +202,7 @@ var MarketSuite = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
166
202
|
seen.upsert(this.unwrappedUnderlying, this.underlyingToken);
|
|
167
203
|
for (const zapper of this.sdk.marketRegister.poolZappers(this.pool.pool.address)) {
|
|
168
204
|
const tokenIn = zapper.tokenIn.addr;
|
|
169
|
-
if (
|
|
205
|
+
if (this.isUnderlyingLike(tokenIn)) continue;
|
|
170
206
|
seen.upsert(tokenIn, this.tokensMeta.mustGetToken(tokenIn));
|
|
171
207
|
}
|
|
172
208
|
return seen.values();
|
|
@@ -392,8 +392,7 @@ var CreditSuite = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
392
392
|
*/
|
|
393
393
|
#allowedDepositTokens(targetCollateral) {
|
|
394
394
|
const unwrappedUnderlying = this.market.unwrappedUnderlying;
|
|
395
|
-
const
|
|
396
|
-
const skip = (token) => (0, viem.isAddressEqual)(token, unwrappedUnderlying) || (0, viem.isAddressEqual)(token, contractUnderlying) || (0, viem.isAddressEqual)(token, targetCollateral);
|
|
395
|
+
const skip = (token) => this.market.isUnderlyingLike(token) || (0, viem.isAddressEqual)(token, targetCollateral);
|
|
397
396
|
return [
|
|
398
397
|
unwrappedUnderlying,
|
|
399
398
|
targetCollateral,
|
|
@@ -51,6 +51,31 @@ var PoolV310Contract = class extends require_onchain_base_BaseContract.BaseContr
|
|
|
51
51
|
return this.totalSupply * this.dieselRate / require_onchain_constants_math.RAY;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
|
+
* {@inheritDoc IPoolContract.getShareBalance}
|
|
55
|
+
*/
|
|
56
|
+
async getShareBalance(wallet, blockNumber) {
|
|
57
|
+
return this.client.readContract({
|
|
58
|
+
address: this.address,
|
|
59
|
+
abi: this.abi,
|
|
60
|
+
functionName: "balanceOf",
|
|
61
|
+
args: [wallet],
|
|
62
|
+
blockNumber
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* {@inheritDoc IPoolContract.sharesToUnderlying}
|
|
67
|
+
*/
|
|
68
|
+
sharesToUnderlying(shares) {
|
|
69
|
+
return this.dieselRate === 0n ? shares : shares * this.dieselRate / require_onchain_constants_math.RAY;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* {@inheritDoc IPoolContract.underlyingToShares}
|
|
73
|
+
*/
|
|
74
|
+
underlyingToShares(underlying, roundUp = false) {
|
|
75
|
+
if (this.dieselRate === 0n) return underlying;
|
|
76
|
+
return roundUp ? (underlying * require_onchain_constants_math.RAY + this.dieselRate - 1n) / this.dieselRate : underlying * require_onchain_constants_math.RAY / this.dieselRate;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
54
79
|
* {@inheritDoc IPoolContract.unwrappedUnderlying}
|
|
55
80
|
*/
|
|
56
81
|
get unwrappedUnderlying() {
|
|
@@ -30,25 +30,6 @@ function payoutCeiling(market) {
|
|
|
30
30
|
return market.priceOracle.toAmount(pool.underlying, pool.pool.availableLiquidity * LIQUIDITY_SAFETY_NUM / LIQUIDITY_SAFETY_DENOM);
|
|
31
31
|
}
|
|
32
32
|
var PoolService = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
33
|
-
/**
|
|
34
|
-
* {@inheritDoc IPoolsService.getShareBalance}
|
|
35
|
-
*/
|
|
36
|
-
async getShareBalance(props) {
|
|
37
|
-
return this.client.readContract({
|
|
38
|
-
address: this.sdk.marketRegister.findByPool(props.pool).pool.pool.address,
|
|
39
|
-
abi: require_abi_iERC20.ierc20Abi,
|
|
40
|
-
functionName: "balanceOf",
|
|
41
|
-
args: [props.wallet],
|
|
42
|
-
blockNumber: props.blockNumber
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* {@inheritDoc IPoolsService.sharesToUnderlying}
|
|
47
|
-
*/
|
|
48
|
-
sharesToUnderlying(pool, shares) {
|
|
49
|
-
const market = this.sdk.marketRegister.findByPool(pool);
|
|
50
|
-
return market.toUnderlyingAmount(shares * market.pool.pool.dieselRate / require_onchain_constants_math.RAY);
|
|
51
|
-
}
|
|
52
33
|
/**
|
|
53
34
|
* {@inheritDoc IPoolsService.getDepositTokensIn}
|
|
54
35
|
*/
|
|
@@ -165,7 +146,7 @@ var PoolService = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
165
146
|
const { zapper } = this.getDepositMetadata(poolAddr, tokenIn, tokenOut);
|
|
166
147
|
return {
|
|
167
148
|
tokenIn: toTokenAmount(tokenIn, amount),
|
|
168
|
-
tokenOut: toTokenAmount(tokenOut,
|
|
149
|
+
tokenOut: toTokenAmount(tokenOut, pool.pool.underlyingToShares(amount)),
|
|
169
150
|
zapper: zapper?.baseParams.addr
|
|
170
151
|
};
|
|
171
152
|
}
|
|
@@ -185,7 +166,7 @@ var PoolService = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
185
166
|
});
|
|
186
167
|
const { zapper } = this.getWithdrawalMetadata(poolAddr, tokenIn, tokenOut);
|
|
187
168
|
return {
|
|
188
|
-
tokenIn: toTokenAmount(tokenIn,
|
|
169
|
+
tokenIn: toTokenAmount(tokenIn, pool.pool.underlyingToShares(amount * require_onchain_constants_math.PERCENTAGE_FACTOR / (require_onchain_constants_math.PERCENTAGE_FACTOR - pool.pool.withdrawFee), true)),
|
|
189
170
|
tokenOut: toTokenAmount(tokenOut, amount),
|
|
190
171
|
zapper: zapper?.baseParams.addr,
|
|
191
172
|
availableLiquidity: payoutCeiling(market)
|
|
@@ -208,7 +189,7 @@ var PoolService = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
208
189
|
const { zapper } = this.getWithdrawalMetadata(poolAddr, tokenIn, tokenOut);
|
|
209
190
|
return {
|
|
210
191
|
tokenIn: toTokenAmount(tokenIn, amount),
|
|
211
|
-
tokenOut: toTokenAmount(tokenOut,
|
|
192
|
+
tokenOut: toTokenAmount(tokenOut, pool.pool.sharesToUnderlying(amount) * (require_onchain_constants_math.PERCENTAGE_FACTOR - pool.pool.withdrawFee) / require_onchain_constants_math.PERCENTAGE_FACTOR),
|
|
212
193
|
zapper: zapper?.baseParams.addr,
|
|
213
194
|
availableLiquidity: payoutCeiling(market)
|
|
214
195
|
};
|
|
@@ -240,7 +221,7 @@ var PoolService = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
240
221
|
}
|
|
241
222
|
const poolContract = this.sdk.marketRegister.findByPool(pool).pool.pool;
|
|
242
223
|
if (meta.zapper instanceof require_onchain_market_zapper_IETHZapperContract.IETHZapperContract || meta.zapper instanceof require_onchain_market_zapper_IERC20ZapperContract.IERC20ZapperContract) {
|
|
243
|
-
const shares = mode === "withdraw" ?
|
|
224
|
+
const shares = mode === "withdraw" ? poolContract.underlyingToShares(amount * require_onchain_constants_math.PERCENTAGE_FACTOR / (require_onchain_constants_math.PERCENTAGE_FACTOR - poolContract.withdrawFee), true) : amount;
|
|
244
225
|
const tx = permit ? meta.zapper.redeemWithPermit(shares, wallet, permit.deadline, permit.v, permit.r, permit.s) : meta.zapper.redeem(shares, wallet);
|
|
245
226
|
return {
|
|
246
227
|
tx,
|
|
@@ -434,42 +415,10 @@ var PoolService = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
434
415
|
chainId: this.chainId,
|
|
435
416
|
pool: pool.address,
|
|
436
417
|
underlyingToken: market.underlyingToken,
|
|
437
|
-
netValue:
|
|
418
|
+
netValue: market.toUnderlyingAmount(pool.sharesToUnderlying(shares)),
|
|
438
419
|
apy: { organicApy: require_onchain_market_math.rayToBps(pool.supplyRate) }
|
|
439
420
|
};
|
|
440
421
|
}
|
|
441
422
|
};
|
|
442
|
-
/**
|
|
443
|
-
* Shares minted for `assets`, as `previewDeposit` would report them.
|
|
444
|
-
*
|
|
445
|
-
* Both directions convert through the diesel rate — underlying per RAY of
|
|
446
|
-
* shares — because that is the rate the pool itself divides by, and the only
|
|
447
|
-
* exact one the SDK holds: `totalAssets` is this rate multiplied out, so
|
|
448
|
-
* converting back through it costs a wei on large amounts. Rounds down, as
|
|
449
|
-
* minting does.
|
|
450
|
-
*/
|
|
451
|
-
function toShares(pool, assets) {
|
|
452
|
-
const { dieselRate } = pool;
|
|
453
|
-
return dieselRate === 0n ? assets : assets * require_onchain_constants_math.RAY / dieselRate;
|
|
454
|
-
}
|
|
455
|
-
/**
|
|
456
|
-
* Shares a withdrawal of `assets` burns, as `previewWithdraw` would report
|
|
457
|
-
* them: {@link toShares} rounded the other way, since the burn has to cover
|
|
458
|
-
* the payout the caller asked for.
|
|
459
|
-
*/
|
|
460
|
-
function toSharesUp(pool, assets) {
|
|
461
|
-
const { dieselRate } = pool;
|
|
462
|
-
return dieselRate === 0n ? assets : (assets * require_onchain_constants_math.RAY + dieselRate - 1n) / dieselRate;
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* Underlying paid out for `shares`, as `previewRedeem` would report it:
|
|
466
|
-
* {@link toShares} run backwards, less the pool's withdrawal fee.
|
|
467
|
-
*/
|
|
468
|
-
function toAssets(pool, shares) {
|
|
469
|
-
const { dieselRate, withdrawFee } = pool;
|
|
470
|
-
return (dieselRate === 0n ? shares : shares * dieselRate / require_onchain_constants_math.RAY) * (require_onchain_constants_math.PERCENTAGE_FACTOR - withdrawFee) / require_onchain_constants_math.PERCENTAGE_FACTOR;
|
|
471
|
-
}
|
|
472
423
|
//#endregion
|
|
473
424
|
exports.PoolService = PoolService;
|
|
474
|
-
exports.toShares = toShares;
|
|
475
|
-
exports.toSharesUp = toSharesUp;
|
|
@@ -2,5 +2,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_onchain_pools_PoolService = require("./PoolService.js");
|
|
3
3
|
require("./types.js");
|
|
4
4
|
exports.PoolService = require_onchain_pools_PoolService.PoolService;
|
|
5
|
-
exports.toShares = require_onchain_pools_PoolService.toShares;
|
|
6
|
-
exports.toSharesUp = require_onchain_pools_PoolService.toSharesUp;
|
|
@@ -294,12 +294,14 @@ var PositionsService = class extends require_onchain_base_SDKConstruct.SDKConstr
|
|
|
294
294
|
withdrawals: withdrawals.get(t.token) ?? []
|
|
295
295
|
});
|
|
296
296
|
if (recomputeTotals) {
|
|
297
|
-
const value = priceOracle.safeConvert(t.token, market.underlying, t.balance) || 0n;
|
|
298
|
-
totalValue += value;
|
|
299
297
|
const usd = priceOracle.safeConvertToUSD(t.token, t.balance) || 0n;
|
|
300
298
|
totalValueUSD += usd;
|
|
301
299
|
}
|
|
302
300
|
}
|
|
301
|
+
if (recomputeTotals) totalValue = market.valueInUnderlying(ca.tokens.map((t) => ({
|
|
302
|
+
token: t.token,
|
|
303
|
+
balance: t.balance
|
|
304
|
+
}))).value;
|
|
303
305
|
const snapshot = {
|
|
304
306
|
...require_onchain_positions_types.accountSnapshotFromCreditAccountData(ca),
|
|
305
307
|
totalValue
|
|
@@ -18,6 +18,7 @@ const require_preview_prerequisites_BalancePrerequisite = require("./prerequisit
|
|
|
18
18
|
const require_preview_prerequisites_RWAOpenRequirementsPrerequisite = require("./prerequisites/RWAOpenRequirementsPrerequisite.js");
|
|
19
19
|
const require_preview_prerequisites_checkPrerequisites = require("./prerequisites/checkPrerequisites.js");
|
|
20
20
|
require("./prerequisites/index.js");
|
|
21
|
+
const require_preview_preview_errors = require("./preview/errors.js");
|
|
21
22
|
const require_preview_preview_buildDelayedStrategyPositionOperationPreview = require("./preview/buildDelayedStrategyPositionOperationPreview.js");
|
|
22
23
|
const require_preview_preview_CreditAccountState = require("./preview/CreditAccountState.js");
|
|
23
24
|
const require_preview_preview_detectCloseOrRepay = require("./preview/detectCloseOrRepay.js");
|
|
@@ -77,3 +78,4 @@ exports.refuse = require_onchain_validation_refusal.refuse;
|
|
|
77
78
|
exports.replayInnerOperations = require_preview_preview_replayInnerOperations.replayInnerOperations;
|
|
78
79
|
exports.replayMulticall = require_preview_preview_replayMulticall.replayMulticall;
|
|
79
80
|
exports.resolveDelayedClaimIntent = require_preview_preview_detectDelayedClaim.resolveDelayedClaimIntent;
|
|
81
|
+
exports.unpriceableTokenError = require_preview_preview_errors.unpriceableTokenError;
|
|
@@ -5,6 +5,7 @@ const require_onchain_constants_math = require("../../onchain/constants/math.js"
|
|
|
5
5
|
const require_model_previews = require("../../model/previews.js");
|
|
6
6
|
require("../../model/index.js");
|
|
7
7
|
require("../../onchain/index.js");
|
|
8
|
+
const require_preview_preview_errors = require("./errors.js");
|
|
8
9
|
let viem = require("viem");
|
|
9
10
|
//#region src/preview/preview/buildDelayedStrategyPositionOperationPreview.ts
|
|
10
11
|
/**
|
|
@@ -13,8 +14,9 @@ let viem = require("viem");
|
|
|
13
14
|
* the claim itself followed by the intent-specific tail
|
|
14
15
|
*
|
|
15
16
|
* Pure function: the input states are never mutated and no network access is performed.
|
|
16
|
-
* Swaps are estimated with the injected conversion;
|
|
17
|
-
*
|
|
17
|
+
* Swaps are estimated with the injected conversion; remaining holdings are
|
|
18
|
+
* priced by `MarketSuite.valueInUnderlying`. Tokens that cannot be priced
|
|
19
|
+
* contribute nothing and set a non-fatal `ERROR_UNPRICEABLE_TOKEN` error on the
|
|
18
20
|
* preview.
|
|
19
21
|
*
|
|
20
22
|
* The changes (e.g. `totalDebtChange`) are reported relative to the account
|
|
@@ -51,10 +53,7 @@ function makeSafeConverter(convert) {
|
|
|
51
53
|
try {
|
|
52
54
|
return convert(token, to, amount);
|
|
53
55
|
} catch {
|
|
54
|
-
error ??=
|
|
55
|
-
code: require_model_previews.ERROR_UNPRICEABLE_TOKEN,
|
|
56
|
-
message: `cannot price token ${token}`
|
|
57
|
-
};
|
|
56
|
+
error ??= require_preview_preview_errors.unpriceableTokenError(token);
|
|
58
57
|
return 0n;
|
|
59
58
|
}
|
|
60
59
|
},
|
|
@@ -149,35 +148,36 @@ function repayFromClaim(post, claimToken, convert, amount) {
|
|
|
149
148
|
post.repay(received);
|
|
150
149
|
}
|
|
151
150
|
/**
|
|
152
|
-
* Oracle estimate of the account's total value in the underlying, ignoring
|
|
153
|
-
* balances at or below `dust`.
|
|
154
|
-
*/
|
|
155
|
-
function totalValueInUnderlying(post, convert, dust) {
|
|
156
|
-
return post.balances.sum((token, balance) => balance > dust ? convert(token, post.underlying, balance) : 0n);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
151
|
* `CLOSE_ACCOUNT` operation tail: everything is swapped into the
|
|
160
152
|
* underlying, the debt is repaid in full and the remainder is withdrawn to
|
|
161
153
|
* the user as `receivedToken`.
|
|
162
154
|
*/
|
|
163
155
|
function buildClosePreview(post, converter, receivedToken, sdk) {
|
|
164
|
-
const
|
|
165
|
-
const
|
|
156
|
+
const market = sdk.marketRegister.findByCreditManager(post.creditManager);
|
|
157
|
+
const priced = market.valueInUnderlying(post.balances.toAssets(), 0n);
|
|
158
|
+
const oracle = market.priceOracle;
|
|
166
159
|
const suite = sdk.marketRegister.findCreditManager(post.creditManager);
|
|
167
160
|
return {
|
|
168
161
|
operation: "CloseCreditAccount",
|
|
169
162
|
permanent: false,
|
|
170
|
-
...
|
|
163
|
+
...require_model_previews.asEstimated(sdk.positions.projection({
|
|
164
|
+
creditManager: post.creditManager,
|
|
165
|
+
assets: [],
|
|
166
|
+
quotas: [],
|
|
167
|
+
totalDebt: 0n,
|
|
168
|
+
totalValue: 0n
|
|
169
|
+
}, { availableLiquidityChange: post.totalDebt })),
|
|
171
170
|
creditAccount: post.creditAccount,
|
|
172
171
|
name: suite.accountStrategyName(post.creditAccount),
|
|
173
172
|
targetCollateral: suite.accountTargetCollateral(post.creditAccount),
|
|
174
|
-
receivedAmount: oracle.toTokenAmount(receivedToken, require_onchain_utils_bigint_math.BigIntMath.max(
|
|
175
|
-
error: converter.error
|
|
173
|
+
receivedAmount: oracle.toTokenAmount(receivedToken, require_onchain_utils_bigint_math.BigIntMath.max(priced.value - post.totalDebt, 0n)),
|
|
174
|
+
error: converter.error ?? (priced.unpriceable ? require_preview_preview_errors.unpriceableTokenError(priced.unpriceable) : void 0)
|
|
176
175
|
};
|
|
177
176
|
}
|
|
178
177
|
function buildAdjustPreview(post, before, collateralWithdrawn, converter, sdk) {
|
|
179
|
-
const snap = post.toSnapshot(totalValueInUnderlying(post, converter.convert, require_onchain_constants_math.DUST_THRESHOLD));
|
|
180
178
|
const market = sdk.marketRegister.findByCreditManager(post.creditManager);
|
|
179
|
+
const priced = market.valueInUnderlying(post.balances.toAssets());
|
|
180
|
+
const snap = post.toSnapshot(priced.value);
|
|
181
181
|
const suite = sdk.marketRegister.findCreditManager(post.creditManager);
|
|
182
182
|
const oracle = market.priceOracle;
|
|
183
183
|
return {
|
|
@@ -194,7 +194,7 @@ function buildAdjustPreview(post, before, collateralWithdrawn, converter, sdk) {
|
|
|
194
194
|
...oracle.toAmount(market.underlying, q.balance)
|
|
195
195
|
})),
|
|
196
196
|
assetsChange: post.balances.difference(before.balances).toAssets(require_onchain_constants_math.DUST_THRESHOLD).map((a) => oracle.toTokenAmount(a.token, a.balance)),
|
|
197
|
-
error: converter.error
|
|
197
|
+
error: converter.error ?? (priced.unpriceable ? require_preview_preview_errors.unpriceableTokenError(priced.unpriceable) : void 0)
|
|
198
198
|
};
|
|
199
199
|
}
|
|
200
200
|
//#endregion
|
|
@@ -1 +1,17 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_model_previews = require("../../model/previews.js");
|
|
3
|
+
require("../../model/index.js");
|
|
4
|
+
//#region src/preview/preview/errors.ts
|
|
5
|
+
/**
|
|
6
|
+
* Preview limitation (2xxx): the oracle could not price `token`. Callers
|
|
7
|
+
* attach this with `error ??=` so a malformed-transaction (1xxx) error
|
|
8
|
+
* already recorded keeps precedence.
|
|
9
|
+
**/
|
|
10
|
+
function unpriceableTokenError(token) {
|
|
11
|
+
return {
|
|
12
|
+
code: require_model_previews.ERROR_UNPRICEABLE_TOKEN,
|
|
13
|
+
message: `cannot price token ${token}`
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
exports.unpriceableTokenError = unpriceableTokenError;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_preview_preview_errors = require("./errors.js");
|
|
2
3
|
const require_preview_preview_buildDelayedStrategyPositionOperationPreview = require("./buildDelayedStrategyPositionOperationPreview.js");
|
|
3
4
|
const require_preview_preview_CreditAccountState = require("./CreditAccountState.js");
|
|
4
5
|
const require_preview_preview_detectCloseOrRepay = require("./detectCloseOrRepay.js");
|
|
5
6
|
const require_preview_preview_detectDelayedClaim = require("./detectDelayedClaim.js");
|
|
6
7
|
const require_preview_preview_detectDelayedOperation = require("./detectDelayedOperation.js");
|
|
7
|
-
require("./errors.js");
|
|
8
8
|
const require_preview_preview_estimateClaimableAt = require("./estimateClaimableAt.js");
|
|
9
9
|
const require_preview_preview_replayInnerOperations = require("./replayInnerOperations.js");
|
|
10
10
|
const require_preview_preview_replayMulticall = require("./replayMulticall.js");
|
|
@@ -25,3 +25,4 @@ exports.previewOperation = require_preview_preview_previewOperation.previewOpera
|
|
|
25
25
|
exports.replayInnerOperations = require_preview_preview_replayInnerOperations.replayInnerOperations;
|
|
26
26
|
exports.replayMulticall = require_preview_preview_replayMulticall.replayMulticall;
|
|
27
27
|
exports.resolveDelayedClaimIntent = require_preview_preview_detectDelayedClaim.resolveDelayedClaimIntent;
|
|
28
|
+
exports.unpriceableTokenError = require_preview_preview_errors.unpriceableTokenError;
|
|
@@ -4,6 +4,7 @@ const require_onchain_constants_math = require("../../onchain/constants/math.js"
|
|
|
4
4
|
const require_model_previews = require("../../model/previews.js");
|
|
5
5
|
require("../../model/index.js");
|
|
6
6
|
require("../../onchain/index.js");
|
|
7
|
+
const require_preview_preview_errors = require("./errors.js");
|
|
7
8
|
const require_preview_preview_replayMulticall = require("./replayMulticall.js");
|
|
8
9
|
const require_preview_preview_unwrapNativeCollateral = require("./unwrapNativeCollateral.js");
|
|
9
10
|
//#region src/preview/preview/previewAdjustStrategyPosition.ts
|
|
@@ -25,18 +26,9 @@ function previewAdjustStrategyPosition(input, operation, options) {
|
|
|
25
26
|
const { assets: collateralAdded, error: unwrapError } = require_preview_preview_unwrapNativeCollateral.unwrapNativeCollateral(after.collateralAdded.toAssets(), value, sdk.addressProvider.getAddress(require_onchain_constants_address_provider.AP_WETH_TOKEN, 0));
|
|
26
27
|
error ??= unwrapError;
|
|
27
28
|
const assetsChange = account.balances.difference(before.balances).toAssets(require_onchain_constants_math.DUST_THRESHOLD);
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} catch {
|
|
32
|
-
error ??= {
|
|
33
|
-
code: require_model_previews.ERROR_UNPRICEABLE_TOKEN,
|
|
34
|
-
message: `cannot price token ${token}`
|
|
35
|
-
};
|
|
36
|
-
return acc;
|
|
37
|
-
}
|
|
38
|
-
}, 0n);
|
|
39
|
-
const snap = account.toSnapshot(totalValue);
|
|
29
|
+
const priced = market.valueInUnderlying(account.balances.toAssets());
|
|
30
|
+
if (priced.unpriceable) error ??= require_preview_preview_errors.unpriceableTokenError(priced.unpriceable);
|
|
31
|
+
const snap = account.toSnapshot(priced.value);
|
|
40
32
|
return {
|
|
41
33
|
operation: "AdjustCreditAccount",
|
|
42
34
|
...require_model_previews.asEstimated(sdk.positions.projection(snap, { availableLiquidityChange: before.totalDebt - account.totalDebt })),
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_onchain_constants_address_provider = require("../../onchain/constants/address-provider.js");
|
|
3
3
|
require("../../onchain/constants/math.js");
|
|
4
|
+
const require_model_previews = require("../../model/previews.js");
|
|
5
|
+
require("../../model/index.js");
|
|
4
6
|
require("../../onchain/index.js");
|
|
7
|
+
const require_preview_preview_errors = require("./errors.js");
|
|
5
8
|
const require_preview_preview_detectCloseOrRepay = require("./detectCloseOrRepay.js");
|
|
6
9
|
const require_preview_preview_replayMulticall = require("./replayMulticall.js");
|
|
7
10
|
const require_preview_preview_unwrapNativeCollateral = require("./unwrapNativeCollateral.js");
|
|
@@ -23,7 +26,11 @@ function previewExitOrRepayStrategyPosition(input, operation, permanent, options
|
|
|
23
26
|
function previewCloseCreditAccount(input, operation, permanent, replay) {
|
|
24
27
|
const { sdk } = input;
|
|
25
28
|
const market = sdk.marketRegister.findByCreditManager(operation.creditManager);
|
|
26
|
-
const { after, error } = replay;
|
|
29
|
+
const { before, after, error: replayError } = replay;
|
|
30
|
+
const account = after.account;
|
|
31
|
+
let error = replayError;
|
|
32
|
+
const priced = market.valueInUnderlying(account.balances.toAssets());
|
|
33
|
+
if (priced.unpriceable) error ??= require_preview_preview_errors.unpriceableTokenError(priced.unpriceable);
|
|
27
34
|
const suite = sdk.marketRegister.findCreditManager(operation.creditManager);
|
|
28
35
|
let receivedToken = market.underlying;
|
|
29
36
|
for (const m of operation.multicall) if (m.operation === "WithdrawCollateral" && m.amount === 115792089237316195423570985008687907853269984665640564039457584007913129639935n) {
|
|
@@ -33,7 +40,7 @@ function previewCloseCreditAccount(input, operation, permanent, replay) {
|
|
|
33
40
|
return {
|
|
34
41
|
operation: "CloseCreditAccount",
|
|
35
42
|
permanent,
|
|
36
|
-
...
|
|
43
|
+
...require_model_previews.asEstimated(sdk.positions.projection(account.toSnapshot(priced.value), { availableLiquidityChange: before.totalDebt - account.totalDebt })),
|
|
37
44
|
creditAccount: operation.creditAccount,
|
|
38
45
|
name: suite.accountStrategyName(operation.creditAccount),
|
|
39
46
|
targetCollateral: suite.accountTargetCollateral(operation.creditAccount),
|
|
@@ -50,18 +57,21 @@ function previewRepayCreditAccount(input, operation, permanent, replay) {
|
|
|
50
57
|
const { sdk, value = 0n } = input;
|
|
51
58
|
const market = sdk.marketRegister.findByCreditManager(operation.creditManager);
|
|
52
59
|
const { before, after, error: replayError } = replay;
|
|
60
|
+
const account = after.account;
|
|
53
61
|
const { assets: collateralAdded, error: unwrapError } = require_preview_preview_unwrapNativeCollateral.unwrapNativeCollateral(after.collateralAdded.toAssets(), value, sdk.addressProvider.getAddress(require_onchain_constants_address_provider.AP_WETH_TOKEN, 0));
|
|
54
|
-
|
|
62
|
+
let error = replayError ?? unwrapError;
|
|
63
|
+
const priced = market.valueInUnderlying(account.balances.toAssets());
|
|
64
|
+
if (priced.unpriceable) error ??= require_preview_preview_errors.unpriceableTokenError(priced.unpriceable);
|
|
55
65
|
const suite = sdk.marketRegister.findCreditManager(operation.creditManager);
|
|
56
66
|
return {
|
|
57
67
|
operation: "RepayCreditAccount",
|
|
58
68
|
permanent,
|
|
59
|
-
...
|
|
69
|
+
...require_model_previews.asEstimated(sdk.positions.projection(account.toSnapshot(priced.value), { availableLiquidityChange: before.totalDebt - account.totalDebt })),
|
|
60
70
|
creditAccount: operation.creditAccount,
|
|
61
71
|
name: suite.accountStrategyName(operation.creditAccount),
|
|
62
72
|
targetCollateral: suite.accountTargetCollateral(operation.creditAccount),
|
|
63
73
|
collateralAdded: collateralAdded.map((a) => market.priceOracle.toTokenAmount(a.token, a.balance)),
|
|
64
|
-
debtRepaid: market.toUnderlyingAmount(before.totalDebt -
|
|
74
|
+
debtRepaid: market.toUnderlyingAmount(before.totalDebt - account.totalDebt),
|
|
65
75
|
collateralWithdrawn: after.collateralWithdrawn.toAssets().map((a) => market.priceOracle.toTokenAmount(a.token, a.balance)),
|
|
66
76
|
error
|
|
67
77
|
};
|
|
@@ -1,29 +1,48 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_abi_iERC20 = require("../../abi/iERC20.js");
|
|
2
3
|
const require_model_result = require("../../model/result.js");
|
|
3
4
|
require("../../model/index.js");
|
|
5
|
+
const require_preview_simulate_errors = require("../simulate/errors.js");
|
|
4
6
|
const require_preview_simulate_simulatePoolOperation = require("../simulate/simulatePoolOperation.js");
|
|
5
|
-
require("../simulate/index.js");
|
|
6
7
|
//#region src/preview/preview/previewPoolPositionOperation.ts
|
|
7
8
|
async function previewPoolPositionOperation(input, operation, options) {
|
|
8
|
-
const { sdk
|
|
9
|
+
const { sdk } = input;
|
|
9
10
|
const { tokenIn, tokenOut } = operation;
|
|
10
11
|
const market = sdk.marketRegister.findByPool(operation.pool);
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
const pool = market.pool.pool;
|
|
13
|
+
const holder = "owner" in operation ? operation.owner : operation.receiver;
|
|
14
|
+
let previewAmount;
|
|
15
|
+
let shares;
|
|
16
|
+
try {
|
|
17
|
+
[previewAmount, shares] = await sdk.client.multicall({
|
|
18
|
+
contracts: [require_preview_simulate_simulatePoolOperation.previewContract(operation), {
|
|
19
|
+
address: operation.pool,
|
|
20
|
+
abi: require_abi_iERC20.ierc20Abi,
|
|
21
|
+
functionName: "balanceOf",
|
|
22
|
+
args: [holder]
|
|
23
|
+
}],
|
|
24
|
+
allowFailure: false,
|
|
25
|
+
batchSize: 0,
|
|
26
|
+
blockNumber: options?.blockNumber
|
|
27
|
+
});
|
|
28
|
+
} catch (cause) {
|
|
29
|
+
const error = require_preview_simulate_errors.asPreviewSimulationError(cause, "multicall");
|
|
30
|
+
options?.logger?.error(error, "pool operation simulation failed");
|
|
31
|
+
return require_model_result.sdkErr(error);
|
|
32
|
+
}
|
|
33
|
+
const sim = require_preview_simulate_simulatePoolOperation.amountsInOut(operation, previewAmount);
|
|
34
|
+
const inflow = operation.operation === "Deposit" || operation.operation === "Mint";
|
|
35
|
+
const after = shares + (inflow ? sim.amountOut : -sim.amountIn);
|
|
19
36
|
return require_model_result.sdkOk({
|
|
20
37
|
operation: operation.operation,
|
|
21
38
|
pool: operation.pool,
|
|
22
39
|
name: sdk.tokensMeta.mustGetToken(operation.pool).name,
|
|
23
40
|
underlyingToken: market.underlyingToken,
|
|
24
|
-
shareRate:
|
|
41
|
+
shareRate: pool.dieselRate,
|
|
25
42
|
tokenIn: market.priceOracle.toTokenAmount(tokenIn, sim.amountIn),
|
|
26
|
-
tokenOut: market.priceOracle.toTokenAmount(tokenOut, sim.amountOut)
|
|
43
|
+
tokenOut: market.priceOracle.toTokenAmount(tokenOut, sim.amountOut),
|
|
44
|
+
curator: market.curator,
|
|
45
|
+
netValue: market.toUnderlyingAmount(pool.sharesToUnderlying(after > 0n ? after : 0n))
|
|
27
46
|
});
|
|
28
47
|
}
|
|
29
48
|
//#endregion
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_preview_simulate_errors = require("./errors.js");
|
|
3
|
-
const require_preview_simulate_simulateFacadeOperation = require("./simulateFacadeOperation.js");
|
|
4
3
|
const require_preview_simulate_simulatePoolOperation = require("./simulatePoolOperation.js");
|
|
4
|
+
const require_preview_simulate_simulateFacadeOperation = require("./simulateFacadeOperation.js");
|
|
5
5
|
const require_preview_simulate_simulateRWAOperation = require("./simulateRWAOperation.js");
|
|
6
6
|
const require_preview_simulate_simulateOperation = require("./simulateOperation.js");
|
|
7
7
|
exports.asPreviewSimulationError = require_preview_simulate_errors.asPreviewSimulationError;
|
|
@@ -3,8 +3,8 @@ const require_model_result = require("../../model/result.js");
|
|
|
3
3
|
require("../../model/index.js");
|
|
4
4
|
const require_preview_parse_types = require("../parse/types.js");
|
|
5
5
|
require("../parse/index.js");
|
|
6
|
-
const require_preview_simulate_simulateFacadeOperation = require("./simulateFacadeOperation.js");
|
|
7
6
|
const require_preview_simulate_simulatePoolOperation = require("./simulatePoolOperation.js");
|
|
7
|
+
const require_preview_simulate_simulateFacadeOperation = require("./simulateFacadeOperation.js");
|
|
8
8
|
const require_preview_simulate_simulateRWAOperation = require("./simulateRWAOperation.js");
|
|
9
9
|
//#region src/preview/simulate/simulateOperation.ts
|
|
10
10
|
/**
|
|
@@ -552,14 +552,13 @@ function routed(result, at) {
|
|
|
552
552
|
* a screen can show.
|
|
553
553
|
**/
|
|
554
554
|
async function lpState(sdk, pool, wallet, simulation, moved) {
|
|
555
|
-
const
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
}) + (moved.mints ?? -moved.burns);
|
|
555
|
+
const market = sdk.marketRegister.findByPool(pool);
|
|
556
|
+
const poolContract = market.pool.pool;
|
|
557
|
+
const after = await poolContract.getShareBalance(wallet) + (moved.mints ?? -moved.burns);
|
|
559
558
|
return {
|
|
560
559
|
...simulation,
|
|
561
|
-
curator:
|
|
562
|
-
|
|
560
|
+
curator: market.curator,
|
|
561
|
+
netValue: market.toUnderlyingAmount(poolContract.sharesToUnderlying(after > 0n ? after : 0n))
|
|
563
562
|
};
|
|
564
563
|
}
|
|
565
564
|
/**
|
|
@@ -2,6 +2,7 @@ import "../../../constants/math.js";
|
|
|
2
2
|
import "../../../constants/index.js";
|
|
3
3
|
import { calcMaxLeverage, usdToNumber } from "../../../market/math.js";
|
|
4
4
|
import { CreditSuite } from "../../../market/credit/CreditSuite.js";
|
|
5
|
+
import { MarketSuite } from "../../../market/MarketSuite.js";
|
|
5
6
|
import { PositionsService } from "../../../positions/PositionsService.js";
|
|
6
7
|
import { vi } from "vitest";
|
|
7
8
|
//#region src/onchain/accounts/intents/testing/sdk-mock.ts
|
|
@@ -221,6 +222,7 @@ function buildMockSdk(args) {
|
|
|
221
222
|
underlying: args.underlying
|
|
222
223
|
}
|
|
223
224
|
};
|
|
225
|
+
Object.assign(market, { valueInUnderlying: MarketSuite.prototype.valueInUnderlying });
|
|
224
226
|
const collateralTokens = [args.underlying.toLowerCase(), ...Object.keys(args.liquidationThresholds).map((t) => t.toLowerCase()).filter((t) => t !== args.underlying.toLowerCase())];
|
|
225
227
|
const forbidden = new Set((args.forbiddenTokens ?? []).map((t) => t.toLowerCase()));
|
|
226
228
|
const forbiddenTokensMask = collateralTokens.reduce((mask, token, i) => forbidden.has(token) ? mask | 1n << BigInt(i) : mask, 0n);
|