@gearbox-protocol/sdk 14.12.0-next.71 → 14.12.0-next.72
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/model/history.js +25 -0
- package/dist/cjs/model/history.schema.js +45 -1
- package/dist/cjs/model/index.js +17 -3
- package/dist/cjs/model/positions.js +89 -0
- package/dist/cjs/model/positions.schema.js +28 -0
- package/dist/cjs/new-sdk/GearboxSDK.js +7 -0
- package/dist/cjs/new-sdk/index.js +3 -0
- package/dist/cjs/new-sdk/positions/PositionsNamespace.js +119 -0
- package/dist/cjs/new-sdk/positions/index.js +4 -0
- package/dist/cjs/new-sdk/positions/types.js +1 -0
- package/dist/cjs/offchain/GearboxAPI.js +9 -2
- package/dist/cjs/offchain/index.js +5 -2
- package/dist/cjs/offchain/opportunities/OffchainOpportunities.js +3 -14
- package/dist/cjs/offchain/opportunities/index.js +0 -1
- package/dist/cjs/offchain/positions/OffchainPositions.js +69 -0
- package/dist/cjs/offchain/positions/index.js +3 -0
- package/dist/cjs/offchain/types.js +17 -0
- package/dist/cjs/sdk/MultichainSDK.js +7 -0
- package/dist/cjs/sdk/OnchainSDK.js +7 -0
- package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +84 -0
- package/dist/cjs/sdk/accounts/constants.js +12 -0
- package/dist/cjs/sdk/accounts/dominantCollateral.js +33 -0
- package/dist/cjs/sdk/accounts/index.js +4 -1
- package/dist/cjs/sdk/accounts/liquidations/LiquidationsService.js +3 -10
- package/dist/cjs/sdk/accounts/liquidations/constants.js +2 -6
- package/dist/cjs/sdk/accounts/liquidations/index.js +2 -1
- package/dist/cjs/sdk/index.js +11 -1
- package/dist/cjs/sdk/market/MarketSuite.js +7 -1
- package/dist/cjs/sdk/market/credit/CreditSuite.js +10 -1
- package/dist/cjs/sdk/market/math.js +37 -0
- package/dist/cjs/sdk/opportunities/index.js +2 -0
- package/dist/cjs/sdk/pools/PoolService.js +37 -0
- package/dist/cjs/sdk/positions/MultichainPositionsService.js +48 -0
- package/dist/cjs/sdk/positions/PositionsService.js +39 -0
- package/dist/cjs/sdk/positions/index.js +6 -0
- package/dist/cjs/sdk/positions/types.js +1 -0
- package/dist/esm/model/history.js +24 -1
- package/dist/esm/model/history.schema.js +42 -2
- package/dist/esm/model/index.js +6 -6
- package/dist/esm/model/positions.js +85 -1
- package/dist/esm/model/positions.schema.js +26 -1
- package/dist/esm/new-sdk/GearboxSDK.js +7 -0
- package/dist/esm/new-sdk/index.js +3 -1
- package/dist/esm/new-sdk/positions/PositionsNamespace.js +118 -0
- package/dist/esm/new-sdk/positions/index.js +3 -0
- package/dist/esm/new-sdk/positions/types.js +1 -0
- package/dist/esm/offchain/GearboxAPI.js +9 -2
- package/dist/esm/offchain/index.js +5 -3
- package/dist/esm/offchain/opportunities/OffchainOpportunities.js +2 -12
- package/dist/esm/offchain/opportunities/index.js +2 -2
- package/dist/esm/offchain/positions/OffchainPositions.js +68 -0
- package/dist/esm/offchain/positions/index.js +2 -0
- package/dist/esm/offchain/types.js +17 -1
- package/dist/esm/sdk/MultichainSDK.js +7 -0
- package/dist/esm/sdk/OnchainSDK.js +7 -0
- package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +84 -0
- package/dist/esm/sdk/accounts/constants.js +11 -0
- package/dist/esm/sdk/accounts/dominantCollateral.js +32 -0
- package/dist/esm/sdk/accounts/index.js +4 -2
- package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +3 -10
- package/dist/esm/sdk/accounts/liquidations/constants.js +1 -5
- package/dist/esm/sdk/accounts/liquidations/index.js +2 -1
- package/dist/esm/sdk/index.js +8 -3
- package/dist/esm/sdk/market/MarketSuite.js +7 -1
- package/dist/esm/sdk/market/credit/CreditSuite.js +10 -1
- package/dist/esm/sdk/market/math.js +37 -2
- package/dist/esm/sdk/opportunities/index.js +2 -2
- package/dist/esm/sdk/pools/PoolService.js +37 -0
- package/dist/esm/sdk/positions/MultichainPositionsService.js +47 -0
- package/dist/esm/sdk/positions/PositionsService.js +38 -0
- package/dist/esm/sdk/positions/index.js +4 -0
- package/dist/esm/sdk/positions/types.js +1 -0
- package/dist/types/model/history.d.ts +50 -2
- package/dist/types/model/history.schema.d.ts +32 -3
- package/dist/types/model/index.d.ts +5 -5
- package/dist/types/model/positions.d.ts +100 -1
- package/dist/types/model/positions.schema.d.ts +29 -1
- package/dist/types/new-sdk/AbstractNamespace.d.ts +2 -2
- package/dist/types/new-sdk/GearboxSDK.d.ts +6 -0
- package/dist/types/new-sdk/index.d.ts +4 -1
- package/dist/types/new-sdk/opportunities/OpportunitiesNamespace.d.ts +1 -1
- package/dist/types/new-sdk/positions/PositionsNamespace.d.ts +62 -0
- package/dist/types/new-sdk/positions/index.d.ts +3 -0
- package/dist/types/new-sdk/positions/types.d.ts +62 -0
- package/dist/types/new-sdk/utils/history.d.ts +6 -2
- package/dist/types/offchain/GearboxAPI.d.ts +8 -2
- package/dist/types/offchain/index.d.ts +5 -3
- package/dist/types/offchain/opportunities/OffchainOpportunities.d.ts +1 -9
- package/dist/types/offchain/opportunities/index.d.ts +2 -2
- package/dist/types/offchain/positions/OffchainPositions.d.ts +47 -0
- package/dist/types/offchain/positions/index.d.ts +2 -0
- package/dist/types/offchain/types.d.ts +12 -1
- package/dist/types/sdk/MultichainSDK.d.ts +6 -0
- package/dist/types/sdk/OnchainSDK.d.ts +6 -0
- package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +7 -1
- package/dist/types/sdk/accounts/constants.d.ts +11 -0
- package/dist/types/sdk/accounts/dominantCollateral.d.ts +22 -0
- package/dist/types/sdk/accounts/index.d.ts +5 -3
- package/dist/types/sdk/accounts/liquidations/MultichainLiquidationsService.d.ts +2 -2
- package/dist/types/sdk/accounts/liquidations/constants.d.ts +1 -5
- package/dist/types/sdk/accounts/liquidations/index.d.ts +2 -1
- package/dist/types/sdk/accounts/liquidations/types.d.ts +1 -1
- package/dist/types/sdk/accounts/types.d.ts +26 -1
- package/dist/types/sdk/base/TokensMeta.d.ts +1 -1
- package/dist/types/sdk/index.d.ts +11 -5
- package/dist/types/sdk/market/MarketConfiguratorContract.d.ts +1 -1
- package/dist/types/sdk/market/MarketSuite.d.ts +5 -1
- package/dist/types/sdk/market/credit/CreditManagerV310Contract.d.ts +1 -1
- package/dist/types/sdk/market/credit/CreditSuite.d.ts +8 -1
- package/dist/types/sdk/market/credit/types.d.ts +1 -1
- package/dist/types/sdk/market/math.d.ts +29 -1
- package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +2 -2
- package/dist/types/sdk/market/oracle/types.d.ts +2 -2
- package/dist/types/sdk/market/pool/LinearInterestRateModelContract.d.ts +1 -1
- package/dist/types/sdk/market/pool/PoolQuotaKeeperV310Contract.d.ts +1 -1
- package/dist/types/sdk/market/pool/PoolSuite.d.ts +1 -1
- package/dist/types/sdk/market/pool/PoolV310Contract.d.ts +1 -1
- package/dist/types/sdk/market/pool/types.d.ts +1 -1
- package/dist/types/sdk/market/pricefeeds/AbstractPriceFeed.d.ts +1 -1
- package/dist/types/sdk/market/pricefeeds/types.d.ts +1 -1
- package/dist/types/sdk/opportunities/MultichainOpportunitiesService.d.ts +2 -2
- package/dist/types/sdk/opportunities/index.d.ts +2 -2
- package/dist/types/sdk/pools/PoolService.d.ts +7 -1
- package/dist/types/sdk/pools/index.d.ts +2 -2
- package/dist/types/sdk/pools/types.d.ts +18 -1
- package/dist/types/sdk/positions/MultichainPositionsService.d.ts +33 -0
- package/dist/types/sdk/positions/PositionsService.d.ts +22 -0
- package/dist/types/sdk/positions/index.d.ts +4 -0
- package/dist/types/sdk/positions/types.d.ts +25 -0
- package/package.json +1 -1
|
@@ -17,10 +17,13 @@ import { hexEq } from "../utils/hex.js";
|
|
|
17
17
|
import "../utils/index.js";
|
|
18
18
|
import { SDKConstruct } from "../base/SDKConstruct.js";
|
|
19
19
|
import "../base/index.js";
|
|
20
|
+
import { borrowApyBps, healthFactorBps, positionLeverage, usdToNumber } from "../market/math.js";
|
|
20
21
|
import { simulateWithPriceUpdates } from "../utils/viem/simulateWithPriceUpdates.js";
|
|
21
22
|
import "../utils/viem/index.js";
|
|
22
23
|
import { getRawPriceUpdates } from "../market/pricefeeds/getRawPriceUpdates.js";
|
|
23
24
|
import "../market/index.js";
|
|
25
|
+
import "./constants.js";
|
|
26
|
+
import { dominantCollateral } from "./dominantCollateral.js";
|
|
24
27
|
import { extractPriceUpdates, extractQuotaTokens, mergePriceUpdates } from "./multicall-utils.js";
|
|
25
28
|
import { encodeFunctionData, getContract } from "viem";
|
|
26
29
|
//#region src/sdk/accounts/CreditAccountsServiceV310.ts
|
|
@@ -218,6 +221,87 @@ var CreditAccountsServiceV310 = class extends SDKConstruct {
|
|
|
218
221
|
return filtered.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
219
222
|
}
|
|
220
223
|
/**
|
|
224
|
+
* {@inheritDoc ICreditAccountsService.listPositions}
|
|
225
|
+
**/
|
|
226
|
+
async listPositions(props) {
|
|
227
|
+
const { owner, includeZeroDebt } = props;
|
|
228
|
+
const [accounts] = await Promise.all([this.getBorrowerCreditAccounts(owner, { includeZeroDebt }), this.sdk.withdrawalCompressor?.loadWithdrawableAssets()]);
|
|
229
|
+
const describable = accounts.filter((ca) => {
|
|
230
|
+
if (!ca.success) this.logger?.warn(`cannot describe position of ${this.labelAddress(ca.creditAccount)}: collateral computation failed`);
|
|
231
|
+
return ca.success;
|
|
232
|
+
});
|
|
233
|
+
const withdrawals = await Promise.all(describable.map((ca) => this.#accountWithdrawals(ca)));
|
|
234
|
+
return describable.map((ca, i) => this.#strategyPosition(ca, withdrawals[i] ?? new AddressMap()));
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Builds one strategy position from an account snapshot.
|
|
238
|
+
*
|
|
239
|
+
* @param withdrawals - Delayed withdrawals of the account, keyed by the
|
|
240
|
+
* phantom token that represents them on it.
|
|
241
|
+
**/
|
|
242
|
+
#strategyPosition(ca, withdrawals) {
|
|
243
|
+
const suite = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
244
|
+
const { market } = suite;
|
|
245
|
+
const { priceOracle } = market;
|
|
246
|
+
const { pool } = market.pool;
|
|
247
|
+
const token = this.sdk.tokensMeta.mustGetToken(market.unwrappedUnderlying);
|
|
248
|
+
const totalDebtValue = ca.debt + ca.accruedInterest + ca.accruedFees;
|
|
249
|
+
const collateral = dominantCollateral(ca, market);
|
|
250
|
+
return {
|
|
251
|
+
kind: "strategy",
|
|
252
|
+
chainId: this.sdk.chainId,
|
|
253
|
+
creditManager: ca.creditManager,
|
|
254
|
+
creditAccount: ca.creditAccount,
|
|
255
|
+
name: collateral ? suite.strategyName(collateral) : token.symbol,
|
|
256
|
+
targetCollateral: collateral ? this.sdk.tokensMeta.mustGetToken(collateral) : null,
|
|
257
|
+
leverage: positionLeverage(totalDebtValue, ca.totalValue),
|
|
258
|
+
borrowApy: borrowApyBps(pool.baseInterestRate, suite.creditManager.feeInterest),
|
|
259
|
+
totalDebt: {
|
|
260
|
+
token,
|
|
261
|
+
value: totalDebtValue,
|
|
262
|
+
valueUsd: usdToNumber(ca.totalDebtUSD)
|
|
263
|
+
},
|
|
264
|
+
totalValue: {
|
|
265
|
+
token,
|
|
266
|
+
value: ca.totalValue,
|
|
267
|
+
valueUsd: usdToNumber(ca.totalValueUSD)
|
|
268
|
+
},
|
|
269
|
+
healthFactor: healthFactorBps(ca.healthFactor),
|
|
270
|
+
collaterals: ca.tokens.flatMap((t) => {
|
|
271
|
+
if ((t.mask & ca.enabledTokensMask) === 0n || t.balance <= 10n) return [];
|
|
272
|
+
return [{
|
|
273
|
+
collateral: priceOracle.toTokenAmount(t.token, t.balance),
|
|
274
|
+
quota: priceOracle.toTokenAmount(market.underlying, t.quota),
|
|
275
|
+
withdrawals: withdrawals.get(t.token) ?? []
|
|
276
|
+
}];
|
|
277
|
+
})
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Delayed withdrawals of one account, keyed by the phantom token that
|
|
282
|
+
* represents them on it, so that each collateral row can pick up its own.
|
|
283
|
+
**/
|
|
284
|
+
async #accountWithdrawals(ca) {
|
|
285
|
+
const compressor = this.sdk.withdrawalCompressor;
|
|
286
|
+
const byPhantomToken = new AddressMap(void 0, "accountWithdrawals");
|
|
287
|
+
const holdsPhantomToken = ca.tokens.some((t) => t.balance > 10n && compressor?.getWithdrawalSourceToken(t.token) !== void 0);
|
|
288
|
+
if (!compressor || !holdsPhantomToken) return byPhantomToken;
|
|
289
|
+
const { priceOracle } = this.sdk.marketRegister.findByCreditManager(ca.creditManager);
|
|
290
|
+
const { claimable, pending } = await compressor.getCurrentWithdrawals(ca.creditAccount);
|
|
291
|
+
const add = (w, outputs, claimableAt) => {
|
|
292
|
+
const assets = outputs.map((o) => ({
|
|
293
|
+
isDelayed: true,
|
|
294
|
+
...priceOracle.toTokenAmount(o.token, o.amount),
|
|
295
|
+
redeemer: w.redeemer,
|
|
296
|
+
claimableAt: claimableAt === void 0 ? void 0 : Number(claimableAt)
|
|
297
|
+
}));
|
|
298
|
+
byPhantomToken.upsert(w.withdrawalPhantomToken, [...byPhantomToken.get(w.withdrawalPhantomToken) ?? [], ...assets]);
|
|
299
|
+
};
|
|
300
|
+
for (const w of claimable) add(w, w.outputs);
|
|
301
|
+
for (const w of pending) add(w, w.expectedOutputs, w.claimableAt);
|
|
302
|
+
return byPhantomToken;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
221
305
|
* {@inheritDoc ICreditAccountsService.getRewards}
|
|
222
306
|
**/
|
|
223
307
|
async getRewards(creditAccount) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/sdk/accounts/constants.ts
|
|
2
|
+
/**
|
|
3
|
+
* Token balances at or below this threshold are treated as dust and ignored,
|
|
4
|
+
* consistent with the rest of the SDK (see `filterDust`).
|
|
5
|
+
*
|
|
6
|
+
* Shared by every service that describes what a credit account holds, so that
|
|
7
|
+
* a liquidation row and a position row agree on which balances exist at all.
|
|
8
|
+
**/
|
|
9
|
+
const DUST_THRESHOLD = 10n;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { DUST_THRESHOLD };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { hexEq } from "../utils/hex.js";
|
|
2
|
+
import "../utils/index.js";
|
|
3
|
+
import "./constants.js";
|
|
4
|
+
//#region src/sdk/accounts/dominantCollateral.ts
|
|
5
|
+
/**
|
|
6
|
+
* The account's dominant collateral: the most valuable enabled non-underlying
|
|
7
|
+
* token it holds above dust, by USD value.
|
|
8
|
+
*
|
|
9
|
+
* This is the single definition of "what this account is a position in".
|
|
10
|
+
* Using onchain-only data we can only determine at the time of the call (without
|
|
11
|
+
* unreasably difficult calls)
|
|
12
|
+
*
|
|
13
|
+
* @param account - Account to inspect.
|
|
14
|
+
* @param market - Market of the account, whose oracle prices the candidates.
|
|
15
|
+
* @returns The dominant collateral, or `undefined` when the account holds
|
|
16
|
+
* nothing but its underlying, or nothing the oracle can price.
|
|
17
|
+
**/
|
|
18
|
+
function dominantCollateral(account, market) {
|
|
19
|
+
let bestValue = 0;
|
|
20
|
+
let dominant;
|
|
21
|
+
for (const t of account.tokens) {
|
|
22
|
+
if (hexEq(t.token, account.underlying) || (t.mask & account.enabledTokensMask) === 0n || t.balance <= 10n) continue;
|
|
23
|
+
const value = market.priceOracle.safeUsdValue(t.token, t.balance) ?? 0;
|
|
24
|
+
if (value > bestValue) {
|
|
25
|
+
bestValue = value;
|
|
26
|
+
dominant = t.token;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return dominant;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { dominantCollateral };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { DUST_THRESHOLD } from "./constants.js";
|
|
2
|
+
import { dominantCollateral } from "./dominantCollateral.js";
|
|
1
3
|
import { CreditAccountsServiceV310 } from "./CreditAccountsServiceV310.js";
|
|
2
4
|
import { primaryInstantOutput } from "./intents/operations/claim-delayed/index.js";
|
|
3
5
|
import { CreditAccountOperationsService } from "./intents/index.js";
|
|
4
|
-
import {
|
|
6
|
+
import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./liquidations/constants.js";
|
|
5
7
|
import { LiquidationsService } from "./liquidations/LiquidationsService.js";
|
|
6
8
|
import { MultichainLiquidationsService } from "./liquidations/MultichainLiquidationsService.js";
|
|
7
9
|
import "./liquidations/index.js";
|
|
@@ -18,4 +20,4 @@ import { toWithdrawalStatus } from "./withdrawal-compressor/types.js";
|
|
|
18
20
|
import { WithdrawalCompressorV313Contract } from "./withdrawal-compressor/WithdrawalCompressorV313Contract.js";
|
|
19
21
|
import { createWithdrawalCompressor } from "./withdrawal-compressor/createWithdrawalCompressor.js";
|
|
20
22
|
import "./withdrawal-compressor/index.js";
|
|
21
|
-
export { AbstractWithdrawalCompressorContract, CreditAccountOperationsService, CreditAccountsServiceV310, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, DUST_THRESHOLD, InvalidDelayedIntentError, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService, RedemptionLoggerV310Contract, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, encodeDelayedIntent, getWithdrawalCompressorAddress, iCreditAccountAbi, primaryInstantOutput, toClaimableWithdrawal, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
|
|
23
|
+
export { AbstractWithdrawalCompressorContract, CreditAccountOperationsService, CreditAccountsServiceV310, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, DUST_THRESHOLD, InvalidDelayedIntentError, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService, RedemptionLoggerV310Contract, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, dominantCollateral, encodeDelayedIntent, getWithdrawalCompressorAddress, iCreditAccountAbi, primaryInstantOutput, toClaimableWithdrawal, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
|
|
@@ -17,6 +17,8 @@ import "../../market/rwa/midas/index.js";
|
|
|
17
17
|
import { RWA_LIQUIDATOR_SECURITIZE } from "../../market/rwa/securitize/constants.js";
|
|
18
18
|
import { SecuritizeLiquidatorContract } from "../../market/rwa/securitize/SecuritizeLiquidatorContract.js";
|
|
19
19
|
import "../../market/rwa/securitize/index.js";
|
|
20
|
+
import "../constants.js";
|
|
21
|
+
import { dominantCollateral } from "../dominantCollateral.js";
|
|
20
22
|
import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./constants.js";
|
|
21
23
|
//#region src/sdk/accounts/liquidations/LiquidationsService.ts
|
|
22
24
|
/**
|
|
@@ -279,16 +281,7 @@ var LiquidationsService = class extends SDKConstruct {
|
|
|
279
281
|
};
|
|
280
282
|
}
|
|
281
283
|
#mainAsset(ca, market, fallback) {
|
|
282
|
-
|
|
283
|
-
let asset;
|
|
284
|
-
for (const t of ca.tokens) {
|
|
285
|
-
if (hexEq(t.token, ca.underlying) || (t.mask & ca.enabledTokensMask) === 0n || t.balance <= 10n) continue;
|
|
286
|
-
const value = market.priceOracle.safeUsdValue(t.token, t.balance) ?? 0;
|
|
287
|
-
if (value > bestValue) {
|
|
288
|
-
bestValue = value;
|
|
289
|
-
asset = t.token;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
284
|
+
const asset = dominantCollateral(ca, market);
|
|
292
285
|
if (!asset) return fallback;
|
|
293
286
|
return this.sdk.withdrawalCompressor?.getWithdrawalSourceToken(asset) ?? asset;
|
|
294
287
|
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
+
import { DUST_THRESHOLD } from "../constants.js";
|
|
1
2
|
//#region src/sdk/accounts/liquidations/constants.ts
|
|
2
3
|
const LIQUIDATION_COMPRESSOR_V313_ADDRESS = "0xB70C4500a0afF02107eB983a348F22492fB6dC94";
|
|
3
4
|
/**
|
|
4
|
-
* Token balances at or below this threshold are treated as dust and ignored,
|
|
5
|
-
* consistent with the rest of the SDK (see `filterDust`).
|
|
6
|
-
**/
|
|
7
|
-
const DUST_THRESHOLD = 10n;
|
|
8
|
-
/**
|
|
9
5
|
* Headroom (in bps) added on top of the amount the liquidation pulls when
|
|
10
6
|
* building the liquidator's approval, so that the transaction does not revert
|
|
11
7
|
* when prices move between the preview and the execution.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { DUST_THRESHOLD
|
|
1
|
+
import { DUST_THRESHOLD } from "../constants.js";
|
|
2
|
+
import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./constants.js";
|
|
2
3
|
import { LiquidationsService } from "./LiquidationsService.js";
|
|
3
4
|
import { MultichainLiquidationsService } from "./MultichainLiquidationsService.js";
|
|
4
5
|
import "./types.js";
|
package/dist/esm/sdk/index.js
CHANGED
|
@@ -47,7 +47,7 @@ import { createAdapter } from "./market/adapters/createAdapter.js";
|
|
|
47
47
|
import { CreditConfiguratorV310Contract } from "./market/credit/CreditConfiguratorV310Contract.js";
|
|
48
48
|
import { CreditFacadeV310BaseContract, creditFacadeV310Abi as abi } from "./market/credit/CreditFacadeV310BaseContract.js";
|
|
49
49
|
import { CreditFacadeV310Contract } from "./market/credit/CreditFacadeV310Contract.js";
|
|
50
|
-
import { additionalBorrowApyBps, borrowApyBps, maxLeverage, rayToBps, usdToNumber, utilizationBps } from "./market/math.js";
|
|
50
|
+
import { additionalBorrowApyBps, borrowApyBps, healthFactorBps, maxLeverage, positionLeverage, rayToBps, usdToNumber, utilizationBps } from "./market/math.js";
|
|
51
51
|
import { CreditManagerV310Contract } from "./market/credit/CreditManagerV310Contract.js";
|
|
52
52
|
import { CreditSuite } from "./market/credit/CreditSuite.js";
|
|
53
53
|
import { simulateMulticall } from "./utils/viem/simulateMulticall.js";
|
|
@@ -102,10 +102,12 @@ import { SecuritizeRWAFactory } from "./market/rwa/securitize/SecuritizeRWAFacto
|
|
|
102
102
|
import { RWARegistry } from "./market/rwa/RWARegistry.js";
|
|
103
103
|
import { RWA_FACTORY_TYPES, isRWAFactory } from "./market/rwa/types.js";
|
|
104
104
|
import "./market/index.js";
|
|
105
|
+
import { DUST_THRESHOLD } from "./accounts/constants.js";
|
|
106
|
+
import { dominantCollateral } from "./accounts/dominantCollateral.js";
|
|
105
107
|
import { CreditAccountsServiceV310 } from "./accounts/CreditAccountsServiceV310.js";
|
|
106
108
|
import { primaryInstantOutput } from "./accounts/intents/operations/claim-delayed/index.js";
|
|
107
109
|
import { CreditAccountOperationsService } from "./accounts/intents/index.js";
|
|
108
|
-
import {
|
|
110
|
+
import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./accounts/liquidations/constants.js";
|
|
109
111
|
import { LiquidationsService } from "./accounts/liquidations/LiquidationsService.js";
|
|
110
112
|
import { MultichainLiquidationsService } from "./accounts/liquidations/MultichainLiquidationsService.js";
|
|
111
113
|
import { DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, decodeDelayedIntent, encodeDelayedIntent } from "./accounts/withdrawal-compressor/intent-codec.js";
|
|
@@ -131,6 +133,9 @@ import { PluginStateVersionError } from "./plugins/errors.js";
|
|
|
131
133
|
import "./plugins/index.js";
|
|
132
134
|
import { PoolService } from "./pools/PoolService.js";
|
|
133
135
|
import "./pools/index.js";
|
|
136
|
+
import { MultichainPositionsService } from "./positions/MultichainPositionsService.js";
|
|
137
|
+
import { PositionsService } from "./positions/PositionsService.js";
|
|
138
|
+
import "./positions/index.js";
|
|
134
139
|
import { assetsMap } from "./router/helpers.js";
|
|
135
140
|
import { RouterV310Contract } from "./router/RouterV310Contract.js";
|
|
136
141
|
import { createRouter } from "./router/createRouter.js";
|
|
@@ -139,4 +144,4 @@ import { OnchainSDK, STATE_VERSION } from "./OnchainSDK.js";
|
|
|
139
144
|
import { MultichainSDK } from "./MultichainSDK.js";
|
|
140
145
|
import { attachOptionsSchema, onchainSDKOptionsSchema } from "./options.js";
|
|
141
146
|
import "./types/index.js";
|
|
142
|
-
export { ADDRESS_0X0, ADDRESS_PROVIDER_V310, AP_ACCOUNT_FACTORY, AP_ACL, AP_BOT_LIST, AP_BYTECODE_REPOSITORY, AP_CONTRACTS_REGISTER, AP_CONTROLLER_TIMELOCK, AP_CREDIT_ACCOUNT_COMPRESSOR, AP_CREDIT_SUITE_COMPRESSOR, AP_DATA_COMPRESSOR, AP_DELEVERAGE_BOT_HV, AP_DELEVERAGE_BOT_LV, AP_DELEVERAGE_BOT_PEGGED, AP_GAUGE_COMPRESSOR, AP_GEAR_STAKING, AP_GEAR_TOKEN, AP_INFLATION_ATTACK_BLOCKER, AP_INSOLVENCY_CHECKER, AP_MARKET_COMPRESSOR, AP_MARKET_CONFIGURATOR, AP_PARTIAL_LIQUIDATION_BOT, AP_PERIPHERY_COMPRESSOR, AP_PRICE_FEED_COMPRESSOR, AP_PRICE_FEED_STORE, AP_PRICE_ORACLE, AP_REDEMPTION_LOGGER, AP_REWARDS_COMPRESSOR, AP_ROUTER, AP_RWA_COMPRESSOR, AP_TOKEN_COMPRESSOR, AP_TREASURY, AP_WETH_GATEWAY, AP_WETH_TOKEN, AP_ZAPPER_REGISTER, AP_ZERO_PRICE_FEED, AbstractLPPriceFeedContract, AbstractPriceFeedContract, AbstractWithdrawalCompressorContract, AddressMap, AddressProviderV310Contract, AddressSet, AssetsMap, BLOCKS_PER_WEEK_BY_NETWORK, BalancerStablePriceFeedContract, BalancerWeightedPriceFeedContract, BaseContract, BasePlugin, BigIntMath, BotPermissions, BoundedPriceFeedContract, ChainContractsRegister, ChainNotConfiguredError, CompositePriceFeedContract, Construct, ContractParseError, CreditAccountOperationsService, CreditAccountsServiceV310, CreditConfiguratorV310Contract, CreditFacadeV310BaseContract, CreditFacadeV310Contract, CreditManagerV310Contract, CreditSuite, CurveCryptoPriceFeedContract, CurveStablePriceFeedContract, CurveUSDPriceFeedContract, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, DUST_THRESHOLD, Erc4626PriceFeedContract, ExternalPriceFeedContract, GaugeContract, IERC20ZapperContract, IETHZapperContract, InvalidDelayedIntentError, LEVERAGE_DECIMALS, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LinearInterestRateModelContract, LiquidationsService, MAX_INT, MAX_UINT16, MAX_UINT256, MIN_INT96, MULTICALL_ADDRESS, MarketRegister, MarketSuite, MellowLRTPriceFeedContract, MidasLiquidatorContract, MissingSerializedParamsError, MultichainConstruct, MultichainLiquidationsService, MultichainOpportunitiesService, MultichainSDK, NATIVE_ADDRESS, NOT_DEPLOYED, NO_VERSION, NetworkType, OnchainSDK, OpportunitiesService, PERCENTAGE_DECIMALS, PERCENTAGE_FACTOR, PERCENTAGE_FACTOR_1KK, PERIPHERY_CONTRACTS, PHANTOM_TOKEN_CONTRACT_TYPES, PHANTOM_TOKEN_MIDAS_REDEMPTION, PHANTOM_TOKEN_SECURITIZE_REDEMPTION, PRICE_DECIMALS, PRICE_DECIMALS_POW, PartialPriceFeedInitError, PendleTWAPPTPriceFeed, PlaceholderAdapterContract, PlaceholderContract, PluginStateVersionError, PoolService, PoolSuite, PoolV310Contract, PriceFeedRef, PriceFeedRegister, PriceOracleV310Contract, PythPriceFeed, RAMP_DURATION_BY_NETWORK, RAY, RAY_DECIMALS_POW, RWARegistry, RWA_FACTORY_SECURITIZE, RWA_FACTORY_TYPES, RWA_LIQUIDATOR_MIDAS, RWA_LIQUIDATOR_SECURITIZE, RWA_ON_DEMAND_LP_MONOPOLIZED, RWA_UNDERLYING_DEFAULT, RWA_UNDERLYING_ON_DEMAND, RedemptionLoggerV310Contract, RedstonePriceFeedContract, RouterV310Contract, SDKConstruct, SECONDS_PER_YEAR, SECURITIZE_REGISTER_VAULT_TYPES, SLIPPAGE_DECIMALS, STATE_VERSION, SUPPORTED_NETWORKS, SdkAlreadyAttachedError, SdkChainMismatchError, SdkMissingChainStateError, SdkNotAttachedError, SdkStateVersionMismatchError, SdkSyncFailedError, SecuritizeLiquidatorContract, SecuritizeRWAFactory, SimulateWithPriceUpdatesError, SimulationError, TokensMeta, TypedObjectUtils, UnsupportedZapperFunctionError, VERSION_RANGE_310, VotingContractStatus, WAD, WAD_DECIMALS_POW, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, WstETHPriceFeedContract, YearnPriceFeedContract, ZapperContract, ZeroPriceFeedContract, ZodAddress, ZodHex, additionalBorrowApyBps, assetsMap, attachOptionsSchema, borrowApyBps, botPermissionsToString, bytes32ToString, chains, childLogger, createAdapter, createAddressProvider, createPriceOracle, createRawTx, createRedemptionLogger, createRouter, createWithdrawalCompressor, createZapper, abi as creditFacadeV310Abi, decodeDelayedIntent, detectNetwork, encodeDelayedIntent, estimateRawTxGas, etherscanApiUrl, etherscanUrl, executeDelegatedMulticalls, fetchPythPayloads, fetchRedstonePayloads, filterDust, filterDustUSD, findCuratorMarketConfigurator, fmtBinaryMask, formatBN, formatBNvalue, formatDuration, formatLeverage, formatNumberToString_, formatPercentage, formatTimestamp, functionArgsToMap, functionArgsToRecord, generateCastTraceCall, getAssetType, getCastTraceArgs, getChain, getCuratorName, getFunctionSignature, getNetworkType, getRawPriceUpdates, getSimulateWithPriceUpdatesError, getWithdrawalCompressorAddress, halfRAY, hexEq, hydrateAddressProvider, iCreditAccountAbi, isDust, isLPPriceFeed, isPublicNetwork, isRWAFactory, isRWAToken, isSunsetPool, isSunsetStrategy, isSupportedNetwork, isUpdatablePriceFeed, isV310, isVersionRange, json_parse, json_stringify, maxLeverage, numberWithCommas, onchainSDKOptionsSchema, percentFmt, primaryInstantOutput, rayToBps, rayToNumber, retry, sendRawTx, shortAddress, shortHash, simulateCall, simulateMulticall, simulateWithPriceUpdates, toAddress, toBN, toBigInt, toClaimableWithdrawal, toPendingWithdrawal, toRequestableWithdrawal, toSignificant, toWithdrawalStatus, usdToNumber, utilizationBps, watchBlocksAsync };
|
|
147
|
+
export { ADDRESS_0X0, ADDRESS_PROVIDER_V310, AP_ACCOUNT_FACTORY, AP_ACL, AP_BOT_LIST, AP_BYTECODE_REPOSITORY, AP_CONTRACTS_REGISTER, AP_CONTROLLER_TIMELOCK, AP_CREDIT_ACCOUNT_COMPRESSOR, AP_CREDIT_SUITE_COMPRESSOR, AP_DATA_COMPRESSOR, AP_DELEVERAGE_BOT_HV, AP_DELEVERAGE_BOT_LV, AP_DELEVERAGE_BOT_PEGGED, AP_GAUGE_COMPRESSOR, AP_GEAR_STAKING, AP_GEAR_TOKEN, AP_INFLATION_ATTACK_BLOCKER, AP_INSOLVENCY_CHECKER, AP_MARKET_COMPRESSOR, AP_MARKET_CONFIGURATOR, AP_PARTIAL_LIQUIDATION_BOT, AP_PERIPHERY_COMPRESSOR, AP_PRICE_FEED_COMPRESSOR, AP_PRICE_FEED_STORE, AP_PRICE_ORACLE, AP_REDEMPTION_LOGGER, AP_REWARDS_COMPRESSOR, AP_ROUTER, AP_RWA_COMPRESSOR, AP_TOKEN_COMPRESSOR, AP_TREASURY, AP_WETH_GATEWAY, AP_WETH_TOKEN, AP_ZAPPER_REGISTER, AP_ZERO_PRICE_FEED, AbstractLPPriceFeedContract, AbstractPriceFeedContract, AbstractWithdrawalCompressorContract, AddressMap, AddressProviderV310Contract, AddressSet, AssetsMap, BLOCKS_PER_WEEK_BY_NETWORK, BalancerStablePriceFeedContract, BalancerWeightedPriceFeedContract, BaseContract, BasePlugin, BigIntMath, BotPermissions, BoundedPriceFeedContract, ChainContractsRegister, ChainNotConfiguredError, CompositePriceFeedContract, Construct, ContractParseError, CreditAccountOperationsService, CreditAccountsServiceV310, CreditConfiguratorV310Contract, CreditFacadeV310BaseContract, CreditFacadeV310Contract, CreditManagerV310Contract, CreditSuite, CurveCryptoPriceFeedContract, CurveStablePriceFeedContract, CurveUSDPriceFeedContract, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, DUST_THRESHOLD, Erc4626PriceFeedContract, ExternalPriceFeedContract, GaugeContract, IERC20ZapperContract, IETHZapperContract, InvalidDelayedIntentError, LEVERAGE_DECIMALS, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LinearInterestRateModelContract, LiquidationsService, MAX_INT, MAX_UINT16, MAX_UINT256, MIN_INT96, MULTICALL_ADDRESS, MarketRegister, MarketSuite, MellowLRTPriceFeedContract, MidasLiquidatorContract, MissingSerializedParamsError, MultichainConstruct, MultichainLiquidationsService, MultichainOpportunitiesService, MultichainPositionsService, MultichainSDK, NATIVE_ADDRESS, NOT_DEPLOYED, NO_VERSION, NetworkType, OnchainSDK, OpportunitiesService, PERCENTAGE_DECIMALS, PERCENTAGE_FACTOR, PERCENTAGE_FACTOR_1KK, PERIPHERY_CONTRACTS, PHANTOM_TOKEN_CONTRACT_TYPES, PHANTOM_TOKEN_MIDAS_REDEMPTION, PHANTOM_TOKEN_SECURITIZE_REDEMPTION, PRICE_DECIMALS, PRICE_DECIMALS_POW, PartialPriceFeedInitError, PendleTWAPPTPriceFeed, PlaceholderAdapterContract, PlaceholderContract, PluginStateVersionError, PoolService, PoolSuite, PoolV310Contract, PositionsService, PriceFeedRef, PriceFeedRegister, PriceOracleV310Contract, PythPriceFeed, RAMP_DURATION_BY_NETWORK, RAY, RAY_DECIMALS_POW, RWARegistry, RWA_FACTORY_SECURITIZE, RWA_FACTORY_TYPES, RWA_LIQUIDATOR_MIDAS, RWA_LIQUIDATOR_SECURITIZE, RWA_ON_DEMAND_LP_MONOPOLIZED, RWA_UNDERLYING_DEFAULT, RWA_UNDERLYING_ON_DEMAND, RedemptionLoggerV310Contract, RedstonePriceFeedContract, RouterV310Contract, SDKConstruct, SECONDS_PER_YEAR, SECURITIZE_REGISTER_VAULT_TYPES, SLIPPAGE_DECIMALS, STATE_VERSION, SUPPORTED_NETWORKS, SdkAlreadyAttachedError, SdkChainMismatchError, SdkMissingChainStateError, SdkNotAttachedError, SdkStateVersionMismatchError, SdkSyncFailedError, SecuritizeLiquidatorContract, SecuritizeRWAFactory, SimulateWithPriceUpdatesError, SimulationError, TokensMeta, TypedObjectUtils, UnsupportedZapperFunctionError, VERSION_RANGE_310, VotingContractStatus, WAD, WAD_DECIMALS_POW, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, WstETHPriceFeedContract, YearnPriceFeedContract, ZapperContract, ZeroPriceFeedContract, ZodAddress, ZodHex, additionalBorrowApyBps, assetsMap, attachOptionsSchema, borrowApyBps, botPermissionsToString, bytes32ToString, chains, childLogger, createAdapter, createAddressProvider, createPriceOracle, createRawTx, createRedemptionLogger, createRouter, createWithdrawalCompressor, createZapper, abi as creditFacadeV310Abi, decodeDelayedIntent, detectNetwork, dominantCollateral, encodeDelayedIntent, estimateRawTxGas, etherscanApiUrl, etherscanUrl, executeDelegatedMulticalls, fetchPythPayloads, fetchRedstonePayloads, filterDust, filterDustUSD, findCuratorMarketConfigurator, fmtBinaryMask, formatBN, formatBNvalue, formatDuration, formatLeverage, formatNumberToString_, formatPercentage, formatTimestamp, functionArgsToMap, functionArgsToRecord, generateCastTraceCall, getAssetType, getCastTraceArgs, getChain, getCuratorName, getFunctionSignature, getNetworkType, getRawPriceUpdates, getSimulateWithPriceUpdatesError, getWithdrawalCompressorAddress, halfRAY, healthFactorBps, hexEq, hydrateAddressProvider, iCreditAccountAbi, isDust, isLPPriceFeed, isPublicNetwork, isRWAFactory, isRWAToken, isSunsetPool, isSunsetStrategy, isSupportedNetwork, isUpdatablePriceFeed, isV310, isVersionRange, json_parse, json_stringify, maxLeverage, numberWithCommas, onchainSDKOptionsSchema, percentFmt, positionLeverage, primaryInstantOutput, rayToBps, rayToNumber, retry, sendRawTx, shortAddress, shortHash, simulateCall, simulateMulticall, simulateWithPriceUpdates, toAddress, toBN, toBigInt, toClaimableWithdrawal, toPendingWithdrawal, toRequestableWithdrawal, toSignificant, toWithdrawalStatus, usdToNumber, utilizationBps, watchBlocksAsync };
|
|
@@ -123,6 +123,12 @@ var MarketSuite = class extends SDKConstruct {
|
|
|
123
123
|
return this.tokensMeta.mustGetToken(this.unwrappedUnderlying);
|
|
124
124
|
}
|
|
125
125
|
/**
|
|
126
|
+
* Display name of this market's pool, e.g. `"USDC Pool"`.
|
|
127
|
+
*/
|
|
128
|
+
get poolName() {
|
|
129
|
+
return `${this.underlyingToken.symbol} Pool`;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
126
132
|
* {@inheritDoc MarketConfiguratorContract.curator}
|
|
127
133
|
*/
|
|
128
134
|
get curator() {
|
|
@@ -212,7 +218,7 @@ var MarketSuite = class extends SDKConstruct {
|
|
|
212
218
|
kind: "pool",
|
|
213
219
|
chainId: this.chainId,
|
|
214
220
|
pool: pool.address,
|
|
215
|
-
name:
|
|
221
|
+
name: this.poolName,
|
|
216
222
|
curator: this.curator,
|
|
217
223
|
underlyingToken: this.underlyingToken,
|
|
218
224
|
totalSupply: oracle.toAmount(pool.underlying, pool.totalAssets),
|
|
@@ -141,6 +141,15 @@ var CreditSuite = class extends SDKConstruct {
|
|
|
141
141
|
return BigIntMath.min(debtParams?.available ?? 115792089237316195423570985008687907853269984665640564039457584007913129639935n, pool.availableLiquidity, this.creditFacade.maxDebt);
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
144
|
+
* Display name of a leveraged position built on one collateral token, e.g.
|
|
145
|
+
* `"wstETH / WETH"`.
|
|
146
|
+
*
|
|
147
|
+
* @param collateral - Target collateral of the position.
|
|
148
|
+
*/
|
|
149
|
+
strategyName(collateral) {
|
|
150
|
+
return `${this.tokensMeta.symbol(collateral)} / ${this.market.underlyingToken.symbol}`;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
144
153
|
* Describes a leveraged position built on one collateral token as the shared
|
|
145
154
|
* read model does.
|
|
146
155
|
*
|
|
@@ -159,7 +168,7 @@ var CreditSuite = class extends SDKConstruct {
|
|
|
159
168
|
chainId: this.chainId,
|
|
160
169
|
creditManager: cm.address,
|
|
161
170
|
targetCollateral: this.tokensMeta.mustGetToken(collateral),
|
|
162
|
-
name:
|
|
171
|
+
name: this.strategyName(collateral),
|
|
163
172
|
curator: market.curator,
|
|
164
173
|
underlyingToken: market.underlyingToken,
|
|
165
174
|
totalBorrow: oracle.toAmount(pool.underlying, borrowed),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PERCENTAGE_FACTOR, PRICE_DECIMALS, RAY } from "../constants/math.js";
|
|
1
|
+
import { PERCENTAGE_FACTOR, PRICE_DECIMALS, RAY, WAD } from "../constants/math.js";
|
|
2
2
|
//#region src/sdk/market/math.ts
|
|
3
3
|
/**
|
|
4
4
|
* Conversions between the units the protocol stores and the basis points the
|
|
@@ -80,6 +80,41 @@ function maxLeverage(liquidationThreshold) {
|
|
|
80
80
|
return equity > 0 ? FULL / equity : Number.POSITIVE_INFINITY;
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
|
+
* Converts a credit account's health factor from the 18-decimal fixed point the
|
|
84
|
+
* contracts store to basis points.
|
|
85
|
+
*
|
|
86
|
+
* An account with no debt return MAX_UINT256 from contract, here we return 0
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* healthFactorBps(1_250_000_000_000_000_000n) // 12500, i.e. 1.25
|
|
91
|
+
* ```
|
|
92
|
+
**/
|
|
93
|
+
function healthFactorBps(healthFactor) {
|
|
94
|
+
if (healthFactor === 115792089237316195423570985008687907853269984665640564039457584007913129639935n) return 0;
|
|
95
|
+
return Number(healthFactor * PERCENTAGE_FACTOR / WAD);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Leverage of an open position: `totalDebt / equity`, where equity is what is
|
|
99
|
+
* left of the position's value once its debt is repaid.
|
|
100
|
+
*
|
|
101
|
+
* Returns `0` for a position that carries no debt and for one that is
|
|
102
|
+
* underwater, where there is no equity to lever.
|
|
103
|
+
*
|
|
104
|
+
* @param totalDebt - Debt principal plus accrued interest and fees.
|
|
105
|
+
* @param totalValue - Total value of the position, in the same token.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* positionLeverage(800n, 1000n) // 4, i.e. 4x debt per unit of equity
|
|
110
|
+
* ```
|
|
111
|
+
**/
|
|
112
|
+
function positionLeverage(totalDebt, totalValue) {
|
|
113
|
+
const equity = totalValue - totalDebt;
|
|
114
|
+
if (equity <= 0n || totalDebt <= 0n) return 0;
|
|
115
|
+
return Number(totalDebt) / Number(equity);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
83
118
|
* Annual quota cost scaled to the debt a maximally leveraged position carries,
|
|
84
119
|
* in basis points. Every unit of own capital carries `maxLeverage - 1` units of
|
|
85
120
|
* debt, and the quota is paid on the whole quoted position.
|
|
@@ -95,4 +130,4 @@ function additionalBorrowApyBps(quotaRate, leverage) {
|
|
|
95
130
|
return Math.round(quotaRate * Math.max(leverage - 1, 0));
|
|
96
131
|
}
|
|
97
132
|
//#endregion
|
|
98
|
-
export { additionalBorrowApyBps, borrowApyBps, maxLeverage, rayToBps, usdToNumber, utilizationBps };
|
|
133
|
+
export { additionalBorrowApyBps, borrowApyBps, healthFactorBps, maxLeverage, positionLeverage, rayToBps, usdToNumber, utilizationBps };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { additionalBorrowApyBps, borrowApyBps, maxLeverage, rayToBps, usdToNumber, utilizationBps } from "../market/math.js";
|
|
1
|
+
import { additionalBorrowApyBps, borrowApyBps, healthFactorBps, maxLeverage, positionLeverage, rayToBps, usdToNumber, utilizationBps } from "../market/math.js";
|
|
2
2
|
import { MultichainOpportunitiesService } from "./MultichainOpportunitiesService.js";
|
|
3
3
|
import { OpportunitiesService } from "./OpportunitiesService.js";
|
|
4
|
-
export { MultichainOpportunitiesService, OpportunitiesService, additionalBorrowApyBps, borrowApyBps, maxLeverage, rayToBps, usdToNumber, utilizationBps };
|
|
4
|
+
export { MultichainOpportunitiesService, OpportunitiesService, additionalBorrowApyBps, borrowApyBps, healthFactorBps, maxLeverage, positionLeverage, rayToBps, usdToNumber, utilizationBps };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ierc20Abi } from "../../abi/iERC20.js";
|
|
2
2
|
import { AddressSet } from "../utils/AddressSet.js";
|
|
3
3
|
import "../constants/addresses.js";
|
|
4
|
+
import { RAY } from "../constants/math.js";
|
|
4
5
|
import "../constants/index.js";
|
|
5
6
|
import { hexEq } from "../utils/hex.js";
|
|
6
7
|
import "../utils/index.js";
|
|
@@ -8,6 +9,7 @@ import { BaseContract } from "../base/BaseContract.js";
|
|
|
8
9
|
import { SDKConstruct } from "../base/SDKConstruct.js";
|
|
9
10
|
import { RWA_UNDERLYING_DEFAULT, RWA_UNDERLYING_ON_DEMAND } from "../base/token-types.js";
|
|
10
11
|
import "../base/index.js";
|
|
12
|
+
import { rayToBps } from "../market/math.js";
|
|
11
13
|
import { IERC20ZapperContract } from "../market/zapper/IERC20ZapperContract.js";
|
|
12
14
|
import { IETHZapperContract } from "../market/zapper/IETHZapperContract.js";
|
|
13
15
|
import "../market/index.js";
|
|
@@ -173,6 +175,27 @@ var PoolService = class extends SDKConstruct {
|
|
|
173
175
|
return this.#withdrawalMetadata("classic", pool, tokenIn, tokenOut, true);
|
|
174
176
|
}
|
|
175
177
|
/**
|
|
178
|
+
* {@inheritDoc IPoolsService.listPositions}
|
|
179
|
+
*/
|
|
180
|
+
async listPositions(props) {
|
|
181
|
+
const { markets } = this.sdk.marketRegister;
|
|
182
|
+
if (markets.length === 0) return [];
|
|
183
|
+
const balances = await this.client.multicall({
|
|
184
|
+
contracts: markets.map((market) => ({
|
|
185
|
+
address: market.pool.pool.address,
|
|
186
|
+
abi: ierc20Abi,
|
|
187
|
+
functionName: "balanceOf",
|
|
188
|
+
args: [props.wallet]
|
|
189
|
+
})),
|
|
190
|
+
allowFailure: false,
|
|
191
|
+
batchSize: 0
|
|
192
|
+
});
|
|
193
|
+
return markets.flatMap((market, i) => {
|
|
194
|
+
const shares = balances[i] ?? 0n;
|
|
195
|
+
return shares > 0n ? [this.#poolPosition(market, shares)] : [];
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
176
199
|
* Returns non-migration zappers available for the pool.
|
|
177
200
|
*/
|
|
178
201
|
#getDepositZappers(poolAddr) {
|
|
@@ -289,6 +312,20 @@ var PoolService = class extends SDKConstruct {
|
|
|
289
312
|
const market = this.sdk.marketRegister.findByPool(pool);
|
|
290
313
|
return this.sdk.tokensMeta.mustGet(market.underlying);
|
|
291
314
|
}
|
|
315
|
+
#poolPosition(market, shares) {
|
|
316
|
+
const { pool } = market.pool;
|
|
317
|
+
return {
|
|
318
|
+
kind: "pool",
|
|
319
|
+
name: market.poolName,
|
|
320
|
+
chainId: this.chainId,
|
|
321
|
+
pool: pool.address,
|
|
322
|
+
netValue: {
|
|
323
|
+
token: this.sdk.tokensMeta.mustGetToken(market.unwrappedUnderlying),
|
|
324
|
+
...market.priceOracle.toAmount(market.underlying, shares * pool.dieselRate / RAY)
|
|
325
|
+
},
|
|
326
|
+
apy: { organicApy: rayToBps(pool.supplyRate) }
|
|
327
|
+
};
|
|
328
|
+
}
|
|
292
329
|
};
|
|
293
330
|
//#endregion
|
|
294
331
|
export { PoolService };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { getNetworkType } from "../chain/chains.js";
|
|
2
|
+
import { MultichainConstruct } from "../base/MultichainConstruct.js";
|
|
3
|
+
import "../base/index.js";
|
|
4
|
+
//#region src/sdk/positions/MultichainPositionsService.ts
|
|
5
|
+
/**
|
|
6
|
+
* Cross-chain counterpart of {@link PositionsService}.
|
|
7
|
+
*
|
|
8
|
+
* Fans out over every chain configured in {@link MultichainSDK}. A chain that
|
|
9
|
+
* fails is logged and skipped so one dead RPC does not hide the positions a
|
|
10
|
+
* wallet holds elsewhere; its failure is reported in
|
|
11
|
+
* {@link MultichainResult.meta}.
|
|
12
|
+
*
|
|
13
|
+
* @typeParam Plugins - Map of attached plugin types.
|
|
14
|
+
**/
|
|
15
|
+
var MultichainPositionsService = class extends MultichainConstruct {
|
|
16
|
+
/**
|
|
17
|
+
* Positions of a wallet on all queried chains, see
|
|
18
|
+
* {@link PositionsService.list}.
|
|
19
|
+
*
|
|
20
|
+
* A filter that names chains narrows the fan-out itself, so chains whose rows
|
|
21
|
+
* would be discarded are never queried and never appear in the meta.
|
|
22
|
+
**/
|
|
23
|
+
async list(props) {
|
|
24
|
+
return this.queryChains({
|
|
25
|
+
networks: this.#networksOf(props.filter),
|
|
26
|
+
label: "list positions",
|
|
27
|
+
run: (sdk) => sdk.positions.list(props)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Chains named by the filter, or `undefined` to query all of them. Chain ids
|
|
32
|
+
* the SDK does not support are dropped here rather than reported as failures:
|
|
33
|
+
* a filter naming them is a narrowing, not a request.
|
|
34
|
+
**/
|
|
35
|
+
#networksOf(filter) {
|
|
36
|
+
if (!filter?.chainIds) return;
|
|
37
|
+
const networks = [];
|
|
38
|
+
for (const chainId of filter.chainIds) try {
|
|
39
|
+
networks.push(getNetworkType(chainId));
|
|
40
|
+
} catch {
|
|
41
|
+
this.sdk.logger?.debug(`ignoring unsupported chain ${chainId} in positions filter`);
|
|
42
|
+
}
|
|
43
|
+
return networks;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
export { MultichainPositionsService };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SDKConstruct } from "../base/SDKConstruct.js";
|
|
2
|
+
import "../base/index.js";
|
|
3
|
+
import { matchesPositionFilter } from "../../model/positions.js";
|
|
4
|
+
import "../../model/index.js";
|
|
5
|
+
//#region src/sdk/positions/PositionsService.ts
|
|
6
|
+
/**
|
|
7
|
+
* The `positions` read model of one chain: everything a wallet holds in the
|
|
8
|
+
* protocol — pool shares, open credit accounts, and delayed withdrawals it
|
|
9
|
+
* took over by liquidating.
|
|
10
|
+
**/
|
|
11
|
+
var PositionsService = class extends SDKConstruct {
|
|
12
|
+
/**
|
|
13
|
+
* Every position of a wallet on this chain, optionally narrowed by
|
|
14
|
+
* {@link PositionFilter} (see {@link matchesPositionFilter} for what each
|
|
15
|
+
* criterion selects). Reads live chain state, so rows reflect the moment of
|
|
16
|
+
* the call rather than the SDK's loaded snapshot.
|
|
17
|
+
**/
|
|
18
|
+
async list(props) {
|
|
19
|
+
const { wallet, filter } = props;
|
|
20
|
+
if (filter?.chainIds && !filter.chainIds.includes(this.chainId)) return [];
|
|
21
|
+
const wanted = (kind) => !filter?.kind || filter.kind === kind;
|
|
22
|
+
const [pool, strategy, liquidation] = await Promise.all([
|
|
23
|
+
wanted("pool") ? this.sdk.pools.listPositions({ wallet }) : Promise.resolve([]),
|
|
24
|
+
wanted("strategy") ? this.sdk.accounts.listPositions({
|
|
25
|
+
owner: wallet,
|
|
26
|
+
includeZeroDebt: filter?.isZeroDebt !== false
|
|
27
|
+
}) : Promise.resolve([]),
|
|
28
|
+
wanted("liquidation") ? this.sdk.liquidations.getLiquidationPositions({ liquidator: wallet }) : Promise.resolve([])
|
|
29
|
+
]);
|
|
30
|
+
return [
|
|
31
|
+
...pool,
|
|
32
|
+
...strategy,
|
|
33
|
+
...liquidation
|
|
34
|
+
].filter((row) => matchesPositionFilter(row, filter));
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
export { PositionsService };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Timestamp } from "./primitives.js";
|
|
2
2
|
import { OpportunityKey } from "./opportunities.js";
|
|
3
|
+
import { PositionKey } from "./positions.js";
|
|
3
4
|
//#region src/model/history.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* Historical time series of an opportunity.
|
|
@@ -32,10 +33,37 @@ type StrategyHistoryMetric = "netApy" | "borrowApy" | "collateralApy" | "tvl" |
|
|
|
32
33
|
* Every {@link StrategyHistoryMetric}, for callers that enumerate them.
|
|
33
34
|
**/
|
|
34
35
|
declare const STRATEGY_HISTORY_METRICS: readonly ["netApy", "borrowApy", "collateralApy", "tvl", "collateralPrice", "collateralUsdPrice", "underlyingUsdPrice"];
|
|
36
|
+
/**
|
|
37
|
+
* Series available for a pool position.
|
|
38
|
+
*
|
|
39
|
+
* Spelled out rather than aliased to {@link PoolHistoryMetric}: an opportunity
|
|
40
|
+
* and a position are separate contracts with the backend, and the position
|
|
41
|
+
* series are expected to grow their own members (PnL above all) without that
|
|
42
|
+
* change reaching the opportunity charts.
|
|
43
|
+
**/
|
|
44
|
+
type PoolPositionHistoryMetric = "depositApy" | "borrowApy" | "dieselRate" | "supplied" | "borrowed" | "availableLiquidity";
|
|
45
|
+
/**
|
|
46
|
+
* Every {@link PoolPositionHistoryMetric}, for callers that enumerate them.
|
|
47
|
+
**/
|
|
48
|
+
declare const POOL_POSITION_HISTORY_METRICS: readonly ["depositApy", "borrowApy", "dieselRate", "supplied", "borrowed", "availableLiquidity"];
|
|
49
|
+
/**
|
|
50
|
+
* Series available for a strategy position, see the note on
|
|
51
|
+
* {@link PoolPositionHistoryMetric} for why these are spelled out separately
|
|
52
|
+
* from {@link StrategyHistoryMetric}.
|
|
53
|
+
**/
|
|
54
|
+
type StrategyPositionHistoryMetric = "netApy" | "borrowApy" | "collateralApy" | "tvl" | "collateralPrice" | "collateralUsdPrice" | "underlyingUsdPrice";
|
|
55
|
+
/**
|
|
56
|
+
* Every {@link StrategyPositionHistoryMetric}, for callers that enumerate them.
|
|
57
|
+
**/
|
|
58
|
+
declare const STRATEGY_POSITION_HISTORY_METRICS: readonly ["netApy", "borrowApy", "collateralApy", "tvl", "collateralPrice", "collateralUsdPrice", "underlyingUsdPrice"];
|
|
59
|
+
/**
|
|
60
|
+
* Any series a position can return.
|
|
61
|
+
**/
|
|
62
|
+
type PositionHistoryMetric = PoolPositionHistoryMetric | StrategyPositionHistoryMetric;
|
|
35
63
|
/**
|
|
36
64
|
* Any series the read model can return.
|
|
37
65
|
**/
|
|
38
|
-
type HistoryMetric = PoolHistoryMetric | StrategyHistoryMetric;
|
|
66
|
+
type HistoryMetric = PoolHistoryMetric | StrategyHistoryMetric | PositionHistoryMetric;
|
|
39
67
|
/**
|
|
40
68
|
* One sample of a series.
|
|
41
69
|
**/
|
|
@@ -101,5 +129,25 @@ interface OpportunityHistoryQuery<M extends HistoryMetric = HistoryMetric> {
|
|
|
101
129
|
**/
|
|
102
130
|
metric: M;
|
|
103
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* A request for one series of a single position.
|
|
134
|
+
*
|
|
135
|
+
* @typeParam M - Metric requested.
|
|
136
|
+
**/
|
|
137
|
+
interface PositionHistoryQuery<M extends PositionHistoryMetric = PositionHistoryMetric> {
|
|
138
|
+
/**
|
|
139
|
+
* Position the series belongs to.
|
|
140
|
+
**/
|
|
141
|
+
position: PositionKey;
|
|
142
|
+
/**
|
|
143
|
+
* Window to cover.
|
|
144
|
+
**/
|
|
145
|
+
range: HistoryRange;
|
|
146
|
+
/**
|
|
147
|
+
* Metric to return. A metric that does not apply to the position's kind has
|
|
148
|
+
* no series.
|
|
149
|
+
**/
|
|
150
|
+
metric: M;
|
|
151
|
+
}
|
|
104
152
|
//#endregion
|
|
105
|
-
export { HistoryChartMetadata, HistoryMetric, HistoryPoint, HistoryRange, HistorySeries, OpportunityHistoryQuery, POOL_HISTORY_METRICS, PoolHistoryMetric, STRATEGY_HISTORY_METRICS, StrategyHistoryMetric };
|
|
153
|
+
export { HistoryChartMetadata, HistoryMetric, HistoryPoint, HistoryRange, HistorySeries, OpportunityHistoryQuery, POOL_HISTORY_METRICS, POOL_POSITION_HISTORY_METRICS, PoolHistoryMetric, PoolPositionHistoryMetric, PositionHistoryMetric, PositionHistoryQuery, STRATEGY_HISTORY_METRICS, STRATEGY_POSITION_HISTORY_METRICS, StrategyHistoryMetric, StrategyPositionHistoryMetric };
|