@gearbox-protocol/sdk 17.12.1 → 17.13.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/onchain/accounts/CreditAccountsServiceV310.js +1 -1
- package/dist/cjs/onchain/accounts/index.js +3 -0
- package/dist/cjs/onchain/accounts/liquidations/LiquidationsService.js +43 -1
- package/dist/cjs/onchain/accounts/liquidations/index.js +3 -0
- package/dist/cjs/onchain/accounts/liquidations/partialLiquidation.js +74 -0
- package/dist/cjs/onchain/index.js +4 -1
- package/dist/cjs/onchain/market/credit/CreditSuite.js +0 -60
- package/dist/cjs/onchain/market/credit/collateralUtils.js +3 -2
- package/dist/cjs/onchain/market/index.js +1 -1
- package/dist/cjs/onchain/market/math.js +34 -12
- package/dist/cjs/permissionless/api/chains/ChainsNamespace.js +17 -6
- package/dist/cjs/permissionless/api/transactions/InstanceOwnerTransactions.js +1 -4
- package/dist/cjs/permissionless/bindings/index.js +1 -1
- package/dist/cjs/permissionless/index.js +1 -1
- package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +1 -1
- package/dist/esm/onchain/accounts/index.js +2 -1
- package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +43 -1
- package/dist/esm/onchain/accounts/liquidations/index.js +2 -1
- package/dist/esm/onchain/accounts/liquidations/partialLiquidation.js +72 -0
- package/dist/esm/onchain/index.js +3 -2
- package/dist/esm/onchain/market/credit/CreditSuite.js +2 -62
- package/dist/esm/onchain/market/credit/collateralUtils.js +3 -2
- package/dist/esm/onchain/market/index.js +2 -2
- package/dist/esm/onchain/market/math.js +34 -12
- package/dist/esm/permissionless/api/chains/ChainsNamespace.js +17 -6
- package/dist/esm/permissionless/api/transactions/InstanceOwnerTransactions.js +1 -4
- package/dist/esm/permissionless/bindings/index.js +1 -1
- package/dist/esm/permissionless/index.js +1 -1
- package/dist/types/onchain/OnchainSDK.d.ts +1 -1
- package/dist/types/onchain/accounts/index.d.ts +7 -6
- package/dist/types/onchain/accounts/liquidations/LiquidationsService.d.ts +27 -1
- package/dist/types/onchain/accounts/liquidations/index.d.ts +3 -2
- package/dist/types/onchain/accounts/liquidations/partialLiquidation.d.ts +81 -0
- package/dist/types/onchain/accounts/liquidations/types.d.ts +36 -1
- package/dist/types/onchain/accounts/types.d.ts +3 -1
- package/dist/types/onchain/index.d.ts +8 -7
- package/dist/types/onchain/market/credit/CreditSuite.d.ts +1 -11
- package/dist/types/onchain/market/credit/collateralUtils.d.ts +2 -1
- package/dist/types/onchain/market/credit/index.d.ts +2 -2
- package/dist/types/onchain/market/credit/types.d.ts +1 -36
- package/dist/types/onchain/market/index.d.ts +3 -3
- package/dist/types/onchain/market/math.d.ts +29 -10
- package/dist/types/permissionless/api/types.d.ts +16 -1
- package/package.json +1 -1
|
@@ -126,7 +126,7 @@ var CreditAccountsServiceV310 = class extends require_onchain_base_SDKConstruct.
|
|
|
126
126
|
async partiallyLiquidate(props) {
|
|
127
127
|
const { account, to } = props;
|
|
128
128
|
const cm = this.sdk.marketRegister.findCreditManager(account.creditManager);
|
|
129
|
-
const { tokenOut, repaidAmount, minSeizedAmount } =
|
|
129
|
+
const { tokenOut, repaidAmount, minSeizedAmount } = this.sdk.liquidations.getPartialLiquidationParams(account, props);
|
|
130
130
|
const updates = await this.getOnDemandPriceUpdates(account, true);
|
|
131
131
|
return cm.creditFacade.partiallyLiquidateCreditAccount(account.creditAccount, tokenOut, repaidAmount, minSeizedAmount, to, updates);
|
|
132
132
|
}
|
|
@@ -11,6 +11,7 @@ const require_onchain_accounts_intents_utils_credit_account_slice = require("./i
|
|
|
11
11
|
const require_onchain_accounts_quota_utils = require("./quota-utils.js");
|
|
12
12
|
const require_onchain_accounts_intents_index = require("./intents/index.js");
|
|
13
13
|
const require_onchain_accounts_liquidations_constants = require("./liquidations/constants.js");
|
|
14
|
+
const require_onchain_accounts_liquidations_partialLiquidation = require("./liquidations/partialLiquidation.js");
|
|
14
15
|
const require_onchain_accounts_liquidations_LiquidationsService = require("./liquidations/LiquidationsService.js");
|
|
15
16
|
const require_onchain_accounts_liquidations_MultichainLiquidationsService = require("./liquidations/MultichainLiquidationsService.js");
|
|
16
17
|
require("./liquidations/index.js");
|
|
@@ -56,6 +57,8 @@ exports.getWithdrawalCompressorAddress = require_onchain_accounts_withdrawal_com
|
|
|
56
57
|
exports.iCreditAccountAbi = require_onchain_accounts_withdrawal_compressor_AbstractWithdrawalCompressorContract.iCreditAccountAbi;
|
|
57
58
|
exports.isPhantomToken = require_onchain_accounts_intents_utils_pick_token.isPhantomToken;
|
|
58
59
|
exports.maxAmountForQuota = require_onchain_accounts_quota_utils.maxAmountForQuota;
|
|
60
|
+
exports.optimalPartialLiquidation = require_onchain_accounts_liquidations_partialLiquidation.optimalPartialLiquidation;
|
|
61
|
+
exports.partialLiquidationParams = require_onchain_accounts_liquidations_partialLiquidation.partialLiquidationParams;
|
|
59
62
|
exports.roundUpQuota = require_onchain_accounts_quota_utils.roundUpQuota;
|
|
60
63
|
exports.toClaimableWithdrawal = require_onchain_accounts_withdrawal_compressor_AbstractWithdrawalCompressorContract.toClaimableWithdrawal;
|
|
61
64
|
exports.toCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.toCreditAccountSlice;
|
|
@@ -21,6 +21,7 @@ const require_onchain_market_rwa_securitize_SecuritizeLiquidatorContract = requi
|
|
|
21
21
|
require("../../market/rwa/securitize/index.js");
|
|
22
22
|
require("../../market/index.js");
|
|
23
23
|
const require_onchain_accounts_liquidations_constants = require("./constants.js");
|
|
24
|
+
const require_onchain_accounts_liquidations_partialLiquidation = require("./partialLiquidation.js");
|
|
24
25
|
const require_onchain_accounts_liquidations_skipLiquidatableAccount = require("./skipLiquidatableAccount.js");
|
|
25
26
|
//#region src/onchain/accounts/liquidations/LiquidationsService.ts
|
|
26
27
|
/**
|
|
@@ -88,6 +89,44 @@ var LiquidationsService = class extends require_onchain_base_SDKConstruct.SDKCon
|
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
91
|
/**
|
|
92
|
+
* Optimal partial liquidation of a credit account: the collateral to seize
|
|
93
|
+
* and the amounts that bring its health factor close to `optimalHF`.
|
|
94
|
+
*
|
|
95
|
+
* Prices come from the last synced oracle state and `ca`, not from fresh
|
|
96
|
+
* price updates. Withdrawal phantom tokens are never seized.
|
|
97
|
+
*
|
|
98
|
+
* @param ca - Credit account to partially liquidate.
|
|
99
|
+
* @param optimalHF - Health factor to aim for, in basis points. Defaults to
|
|
100
|
+
* {@link CreditSuite.optimalHFForPartialLiquidation}.
|
|
101
|
+
* @throws If no `tokenOut` can be picked.
|
|
102
|
+
**/
|
|
103
|
+
getOptimalPartialLiquidation(ca, optimalHF) {
|
|
104
|
+
return require_onchain_accounts_liquidations_partialLiquidation.optimalPartialLiquidation({
|
|
105
|
+
suite: this.sdk.marketRegister.findCreditManager(ca.creditManager),
|
|
106
|
+
account: ca,
|
|
107
|
+
optimalHF,
|
|
108
|
+
exclude: (token) => this.#isWithdrawalPhantom(token)
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Everything a partial liquidation of a credit account needs, with any
|
|
113
|
+
* parameter the caller pinned down taken as given and the rest derived from
|
|
114
|
+
* current state. A derived `tokenOut` is never a withdrawal phantom token.
|
|
115
|
+
*
|
|
116
|
+
* @param ca - Credit account to partially liquidate.
|
|
117
|
+
* @param overrides - Parameters to use instead of the derived defaults.
|
|
118
|
+
* @throws If a derived `tokenOut` cannot be picked, or if the seized token is
|
|
119
|
+
* not a collateral token of the credit manager.
|
|
120
|
+
**/
|
|
121
|
+
getPartialLiquidationParams(ca, overrides) {
|
|
122
|
+
return require_onchain_accounts_liquidations_partialLiquidation.partialLiquidationParams({
|
|
123
|
+
suite: this.sdk.marketRegister.findCreditManager(ca.creditManager),
|
|
124
|
+
account: ca,
|
|
125
|
+
overrides,
|
|
126
|
+
exclude: (token) => this.#isWithdrawalPhantom(token)
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
91
130
|
* Returns the status of delayed-withdrawal positions (redemption receipts)
|
|
92
131
|
* owned by a liquidator wallet: what is receivable, how much, and when it
|
|
93
132
|
* becomes claimable.
|
|
@@ -279,11 +318,14 @@ var LiquidationsService = class extends require_onchain_base_SDKConstruct.SDKCon
|
|
|
279
318
|
value: estimatedProfit,
|
|
280
319
|
valueUsd: usd(estimatedProfit)
|
|
281
320
|
},
|
|
282
|
-
isDelayed: ca.tokens.some((t) => t.balance > 10n &&
|
|
321
|
+
isDelayed: ca.tokens.some((t) => t.balance > 10n && this.#isWithdrawalPhantom(t.token)),
|
|
283
322
|
paused: suite.creditFacade.isPaused,
|
|
284
323
|
rwa: market.rwa
|
|
285
324
|
};
|
|
286
325
|
}
|
|
326
|
+
#isWithdrawalPhantom(token) {
|
|
327
|
+
return !!this.sdk.withdrawalCompressor?.getWithdrawalSourceToken(token);
|
|
328
|
+
}
|
|
287
329
|
#mainAsset(ca, market, fallback) {
|
|
288
330
|
const asset = require_onchain_market_credit_collateralUtils.dominantCollateral(ca, market);
|
|
289
331
|
if (!asset) return fallback;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_onchain_accounts_liquidations_constants = require("./constants.js");
|
|
3
|
+
const require_onchain_accounts_liquidations_partialLiquidation = require("./partialLiquidation.js");
|
|
3
4
|
const require_onchain_accounts_liquidations_LiquidationsService = require("./LiquidationsService.js");
|
|
4
5
|
const require_onchain_accounts_liquidations_MultichainLiquidationsService = require("./MultichainLiquidationsService.js");
|
|
5
6
|
require("./types.js");
|
|
@@ -7,3 +8,5 @@ exports.LIQUIDATION_APPROVAL_BUFFER = require_onchain_accounts_liquidations_cons
|
|
|
7
8
|
exports.LIQUIDATION_COMPRESSOR_V313_ADDRESS = require_onchain_accounts_liquidations_constants.LIQUIDATION_COMPRESSOR_V313_ADDRESS;
|
|
8
9
|
exports.LiquidationsService = require_onchain_accounts_liquidations_LiquidationsService.LiquidationsService;
|
|
9
10
|
exports.MultichainLiquidationsService = require_onchain_accounts_liquidations_MultichainLiquidationsService.MultichainLiquidationsService;
|
|
11
|
+
exports.optimalPartialLiquidation = require_onchain_accounts_liquidations_partialLiquidation.optimalPartialLiquidation;
|
|
12
|
+
exports.partialLiquidationParams = require_onchain_accounts_liquidations_partialLiquidation.partialLiquidationParams;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_onchain_market_math = require("../../market/math.js");
|
|
3
|
+
const require_onchain_market_credit_collateralUtils = require("../../market/credit/collateralUtils.js");
|
|
4
|
+
require("../../market/index.js");
|
|
5
|
+
//#region src/onchain/accounts/liquidations/partialLiquidation.ts
|
|
6
|
+
/**
|
|
7
|
+
* Optimal partial liquidation of an account: the collateral to seize and the
|
|
8
|
+
* amounts that bring its health factor close to `optimalHF`.
|
|
9
|
+
*
|
|
10
|
+
* Ported from solidity, without the price updates the contract applies first:
|
|
11
|
+
* https://github.com/Gearbox-protocol/router-v3/blob/56e2d515ec6d9bb1e324e71c3708e59710779b24/contracts/liquidation/AbstractLiquidator.sol#L252
|
|
12
|
+
*
|
|
13
|
+
* @throws If no `tokenOut` can be picked.
|
|
14
|
+
**/
|
|
15
|
+
function optimalPartialLiquidation({ suite, account, optimalHF = suite.optimalHFForPartialLiquidation(account), exclude }) {
|
|
16
|
+
const tokenOut = bestTokenOut(suite, account, exclude);
|
|
17
|
+
return {
|
|
18
|
+
tokenOut,
|
|
19
|
+
...optimalAmounts(suite, account, tokenOut, optimalHF)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Everything a partial liquidation of credit account needs, with any parameter
|
|
24
|
+
* the caller pinned down taken as given and the rest derived from current state.
|
|
25
|
+
*
|
|
26
|
+
* @throws If a derived `tokenOut` cannot be picked, or if the seized token is
|
|
27
|
+
* not a collateral token of the credit manager.
|
|
28
|
+
**/
|
|
29
|
+
function partialLiquidationParams({ suite, account, overrides = {}, exclude }) {
|
|
30
|
+
const tokenOut = overrides.tokenOut ?? bestTokenOut(suite, account, exclude);
|
|
31
|
+
const optimalHF = overrides.optimalHF ?? suite.optimalHFForPartialLiquidation(account);
|
|
32
|
+
const repaidAmount = overrides.repaidAmount ?? optimalAmounts(suite, account, tokenOut, optimalHF).repaidAmount;
|
|
33
|
+
return {
|
|
34
|
+
tokenOut,
|
|
35
|
+
optimalHF,
|
|
36
|
+
repaidAmount,
|
|
37
|
+
minSeizedAmount: overrides.minSeizedAmount ?? minSeizedAmountOf(suite, tokenOut, repaidAmount)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function bestTokenOut(suite, account, exclude) {
|
|
41
|
+
const collateral = require_onchain_market_credit_collateralUtils.dominantCollateral(account, suite.market, exclude);
|
|
42
|
+
if (!collateral) throw new Error(`cannot determine tokenOut for partial liquidation of ${suite.register.labelAddress(account.creditAccount)}: no enabled non-underlying collateral with value`);
|
|
43
|
+
return collateral;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @throws If `tokenOut` is not a collateral token of the credit manager.
|
|
47
|
+
**/
|
|
48
|
+
function optimalAmounts(suite, account, tokenOut, optimalHF) {
|
|
49
|
+
const { creditManager: cm, market } = suite;
|
|
50
|
+
const { feeLiquidation, liquidationDiscount } = suite.liquidationFees();
|
|
51
|
+
const ltTokenOut = cm.liquidationThresholds.get(tokenOut);
|
|
52
|
+
if (ltTokenOut === void 0) throw new Error(`token ${suite.register.labelAddress(tokenOut)} is not a collateral token in credit manager ${suite.register.labelAddress(cm.address)}`);
|
|
53
|
+
return require_onchain_market_math.optimalPartialLiquidationAmounts({
|
|
54
|
+
totalDebt: account.debt + account.accruedInterest + account.accruedFees,
|
|
55
|
+
twvUnderlying: market.priceOracle.convertFromUSD(market.underlying, account.twvUSD),
|
|
56
|
+
minDebt: suite.creditFacade.minDebt,
|
|
57
|
+
optimalHF,
|
|
58
|
+
liquidationDiscount: BigInt(liquidationDiscount),
|
|
59
|
+
discount: BigInt(liquidationDiscount) - BigInt(feeLiquidation),
|
|
60
|
+
ltTokenOut: BigInt(ltTokenOut)
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Minimum amount of `token` that must be seized when repaying `repaidAmount`
|
|
65
|
+
* of underlying.
|
|
66
|
+
**/
|
|
67
|
+
function minSeizedAmountOf(suite, token, repaidAmount) {
|
|
68
|
+
const { market } = suite;
|
|
69
|
+
const tokenAmount = market.priceOracle.convert(market.underlying, token, repaidAmount);
|
|
70
|
+
return require_onchain_market_math.minSeizedAmount(tokenAmount, suite.liquidationFees().liquidationDiscount);
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
exports.optimalPartialLiquidation = optimalPartialLiquidation;
|
|
74
|
+
exports.partialLiquidationParams = partialLiquidationParams;
|
|
@@ -246,6 +246,7 @@ const require_onchain_accounts_intents_utils_credit_account_slice = require("./a
|
|
|
246
246
|
const require_onchain_accounts_quota_utils = require("./accounts/quota-utils.js");
|
|
247
247
|
const require_onchain_accounts_intents_index = require("./accounts/intents/index.js");
|
|
248
248
|
const require_onchain_accounts_liquidations_constants = require("./accounts/liquidations/constants.js");
|
|
249
|
+
const require_onchain_accounts_liquidations_partialLiquidation = require("./accounts/liquidations/partialLiquidation.js");
|
|
249
250
|
const require_onchain_accounts_liquidations_LiquidationsService = require("./accounts/liquidations/LiquidationsService.js");
|
|
250
251
|
const require_onchain_accounts_liquidations_MultichainLiquidationsService = require("./accounts/liquidations/MultichainLiquidationsService.js");
|
|
251
252
|
const require_onchain_accounts_withdrawal_compressor_intent_codec = require("./accounts/withdrawal-compressor/intent-codec.js");
|
|
@@ -773,7 +774,8 @@ exports.minSeizedAmount = require_onchain_market_math.minSeizedAmount;
|
|
|
773
774
|
exports.numberWithCommas = require_onchain_utils_formatter.numberWithCommas;
|
|
774
775
|
exports.onchainSDKOptionsSchema = require_onchain_options.onchainSDKOptionsSchema;
|
|
775
776
|
exports.optimalHFForPartialLiquidation = require_onchain_market_math.optimalHFForPartialLiquidation;
|
|
776
|
-
exports.
|
|
777
|
+
exports.optimalPartialLiquidation = require_onchain_accounts_liquidations_partialLiquidation.optimalPartialLiquidation;
|
|
778
|
+
exports.optimalPartialLiquidationAmounts = require_onchain_market_math.optimalPartialLiquidationAmounts;
|
|
777
779
|
exports.parseAdapterAction = require_onchain_market_adapters_abi_utils.parseAdapterAction;
|
|
778
780
|
exports.parseAdapterDeployParams = require_onchain_market_adapters_abi_utils.parseAdapterDeployParams;
|
|
779
781
|
exports.parseFacadeOperationCalldata = require_onchain_preview_parse_parseFacadeOperationCalldata.parseFacadeOperationCalldata;
|
|
@@ -781,6 +783,7 @@ exports.parseOperationCalldata = require_onchain_preview_parse_parseOperationCal
|
|
|
781
783
|
exports.parsePoolOperationCalldata = require_onchain_preview_parse_parsePoolOperationCalldata.parsePoolOperationCalldata;
|
|
782
784
|
exports.parsePosNegAmount = require_onchain_market_adapters_transferHelpers.parsePosNegAmount;
|
|
783
785
|
exports.parseRWAFactoryOperationCalldata = require_onchain_preview_parse_parseRWAFactoryOperationCalldata.parseRWAFactoryOperationCalldata;
|
|
786
|
+
exports.partialLiquidationParams = require_onchain_accounts_liquidations_partialLiquidation.partialLiquidationParams;
|
|
784
787
|
exports.percentFmt = require_onchain_utils_formatter.percentFmt;
|
|
785
788
|
exports.pickStrategyTargetCollateral = require_onchain_market_credit_collateralUtils.pickStrategyTargetCollateral;
|
|
786
789
|
exports.previewAdjustStrategyPosition = require_onchain_preview_preview_previewAdjustStrategyPosition.previewAdjustStrategyPosition;
|
|
@@ -335,26 +335,6 @@ var CreditSuite = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
335
335
|
return target ? require_onchain_market_strategyName.strategyName(target, this.underlyingToken) : this.underlyingToken.symbol;
|
|
336
336
|
}
|
|
337
337
|
/**
|
|
338
|
-
* Everything a partial liquidation of credit account needs, with any parameter the
|
|
339
|
-
* caller pinned down taken as given and the rest derived from current state.
|
|
340
|
-
*
|
|
341
|
-
* @param ca - Credit account to partially liquidate.
|
|
342
|
-
* @param overrides - Parameters to use instead of the derived defaults.
|
|
343
|
-
* @throws If a derived `tokenOut` cannot be picked, or if the seized token is
|
|
344
|
-
* not a collateral token of this credit manager.
|
|
345
|
-
*/
|
|
346
|
-
partialLiquidationParams(ca, overrides = {}) {
|
|
347
|
-
const tokenOut = overrides.tokenOut ?? this.#bestTokenOut(ca);
|
|
348
|
-
const optimalHF = overrides.optimalHF ?? this.optimalHFForPartialLiquidation(ca);
|
|
349
|
-
const repaidAmount = overrides.repaidAmount ?? this.#optimalRepaidAmount(ca, tokenOut, optimalHF);
|
|
350
|
-
return {
|
|
351
|
-
tokenOut,
|
|
352
|
-
optimalHF,
|
|
353
|
-
repaidAmount,
|
|
354
|
-
minSeizedAmount: overrides.minSeizedAmount ?? this.#minSeizedAmount(tokenOut, repaidAmount)
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
338
|
* Health factor a partial liquidation of `ca` should target, in basis points.
|
|
359
339
|
*
|
|
360
340
|
* @param ca - Credit account to partially liquidate.
|
|
@@ -363,17 +343,6 @@ var CreditSuite = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
363
343
|
return require_onchain_market_math.optimalHFForPartialLiquidation(this.#borrowRate(ca));
|
|
364
344
|
}
|
|
365
345
|
/**
|
|
366
|
-
* Collateral token a partial liquidation seizes by default.
|
|
367
|
-
*
|
|
368
|
-
* Ported from solidity:
|
|
369
|
-
* https://github.com/Gearbox-protocol/router-v3/blob/main/contracts/liquidation/AbstractLiquidator.sol#L270
|
|
370
|
-
*/
|
|
371
|
-
#bestTokenOut(ca) {
|
|
372
|
-
const collateral = require_onchain_market_credit_collateralUtils.dominantCollateral(ca, this.market);
|
|
373
|
-
if (!collateral) throw new Error(`cannot determine tokenOut for partial liquidation of ${this.labelAddress(ca.creditAccount)}: no enabled non-underlying collateral with value`);
|
|
374
|
-
return collateral;
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
346
|
* Shared inputs of {@link isStrategyCollateral} for one of this suite's
|
|
378
347
|
* collateral tokens.
|
|
379
348
|
*/
|
|
@@ -391,35 +360,6 @@ var CreditSuite = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
391
360
|
};
|
|
392
361
|
}
|
|
393
362
|
/**
|
|
394
|
-
* Minimum amount of `token` that must be seized when repaying `repaidAmount`
|
|
395
|
-
* of underlying.
|
|
396
|
-
*/
|
|
397
|
-
#minSeizedAmount(token, repaidAmount) {
|
|
398
|
-
const { market } = this;
|
|
399
|
-
const tokenAmount = market.priceOracle.convert(market.underlying, token, repaidAmount);
|
|
400
|
-
return require_onchain_market_math.minSeizedAmount(tokenAmount, this.liquidationFees().liquidationDiscount);
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Amount of underlying to repay to bring `ca`'s health factor close to
|
|
404
|
-
* `optimalHF` by seizing `token`.
|
|
405
|
-
*
|
|
406
|
-
* @throws If `token` is not a collateral token of this credit manager.
|
|
407
|
-
*/
|
|
408
|
-
#optimalRepaidAmount(ca, token, optimalHF) {
|
|
409
|
-
const { creditManager: cm, market } = this;
|
|
410
|
-
const { feeLiquidation, liquidationDiscount } = this.liquidationFees();
|
|
411
|
-
const ltTokenOut = cm.liquidationThresholds.get(token);
|
|
412
|
-
if (ltTokenOut === void 0) throw new Error(`token ${this.labelAddress(token)} is not a collateral token in credit manager ${this.labelAddress(cm.address)}`);
|
|
413
|
-
return require_onchain_market_math.optimalRepaidAmount({
|
|
414
|
-
totalDebt: ca.debt + ca.accruedInterest + ca.accruedFees,
|
|
415
|
-
twvUnderlying: market.priceOracle.convertFromUSD(market.underlying, ca.twvUSD),
|
|
416
|
-
minDebt: this.creditFacade.minDebt,
|
|
417
|
-
optimalHF,
|
|
418
|
-
discount: BigInt(liquidationDiscount) - BigInt(feeLiquidation),
|
|
419
|
-
ltTokenOut: BigInt(ltTokenOut)
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
363
|
* Blended annual cost of credit account's debt, in basis points: base interest weighted
|
|
424
364
|
* by the account's share of its own total debt, plus the quota rates of the
|
|
425
365
|
* collaterals it actually holds, both marked up by the interest fee.
|
|
@@ -63,14 +63,15 @@ function pickStrategyTargetCollateral(tokens) {
|
|
|
63
63
|
*
|
|
64
64
|
* @param account - Account to inspect.
|
|
65
65
|
* @param market - Market of the account, whose oracle prices the candidates.
|
|
66
|
+
* @param exclude - Tokens that cannot be the dominant collateral.
|
|
66
67
|
* @returns The dominant collateral, or `undefined` when the account holds
|
|
67
68
|
* nothing but its underlying, or nothing the oracle can price.
|
|
68
69
|
**/
|
|
69
|
-
function dominantCollateral(account, market) {
|
|
70
|
+
function dominantCollateral(account, market, exclude) {
|
|
70
71
|
let bestValue = 0n;
|
|
71
72
|
let dominant;
|
|
72
73
|
for (const t of account.tokens) {
|
|
73
|
-
if ((0, viem.isAddressEqual)(t.token, account.underlying) || (t.mask & account.enabledTokensMask) === 0n || t.balance <= 10n) continue;
|
|
74
|
+
if ((0, viem.isAddressEqual)(t.token, account.underlying) || (t.mask & account.enabledTokensMask) === 0n || t.balance <= 10n || exclude?.(t.token)) continue;
|
|
74
75
|
const value = market.priceOracle.safeConvertToUSD(t.token, t.balance).value;
|
|
75
76
|
if (value > bestValue) {
|
|
76
77
|
bestValue = value;
|
|
@@ -360,7 +360,7 @@ exports.lidoV1_WETHGatewayAbi = require_onchain_market_adapters_abi_targetContra
|
|
|
360
360
|
exports.mellowDvvAdapterAbi = require_onchain_market_adapters_abi_adapters_mellowDvvAdapter.mellowDvvAdapterAbi;
|
|
361
361
|
exports.minSeizedAmount = require_onchain_market_math.minSeizedAmount;
|
|
362
362
|
exports.optimalHFForPartialLiquidation = require_onchain_market_math.optimalHFForPartialLiquidation;
|
|
363
|
-
exports.
|
|
363
|
+
exports.optimalPartialLiquidationAmounts = require_onchain_market_math.optimalPartialLiquidationAmounts;
|
|
364
364
|
exports.parseAdapterAction = require_onchain_market_adapters_abi_utils.parseAdapterAction;
|
|
365
365
|
exports.parseAdapterDeployParams = require_onchain_market_adapters_abi_utils.parseAdapterDeployParams;
|
|
366
366
|
exports.parsePosNegAmount = require_onchain_market_adapters_transferHelpers.parsePosNegAmount;
|
|
@@ -257,28 +257,50 @@ function minSeizedAmount(tokenAmount, liquidationDiscount) {
|
|
|
257
257
|
return tokenAmount * PARTIAL_LIQUIDATION_BUFFER_BPS / BigInt(liquidationDiscount);
|
|
258
258
|
}
|
|
259
259
|
/**
|
|
260
|
-
*
|
|
261
|
-
* to `optimalHF`, capped so the account keeps at least `minDebt` of debt.
|
|
260
|
+
* Amounts of a partial liquidation that brings the account's health factor
|
|
261
|
+
* close to `optimalHF`, capped so the account keeps at least `minDebt` of debt.
|
|
262
262
|
*
|
|
263
263
|
* Ported from solidity:
|
|
264
|
-
* https://github.com/Gearbox-protocol/router-v3/blob/56e2d515ec6d9bb1e324e71c3708e59710779b24/contracts/liquidation/AbstractLiquidator.sol#
|
|
264
|
+
* https://github.com/Gearbox-protocol/router-v3/blob/56e2d515ec6d9bb1e324e71c3708e59710779b24/contracts/liquidation/AbstractLiquidator.sol#L252
|
|
265
265
|
*
|
|
266
|
-
* @returns
|
|
267
|
-
*
|
|
266
|
+
* @returns Zero amounts when the account is already healthy enough or
|
|
267
|
+
* carries less than the minimum debt.
|
|
268
268
|
* @throws If the discounted target health factor does not exceed the seized
|
|
269
269
|
* token's liquidation threshold, in which case no repayment improves the
|
|
270
270
|
* account.
|
|
271
271
|
**/
|
|
272
|
-
function
|
|
272
|
+
function optimalPartialLiquidationAmounts({ totalDebt, twvUnderlying, minDebt, optimalHF, liquidationDiscount, discount, ltTokenOut }) {
|
|
273
273
|
const denominator = discount * optimalHF / require_onchain_constants_math.PERCENTAGE_FACTOR - ltTokenOut;
|
|
274
274
|
if (denominator <= 0n) throw new Error("cannot compute optimal repaid amount: invalid liquidation parameters (discount * hfOptimal <= ltTokenOut)");
|
|
275
275
|
const numerator = totalDebt * optimalHF - twvUnderlying * require_onchain_constants_math.PERCENTAGE_FACTOR;
|
|
276
|
-
if (numerator <= 0n) return
|
|
277
|
-
|
|
278
|
-
|
|
276
|
+
if (numerator <= 0n) return {
|
|
277
|
+
optimalAmount: 0n,
|
|
278
|
+
repaidAmount: 0n,
|
|
279
|
+
flashLoanAmount: 0n,
|
|
280
|
+
isOptimalRepayable: true
|
|
281
|
+
};
|
|
282
|
+
if (totalDebt < minDebt) return {
|
|
283
|
+
optimalAmount: 0n,
|
|
284
|
+
repaidAmount: 0n,
|
|
285
|
+
flashLoanAmount: 0n,
|
|
286
|
+
isOptimalRepayable: false
|
|
287
|
+
};
|
|
288
|
+
const optimalValueSeized = numerator / denominator;
|
|
289
|
+
let optimalAmount = optimalValueSeized * liquidationDiscount / require_onchain_constants_math.PERCENTAGE_FACTOR;
|
|
290
|
+
let repaidAmount = optimalValueSeized * discount / require_onchain_constants_math.PERCENTAGE_FACTOR;
|
|
291
|
+
let isOptimalRepayable = true;
|
|
279
292
|
const surplusDebt = totalDebt - minDebt;
|
|
280
|
-
if (repaidAmount > surplusDebt)
|
|
281
|
-
|
|
293
|
+
if (repaidAmount > surplusDebt) {
|
|
294
|
+
optimalAmount = optimalAmount * surplusDebt * PARTIAL_LIQUIDATION_BUFFER_BPS / (repaidAmount * require_onchain_constants_math.PERCENTAGE_FACTOR);
|
|
295
|
+
repaidAmount = surplusDebt * PARTIAL_LIQUIDATION_BUFFER_BPS / require_onchain_constants_math.PERCENTAGE_FACTOR;
|
|
296
|
+
isOptimalRepayable = false;
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
optimalAmount,
|
|
300
|
+
repaidAmount,
|
|
301
|
+
flashLoanAmount: optimalAmount * 1001n / 1000n,
|
|
302
|
+
isOptimalRepayable
|
|
303
|
+
};
|
|
282
304
|
}
|
|
283
305
|
/**
|
|
284
306
|
* Health factor a partial liquidation should target, in basis points: just
|
|
@@ -306,6 +328,6 @@ exports.calcUtilizationRaw = calcUtilizationRaw;
|
|
|
306
328
|
exports.healthFactorBps = healthFactorBps;
|
|
307
329
|
exports.minSeizedAmount = minSeizedAmount;
|
|
308
330
|
exports.optimalHFForPartialLiquidation = optimalHFForPartialLiquidation;
|
|
309
|
-
exports.
|
|
331
|
+
exports.optimalPartialLiquidationAmounts = optimalPartialLiquidationAmounts;
|
|
310
332
|
exports.rayToBps = rayToBps;
|
|
311
333
|
exports.usdToNumber = usdToNumber;
|
|
@@ -35,6 +35,8 @@ let viem = require("viem");
|
|
|
35
35
|
**/
|
|
36
36
|
var ChainsNamespace = class extends require_offchain_AbstractOffchainNamespace.AbstractOffchainNamespace {
|
|
37
37
|
#clients = /* @__PURE__ */ new Map();
|
|
38
|
+
/** Transports the caller supplied, by chain id. See {@link #client}. */
|
|
39
|
+
#transports;
|
|
38
40
|
#chains;
|
|
39
41
|
#attaching;
|
|
40
42
|
/** The scope {@link attach} settled on, which {@link summary} follows. */
|
|
@@ -44,6 +46,7 @@ var ChainsNamespace = class extends require_offchain_AbstractOffchainNamespace.A
|
|
|
44
46
|
...options,
|
|
45
47
|
chainIds: []
|
|
46
48
|
});
|
|
49
|
+
this.#transports = options.transports ?? {};
|
|
47
50
|
}
|
|
48
51
|
/**
|
|
49
52
|
* Reads the chain list off the backend and builds a client for each chain
|
|
@@ -147,14 +150,17 @@ var ChainsNamespace = class extends require_offchain_AbstractOffchainNamespace.A
|
|
|
147
150
|
this.#chains = chains;
|
|
148
151
|
}
|
|
149
152
|
/**
|
|
150
|
-
* A client over the
|
|
151
|
-
* has no definition
|
|
153
|
+
* A client over the transport the caller gave for the chain, or over the
|
|
154
|
+
* chain's own public endpoints, or nothing when this SDK has no definition
|
|
155
|
+
* for it.
|
|
152
156
|
*
|
|
153
157
|
* The backend will not hand over its endpoints — they carry provider keys —
|
|
154
|
-
* so the chain definition is all there is to go on
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
+
* so without `transports` the chain definition is all there is to go on,
|
|
159
|
+
* and its public endpoints rate limit anything past a glance. A caller that
|
|
160
|
+
* reads in earnest supplies its own. A chain the SDK does not know stays in
|
|
161
|
+
* {@link list}, because the backend serves it and its rows are readable
|
|
162
|
+
* through the backend; only the calls that have to reach it directly fail,
|
|
163
|
+
* and they say which chain they could not reach.
|
|
158
164
|
**/
|
|
159
165
|
#client(chainId) {
|
|
160
166
|
let chain;
|
|
@@ -164,6 +170,11 @@ var ChainsNamespace = class extends require_offchain_AbstractOffchainNamespace.A
|
|
|
164
170
|
this.logger?.warn(`no chain definition for ${chainId}: it will be listed, but nothing can be read off it directly`);
|
|
165
171
|
return;
|
|
166
172
|
}
|
|
173
|
+
const supplied = this.#transports[chainId];
|
|
174
|
+
if (supplied) return (0, viem.createPublicClient)({
|
|
175
|
+
chain,
|
|
176
|
+
transport: supplied
|
|
177
|
+
});
|
|
167
178
|
const urls = chain.rpcUrls.default.http;
|
|
168
179
|
if (urls.length === 0) {
|
|
169
180
|
this.logger?.warn(`no public endpoint for chain ${chainId}`);
|
|
@@ -7,10 +7,8 @@ const require_onchain_base_ChainContractsRegister = require("../../../onchain/ba
|
|
|
7
7
|
const require_onchain_OnchainSDK = require("../../../onchain/OnchainSDK.js");
|
|
8
8
|
require("../../../onchain/index.js");
|
|
9
9
|
const require_permissionless_api_errors = require("../errors.js");
|
|
10
|
-
const require_permissionless_utils_literals = require("../../utils/literals.js");
|
|
11
10
|
const require_permissionless_bindings_price_feed_store = require("../../bindings/price-feed-store.js");
|
|
12
11
|
require("../../deployment/addresses.js");
|
|
13
|
-
const require_permissionless_bindings_address_provider = require("../../bindings/address-provider.js");
|
|
14
12
|
const require_permissionless_bindings_instance_manager = require("../../bindings/instance-manager.js");
|
|
15
13
|
const require_permissionless_utils_governance_batch = require("../../utils/governance/batch.js");
|
|
16
14
|
const require_permissionless_utils_price_update_get_updatable_feeds = require("../../utils/price-update/get-updatable-feeds.js");
|
|
@@ -163,8 +161,7 @@ var InstanceOwnerTransactions = class {
|
|
|
163
161
|
**/
|
|
164
162
|
async #batchContext(chainId) {
|
|
165
163
|
const client = this.#chains.client(chainId);
|
|
166
|
-
const
|
|
167
|
-
const instanceManager = new require_permissionless_bindings_instance_manager.InstanceManagerContract(await addressProvider.getAddressOrRevert(require_permissionless_utils_literals.INSTANCE_MANAGER), new require_onchain_base_ChainContractsRegister.ChainContractsRegister(client));
|
|
164
|
+
const instanceManager = new require_permissionless_bindings_instance_manager.InstanceManagerContract("0x77777777144339Bdc3aCceE992D8d4D31734CB2e", new require_onchain_base_ChainContractsRegister.ChainContractsRegister(client));
|
|
168
165
|
return {
|
|
169
166
|
chainId,
|
|
170
167
|
client,
|
|
@@ -2,7 +2,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_permissionless_bindings_bytecode_repository = require("./bytecode-repository.js");
|
|
3
3
|
const require_permissionless_bindings_pricefeeds_index = require("./pricefeeds/index.js");
|
|
4
4
|
const require_permissionless_bindings_price_feed_store = require("./price-feed-store.js");
|
|
5
|
-
const require_permissionless_bindings_address_provider = require("./address-provider.js");
|
|
6
5
|
const require_permissionless_bindings_compressors_token_compressor = require("./compressors/token-compressor.js");
|
|
7
6
|
const require_permissionless_bindings_compressors_withdrawal_compressor = require("./compressors/withdrawal-compressor.js");
|
|
8
7
|
require("./compressors/index.js");
|
|
@@ -10,6 +9,7 @@ const require_permissionless_bindings_router_routing_manager = require("./router
|
|
|
10
9
|
require("./router/index.js");
|
|
11
10
|
const require_permissionless_bindings_treasury_splitter = require("./treasury-splitter.js");
|
|
12
11
|
const require_permissionless_bindings_instance_manager = require("./instance-manager.js");
|
|
12
|
+
const require_permissionless_bindings_address_provider = require("./address-provider.js");
|
|
13
13
|
const require_permissionless_bindings_market_configurator_factory = require("./market-configurator-factory.js");
|
|
14
14
|
const require_permissionless_bindings_cross_chain_multisig = require("./cross-chain-multisig.js");
|
|
15
15
|
const require_permissionless_bindings_types = require("./types.js");
|
|
@@ -12,7 +12,6 @@ const require_permissionless_utils_abi_encoder = require("./utils/abi-encoder.js
|
|
|
12
12
|
const require_permissionless_api_deploy_PermissionlessDeploy = require("./api/deploy/PermissionlessDeploy.js");
|
|
13
13
|
const require_permissionless_utils_price_update_get_prices = require("./utils/price-update/get-prices.js");
|
|
14
14
|
const require_permissionless_api_oracles_PermissionlessOracles = require("./api/oracles/PermissionlessOracles.js");
|
|
15
|
-
const require_permissionless_bindings_address_provider = require("./bindings/address-provider.js");
|
|
16
15
|
const require_permissionless_bindings_compressors_token_compressor = require("./bindings/compressors/token-compressor.js");
|
|
17
16
|
const require_permissionless_bindings_compressors_withdrawal_compressor = require("./bindings/compressors/withdrawal-compressor.js");
|
|
18
17
|
const require_permissionless_bindings_router_routing_manager = require("./bindings/router/routing-manager.js");
|
|
@@ -23,6 +22,7 @@ const require_permissionless_utils_price_update_get_updatable_feeds = require(".
|
|
|
23
22
|
const require_permissionless_api_transactions_InstanceOwnerTransactions = require("./api/transactions/InstanceOwnerTransactions.js");
|
|
24
23
|
const require_permissionless_api_GearboxPermissionless = require("./api/GearboxPermissionless.js");
|
|
25
24
|
require("./api/index.js");
|
|
25
|
+
const require_permissionless_bindings_address_provider = require("./bindings/address-provider.js");
|
|
26
26
|
const require_permissionless_bindings_market_configurator_factory = require("./bindings/market-configurator-factory.js");
|
|
27
27
|
const require_permissionless_bindings_cross_chain_multisig = require("./bindings/cross-chain-multisig.js");
|
|
28
28
|
const require_permissionless_utils_create2 = require("./utils/create2.js");
|
|
@@ -125,7 +125,7 @@ var CreditAccountsServiceV310 = class extends SDKConstruct {
|
|
|
125
125
|
async partiallyLiquidate(props) {
|
|
126
126
|
const { account, to } = props;
|
|
127
127
|
const cm = this.sdk.marketRegister.findCreditManager(account.creditManager);
|
|
128
|
-
const { tokenOut, repaidAmount, minSeizedAmount } =
|
|
128
|
+
const { tokenOut, repaidAmount, minSeizedAmount } = this.sdk.liquidations.getPartialLiquidationParams(account, props);
|
|
129
129
|
const updates = await this.getOnDemandPriceUpdates(account, true);
|
|
130
130
|
return cm.creditFacade.partiallyLiquidateCreditAccount(account.creditAccount, tokenOut, repaidAmount, minSeizedAmount, to, updates);
|
|
131
131
|
}
|
|
@@ -10,6 +10,7 @@ import { fetchCreditAccountSlice, toCreditAccountSlice } from "./intents/utils/c
|
|
|
10
10
|
import { DIRECT_TRANSFERS_QUOTA, calcDefaultQuota, calcQuotaUpdate, calcRecommendedQuota, maxAmountForQuota, roundUpQuota } from "./quota-utils.js";
|
|
11
11
|
import { CreditAccountOperationsService } from "./intents/index.js";
|
|
12
12
|
import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./liquidations/constants.js";
|
|
13
|
+
import { optimalPartialLiquidation, partialLiquidationParams } from "./liquidations/partialLiquidation.js";
|
|
13
14
|
import { LiquidationsService } from "./liquidations/LiquidationsService.js";
|
|
14
15
|
import { MultichainLiquidationsService } from "./liquidations/MultichainLiquidationsService.js";
|
|
15
16
|
import "./liquidations/index.js";
|
|
@@ -25,4 +26,4 @@ import { toWithdrawalStatus } from "./withdrawal-compressor/types.js";
|
|
|
25
26
|
import { WithdrawalCompressorV313Contract } from "./withdrawal-compressor/WithdrawalCompressorV313Contract.js";
|
|
26
27
|
import { createWithdrawalCompressor } from "./withdrawal-compressor/createWithdrawalCompressor.js";
|
|
27
28
|
import "./withdrawal-compressor/index.js";
|
|
28
|
-
export { AbstractWithdrawalCompressorContract, AccountBotsService, CreditAccountCompressor, CreditAccountCompressorV310Contract, CreditAccountOperationsService, CreditAccountsServiceV310, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, DIRECT_TRANSFERS_QUOTA, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService, PeripheryCompressorV310Contract, RedemptionLoggerV310Contract, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, calcDefaultQuota, calcQuotaUpdate, calcRecommendedQuota, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, encodeDelayedIntent, fetchCreditAccountSlice, getWithdrawalCompressorAddress, iCreditAccountAbi, isPhantomToken, maxAmountForQuota, roundUpQuota, toClaimableWithdrawal, toCreditAccountSlice, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
|
|
29
|
+
export { AbstractWithdrawalCompressorContract, AccountBotsService, CreditAccountCompressor, CreditAccountCompressorV310Contract, CreditAccountOperationsService, CreditAccountsServiceV310, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, DIRECT_TRANSFERS_QUOTA, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService, PeripheryCompressorV310Contract, RedemptionLoggerV310Contract, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, calcDefaultQuota, calcQuotaUpdate, calcRecommendedQuota, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, encodeDelayedIntent, fetchCreditAccountSlice, getWithdrawalCompressorAddress, iCreditAccountAbi, isPhantomToken, maxAmountForQuota, optimalPartialLiquidation, partialLiquidationParams, roundUpQuota, toClaimableWithdrawal, toCreditAccountSlice, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
|
|
@@ -20,6 +20,7 @@ import { SecuritizeLiquidatorContract } from "../../market/rwa/securitize/Securi
|
|
|
20
20
|
import "../../market/rwa/securitize/index.js";
|
|
21
21
|
import "../../market/index.js";
|
|
22
22
|
import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./constants.js";
|
|
23
|
+
import { optimalPartialLiquidation, partialLiquidationParams } from "./partialLiquidation.js";
|
|
23
24
|
import { skipLiquidatableAccount } from "./skipLiquidatableAccount.js";
|
|
24
25
|
//#region src/onchain/accounts/liquidations/LiquidationsService.ts
|
|
25
26
|
/**
|
|
@@ -87,6 +88,44 @@ var LiquidationsService = class extends SDKConstruct {
|
|
|
87
88
|
};
|
|
88
89
|
}
|
|
89
90
|
/**
|
|
91
|
+
* Optimal partial liquidation of a credit account: the collateral to seize
|
|
92
|
+
* and the amounts that bring its health factor close to `optimalHF`.
|
|
93
|
+
*
|
|
94
|
+
* Prices come from the last synced oracle state and `ca`, not from fresh
|
|
95
|
+
* price updates. Withdrawal phantom tokens are never seized.
|
|
96
|
+
*
|
|
97
|
+
* @param ca - Credit account to partially liquidate.
|
|
98
|
+
* @param optimalHF - Health factor to aim for, in basis points. Defaults to
|
|
99
|
+
* {@link CreditSuite.optimalHFForPartialLiquidation}.
|
|
100
|
+
* @throws If no `tokenOut` can be picked.
|
|
101
|
+
**/
|
|
102
|
+
getOptimalPartialLiquidation(ca, optimalHF) {
|
|
103
|
+
return optimalPartialLiquidation({
|
|
104
|
+
suite: this.sdk.marketRegister.findCreditManager(ca.creditManager),
|
|
105
|
+
account: ca,
|
|
106
|
+
optimalHF,
|
|
107
|
+
exclude: (token) => this.#isWithdrawalPhantom(token)
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Everything a partial liquidation of a credit account needs, with any
|
|
112
|
+
* parameter the caller pinned down taken as given and the rest derived from
|
|
113
|
+
* current state. A derived `tokenOut` is never a withdrawal phantom token.
|
|
114
|
+
*
|
|
115
|
+
* @param ca - Credit account to partially liquidate.
|
|
116
|
+
* @param overrides - Parameters to use instead of the derived defaults.
|
|
117
|
+
* @throws If a derived `tokenOut` cannot be picked, or if the seized token is
|
|
118
|
+
* not a collateral token of the credit manager.
|
|
119
|
+
**/
|
|
120
|
+
getPartialLiquidationParams(ca, overrides) {
|
|
121
|
+
return partialLiquidationParams({
|
|
122
|
+
suite: this.sdk.marketRegister.findCreditManager(ca.creditManager),
|
|
123
|
+
account: ca,
|
|
124
|
+
overrides,
|
|
125
|
+
exclude: (token) => this.#isWithdrawalPhantom(token)
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
90
129
|
* Returns the status of delayed-withdrawal positions (redemption receipts)
|
|
91
130
|
* owned by a liquidator wallet: what is receivable, how much, and when it
|
|
92
131
|
* becomes claimable.
|
|
@@ -278,11 +317,14 @@ var LiquidationsService = class extends SDKConstruct {
|
|
|
278
317
|
value: estimatedProfit,
|
|
279
318
|
valueUsd: usd(estimatedProfit)
|
|
280
319
|
},
|
|
281
|
-
isDelayed: ca.tokens.some((t) => t.balance > 10n &&
|
|
320
|
+
isDelayed: ca.tokens.some((t) => t.balance > 10n && this.#isWithdrawalPhantom(t.token)),
|
|
282
321
|
paused: suite.creditFacade.isPaused,
|
|
283
322
|
rwa: market.rwa
|
|
284
323
|
};
|
|
285
324
|
}
|
|
325
|
+
#isWithdrawalPhantom(token) {
|
|
326
|
+
return !!this.sdk.withdrawalCompressor?.getWithdrawalSourceToken(token);
|
|
327
|
+
}
|
|
286
328
|
#mainAsset(ca, market, fallback) {
|
|
287
329
|
const asset = dominantCollateral(ca, market);
|
|
288
330
|
if (!asset) return fallback;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./constants.js";
|
|
2
|
+
import { optimalPartialLiquidation, partialLiquidationParams } from "./partialLiquidation.js";
|
|
2
3
|
import { LiquidationsService } from "./LiquidationsService.js";
|
|
3
4
|
import { MultichainLiquidationsService } from "./MultichainLiquidationsService.js";
|
|
4
5
|
import "./types.js";
|
|
5
|
-
export { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService };
|
|
6
|
+
export { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService, optimalPartialLiquidation, partialLiquidationParams };
|