@gearbox-protocol/sdk 17.12.2 → 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/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/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/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;
|
|
@@ -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 };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { minSeizedAmount, optimalPartialLiquidationAmounts } from "../../market/math.js";
|
|
2
|
+
import { dominantCollateral } from "../../market/credit/collateralUtils.js";
|
|
3
|
+
import "../../market/index.js";
|
|
4
|
+
//#region src/onchain/accounts/liquidations/partialLiquidation.ts
|
|
5
|
+
/**
|
|
6
|
+
* Optimal partial liquidation of an account: the collateral to seize and the
|
|
7
|
+
* amounts that bring its health factor close to `optimalHF`.
|
|
8
|
+
*
|
|
9
|
+
* Ported from solidity, without the price updates the contract applies first:
|
|
10
|
+
* https://github.com/Gearbox-protocol/router-v3/blob/56e2d515ec6d9bb1e324e71c3708e59710779b24/contracts/liquidation/AbstractLiquidator.sol#L252
|
|
11
|
+
*
|
|
12
|
+
* @throws If no `tokenOut` can be picked.
|
|
13
|
+
**/
|
|
14
|
+
function optimalPartialLiquidation({ suite, account, optimalHF = suite.optimalHFForPartialLiquidation(account), exclude }) {
|
|
15
|
+
const tokenOut = bestTokenOut(suite, account, exclude);
|
|
16
|
+
return {
|
|
17
|
+
tokenOut,
|
|
18
|
+
...optimalAmounts(suite, account, tokenOut, optimalHF)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Everything a partial liquidation of credit account needs, with any parameter
|
|
23
|
+
* the caller pinned down taken as given and the rest derived from current state.
|
|
24
|
+
*
|
|
25
|
+
* @throws If a derived `tokenOut` cannot be picked, or if the seized token is
|
|
26
|
+
* not a collateral token of the credit manager.
|
|
27
|
+
**/
|
|
28
|
+
function partialLiquidationParams({ suite, account, overrides = {}, exclude }) {
|
|
29
|
+
const tokenOut = overrides.tokenOut ?? bestTokenOut(suite, account, exclude);
|
|
30
|
+
const optimalHF = overrides.optimalHF ?? suite.optimalHFForPartialLiquidation(account);
|
|
31
|
+
const repaidAmount = overrides.repaidAmount ?? optimalAmounts(suite, account, tokenOut, optimalHF).repaidAmount;
|
|
32
|
+
return {
|
|
33
|
+
tokenOut,
|
|
34
|
+
optimalHF,
|
|
35
|
+
repaidAmount,
|
|
36
|
+
minSeizedAmount: overrides.minSeizedAmount ?? minSeizedAmountOf(suite, tokenOut, repaidAmount)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function bestTokenOut(suite, account, exclude) {
|
|
40
|
+
const collateral = dominantCollateral(account, suite.market, exclude);
|
|
41
|
+
if (!collateral) throw new Error(`cannot determine tokenOut for partial liquidation of ${suite.register.labelAddress(account.creditAccount)}: no enabled non-underlying collateral with value`);
|
|
42
|
+
return collateral;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* @throws If `tokenOut` is not a collateral token of the credit manager.
|
|
46
|
+
**/
|
|
47
|
+
function optimalAmounts(suite, account, tokenOut, optimalHF) {
|
|
48
|
+
const { creditManager: cm, market } = suite;
|
|
49
|
+
const { feeLiquidation, liquidationDiscount } = suite.liquidationFees();
|
|
50
|
+
const ltTokenOut = cm.liquidationThresholds.get(tokenOut);
|
|
51
|
+
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)}`);
|
|
52
|
+
return optimalPartialLiquidationAmounts({
|
|
53
|
+
totalDebt: account.debt + account.accruedInterest + account.accruedFees,
|
|
54
|
+
twvUnderlying: market.priceOracle.convertFromUSD(market.underlying, account.twvUSD),
|
|
55
|
+
minDebt: suite.creditFacade.minDebt,
|
|
56
|
+
optimalHF,
|
|
57
|
+
liquidationDiscount: BigInt(liquidationDiscount),
|
|
58
|
+
discount: BigInt(liquidationDiscount) - BigInt(feeLiquidation),
|
|
59
|
+
ltTokenOut: BigInt(ltTokenOut)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Minimum amount of `token` that must be seized when repaying `repaidAmount`
|
|
64
|
+
* of underlying.
|
|
65
|
+
**/
|
|
66
|
+
function minSeizedAmountOf(suite, token, repaidAmount) {
|
|
67
|
+
const { market } = suite;
|
|
68
|
+
const tokenAmount = market.priceOracle.convert(market.underlying, token, repaidAmount);
|
|
69
|
+
return minSeizedAmount(tokenAmount, suite.liquidationFees().liquidationDiscount);
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
export { optimalPartialLiquidation, partialLiquidationParams };
|