@gearbox-protocol/sdk 14.3.0 → 14.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/dev/index.js +2 -0
- package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +103 -16
- package/dist/esm/dev/index.js +1 -0
- package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +103 -16
- package/dist/types/dev/index.d.ts +1 -0
- package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +0 -4
- package/dist/types/sdk/accounts/types.d.ts +17 -28
- package/package.json +1 -1
package/dist/cjs/dev/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(dev_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(dev_exports);
|
|
26
26
|
__reExport(dev_exports, require("./AccountOpener.js"), module.exports);
|
|
27
27
|
__reExport(dev_exports, require("./calcLiquidatableLTs.js"), module.exports);
|
|
28
|
+
__reExport(dev_exports, require("./claimDSToken.js"), module.exports);
|
|
28
29
|
__reExport(dev_exports, require("./claimFromFaucet.js"), module.exports);
|
|
29
30
|
__reExport(dev_exports, require("./create2.js"), module.exports);
|
|
30
31
|
__reExport(dev_exports, require("./createAnvilClient.js"), module.exports);
|
|
@@ -49,6 +50,7 @@ __reExport(dev_exports, require("./types.js"), module.exports);
|
|
|
49
50
|
logSplitterTransport,
|
|
50
51
|
...require("./AccountOpener.js"),
|
|
51
52
|
...require("./calcLiquidatableLTs.js"),
|
|
53
|
+
...require("./claimDSToken.js"),
|
|
52
54
|
...require("./claimFromFaucet.js"),
|
|
53
55
|
...require("./create2.js"),
|
|
54
56
|
...require("./createAnvilClient.js"),
|
|
@@ -454,10 +454,63 @@ class CreditAccountsServiceV310 extends import_base.SDKConstruct {
|
|
|
454
454
|
};
|
|
455
455
|
}
|
|
456
456
|
/**
|
|
457
|
-
* {@inheritDoc ICreditAccountsService.
|
|
457
|
+
* {@inheritDoc ICreditAccountsService.partiallyLiquidate}
|
|
458
458
|
*/
|
|
459
|
-
|
|
460
|
-
const { account,
|
|
459
|
+
async partiallyLiquidate(props) {
|
|
460
|
+
const { account, to } = props;
|
|
461
|
+
const tokenOut = props.tokenOut ?? this.#getBestTokenOut(account);
|
|
462
|
+
const optimalHF = props.optimalHF ?? this.getOptimalHFForPartialLiquidation(account);
|
|
463
|
+
const repaidAmount = props.repaidAmount ?? this.#calcOptimalRepaidAmount(account, tokenOut, optimalHF);
|
|
464
|
+
const minSeizedAmount = props.minSeizedAmount ?? this.#calcMinSeizedAmount(account, tokenOut, repaidAmount);
|
|
465
|
+
const cm = this.sdk.marketRegister.findCreditManager(account.creditManager);
|
|
466
|
+
const updates = await this.getOnDemandPriceUpdates(account, true);
|
|
467
|
+
const tx = cm.creditFacade.partiallyLiquidateCreditAccount(
|
|
468
|
+
account.creditAccount,
|
|
469
|
+
tokenOut,
|
|
470
|
+
repaidAmount,
|
|
471
|
+
minSeizedAmount,
|
|
472
|
+
to,
|
|
473
|
+
updates
|
|
474
|
+
);
|
|
475
|
+
return tx;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Picks the most valuable enabled non-underlying collateral token on the
|
|
479
|
+
* credit account (by oracle value in underlying).
|
|
480
|
+
*
|
|
481
|
+
* Ported from solidity:
|
|
482
|
+
* https://github.com/Gearbox-protocol/router-v3/blob/main/contracts/liquidation/AbstractLiquidator.sol#L270
|
|
483
|
+
*/
|
|
484
|
+
#getBestTokenOut(account) {
|
|
485
|
+
const market = this.sdk.marketRegister.findByCreditManager(
|
|
486
|
+
account.creditManager
|
|
487
|
+
);
|
|
488
|
+
const underlying = market.underlying;
|
|
489
|
+
let bestVal = 0n;
|
|
490
|
+
let bestToken;
|
|
491
|
+
for (const t of account.tokens) {
|
|
492
|
+
if (t.token === underlying) continue;
|
|
493
|
+
if ((t.mask & account.enabledTokensMask) === 0n) continue;
|
|
494
|
+
if (t.balance === 0n) continue;
|
|
495
|
+
const val = market.priceOracle.convert(t.token, underlying, t.balance);
|
|
496
|
+
if (val > bestVal) {
|
|
497
|
+
bestVal = val;
|
|
498
|
+
bestToken = t.token;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (!bestToken) {
|
|
502
|
+
throw new Error(
|
|
503
|
+
`cannot determine tokenOut for partial liquidation of ${this.sdk.labelAddress(account.creditAccount)}: no enabled non-underlying collateral with value`
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
return bestToken;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Returns the minimum amount of `token` collateral that must be seized when
|
|
510
|
+
* repaying `repaidAmount` of underlying. Mirrors the on-chain liquidation
|
|
511
|
+
* discount math, expired-aware.
|
|
512
|
+
*/
|
|
513
|
+
#calcMinSeizedAmount(account, token, repaidAmount) {
|
|
461
514
|
const market = this.sdk.marketRegister.findByCreditManager(
|
|
462
515
|
account.creditManager
|
|
463
516
|
);
|
|
@@ -473,21 +526,55 @@ class CreditAccountsServiceV310 extends import_base.SDKConstruct {
|
|
|
473
526
|
return tokenAmount * 9990n / BigInt(fee);
|
|
474
527
|
}
|
|
475
528
|
/**
|
|
476
|
-
*
|
|
529
|
+
* Computes the optimal `repaidAmount` (in underlying) that brings the credit
|
|
530
|
+
* account's health factor close to `optimalHF` after partial liquidation.
|
|
531
|
+
*
|
|
532
|
+
* Ported from solidity:
|
|
533
|
+
* https://github.com/Gearbox-protocol/router-v3/blob/56e2d515ec6d9bb1e324e71c3708e59710779b24/contracts/liquidation/AbstractLiquidator.sol#L292
|
|
477
534
|
*/
|
|
478
|
-
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
const updates = await this.getOnDemandPriceUpdates(account, true);
|
|
482
|
-
const tx = cm.creditFacade.partiallyLiquidateCreditAccount(
|
|
483
|
-
account.creditAccount,
|
|
484
|
-
token,
|
|
485
|
-
repaidAmount,
|
|
486
|
-
minSeizedAmount,
|
|
487
|
-
to,
|
|
488
|
-
updates
|
|
535
|
+
#calcOptimalRepaidAmount(account, token, optimalHF) {
|
|
536
|
+
const suite = this.sdk.marketRegister.findCreditManager(
|
|
537
|
+
account.creditManager
|
|
489
538
|
);
|
|
490
|
-
|
|
539
|
+
const market = this.sdk.marketRegister.findByCreditManager(
|
|
540
|
+
account.creditManager
|
|
541
|
+
);
|
|
542
|
+
const cm = suite.creditManager;
|
|
543
|
+
const feeLiquidation = suite.isExpired ? cm.feeLiquidationExpired : cm.feeLiquidation;
|
|
544
|
+
const liquidationDiscount = suite.isExpired ? cm.liquidationDiscountExpired : cm.liquidationDiscount;
|
|
545
|
+
const discount = BigInt(liquidationDiscount) - BigInt(feeLiquidation);
|
|
546
|
+
const ltTokenOut = cm.liquidationThresholds.get(token);
|
|
547
|
+
if (ltTokenOut === void 0) {
|
|
548
|
+
throw new Error(
|
|
549
|
+
`token ${this.sdk.labelAddress(token)} is not a collateral token in credit manager ${this.sdk.labelAddress(account.creditManager)}`
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
const totalDebt = account.debt + account.accruedInterest + account.accruedFees;
|
|
553
|
+
const twvUnderlying = market.priceOracle.convertFromUSD(
|
|
554
|
+
market.underlying,
|
|
555
|
+
account.twvUSD
|
|
556
|
+
);
|
|
557
|
+
const denominator = discount * optimalHF / import_constants.PERCENTAGE_FACTOR - BigInt(ltTokenOut);
|
|
558
|
+
if (denominator <= 0n) {
|
|
559
|
+
throw new Error(
|
|
560
|
+
"cannot compute optimal repaid amount: invalid liquidation parameters (discount * hfOptimal <= ltTokenOut)"
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
const numerator = totalDebt * optimalHF - twvUnderlying * import_constants.PERCENTAGE_FACTOR;
|
|
564
|
+
if (numerator <= 0n) {
|
|
565
|
+
return 0n;
|
|
566
|
+
}
|
|
567
|
+
const optimalValueSeized = numerator / denominator;
|
|
568
|
+
let repaidAmount = optimalValueSeized * discount / import_constants.PERCENTAGE_FACTOR;
|
|
569
|
+
const minDebt = suite.creditFacade.minDebt;
|
|
570
|
+
if (totalDebt < minDebt) {
|
|
571
|
+
return 0n;
|
|
572
|
+
}
|
|
573
|
+
const surplusDebt = totalDebt - minDebt;
|
|
574
|
+
if (repaidAmount > surplusDebt) {
|
|
575
|
+
repaidAmount = surplusDebt * 999n / 1000n;
|
|
576
|
+
}
|
|
577
|
+
return repaidAmount;
|
|
491
578
|
}
|
|
492
579
|
/**
|
|
493
580
|
* {@inheritDoc ICreditAccountsService.closeCreditAccount}
|
package/dist/esm/dev/index.js
CHANGED
|
@@ -449,10 +449,63 @@ class CreditAccountsServiceV310 extends SDKConstruct {
|
|
|
449
449
|
};
|
|
450
450
|
}
|
|
451
451
|
/**
|
|
452
|
-
* {@inheritDoc ICreditAccountsService.
|
|
452
|
+
* {@inheritDoc ICreditAccountsService.partiallyLiquidate}
|
|
453
453
|
*/
|
|
454
|
-
|
|
455
|
-
const { account,
|
|
454
|
+
async partiallyLiquidate(props) {
|
|
455
|
+
const { account, to } = props;
|
|
456
|
+
const tokenOut = props.tokenOut ?? this.#getBestTokenOut(account);
|
|
457
|
+
const optimalHF = props.optimalHF ?? this.getOptimalHFForPartialLiquidation(account);
|
|
458
|
+
const repaidAmount = props.repaidAmount ?? this.#calcOptimalRepaidAmount(account, tokenOut, optimalHF);
|
|
459
|
+
const minSeizedAmount = props.minSeizedAmount ?? this.#calcMinSeizedAmount(account, tokenOut, repaidAmount);
|
|
460
|
+
const cm = this.sdk.marketRegister.findCreditManager(account.creditManager);
|
|
461
|
+
const updates = await this.getOnDemandPriceUpdates(account, true);
|
|
462
|
+
const tx = cm.creditFacade.partiallyLiquidateCreditAccount(
|
|
463
|
+
account.creditAccount,
|
|
464
|
+
tokenOut,
|
|
465
|
+
repaidAmount,
|
|
466
|
+
minSeizedAmount,
|
|
467
|
+
to,
|
|
468
|
+
updates
|
|
469
|
+
);
|
|
470
|
+
return tx;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Picks the most valuable enabled non-underlying collateral token on the
|
|
474
|
+
* credit account (by oracle value in underlying).
|
|
475
|
+
*
|
|
476
|
+
* Ported from solidity:
|
|
477
|
+
* https://github.com/Gearbox-protocol/router-v3/blob/main/contracts/liquidation/AbstractLiquidator.sol#L270
|
|
478
|
+
*/
|
|
479
|
+
#getBestTokenOut(account) {
|
|
480
|
+
const market = this.sdk.marketRegister.findByCreditManager(
|
|
481
|
+
account.creditManager
|
|
482
|
+
);
|
|
483
|
+
const underlying = market.underlying;
|
|
484
|
+
let bestVal = 0n;
|
|
485
|
+
let bestToken;
|
|
486
|
+
for (const t of account.tokens) {
|
|
487
|
+
if (t.token === underlying) continue;
|
|
488
|
+
if ((t.mask & account.enabledTokensMask) === 0n) continue;
|
|
489
|
+
if (t.balance === 0n) continue;
|
|
490
|
+
const val = market.priceOracle.convert(t.token, underlying, t.balance);
|
|
491
|
+
if (val > bestVal) {
|
|
492
|
+
bestVal = val;
|
|
493
|
+
bestToken = t.token;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (!bestToken) {
|
|
497
|
+
throw new Error(
|
|
498
|
+
`cannot determine tokenOut for partial liquidation of ${this.sdk.labelAddress(account.creditAccount)}: no enabled non-underlying collateral with value`
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
return bestToken;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Returns the minimum amount of `token` collateral that must be seized when
|
|
505
|
+
* repaying `repaidAmount` of underlying. Mirrors the on-chain liquidation
|
|
506
|
+
* discount math, expired-aware.
|
|
507
|
+
*/
|
|
508
|
+
#calcMinSeizedAmount(account, token, repaidAmount) {
|
|
456
509
|
const market = this.sdk.marketRegister.findByCreditManager(
|
|
457
510
|
account.creditManager
|
|
458
511
|
);
|
|
@@ -468,21 +521,55 @@ class CreditAccountsServiceV310 extends SDKConstruct {
|
|
|
468
521
|
return tokenAmount * 9990n / BigInt(fee);
|
|
469
522
|
}
|
|
470
523
|
/**
|
|
471
|
-
*
|
|
524
|
+
* Computes the optimal `repaidAmount` (in underlying) that brings the credit
|
|
525
|
+
* account's health factor close to `optimalHF` after partial liquidation.
|
|
526
|
+
*
|
|
527
|
+
* Ported from solidity:
|
|
528
|
+
* https://github.com/Gearbox-protocol/router-v3/blob/56e2d515ec6d9bb1e324e71c3708e59710779b24/contracts/liquidation/AbstractLiquidator.sol#L292
|
|
472
529
|
*/
|
|
473
|
-
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
const updates = await this.getOnDemandPriceUpdates(account, true);
|
|
477
|
-
const tx = cm.creditFacade.partiallyLiquidateCreditAccount(
|
|
478
|
-
account.creditAccount,
|
|
479
|
-
token,
|
|
480
|
-
repaidAmount,
|
|
481
|
-
minSeizedAmount,
|
|
482
|
-
to,
|
|
483
|
-
updates
|
|
530
|
+
#calcOptimalRepaidAmount(account, token, optimalHF) {
|
|
531
|
+
const suite = this.sdk.marketRegister.findCreditManager(
|
|
532
|
+
account.creditManager
|
|
484
533
|
);
|
|
485
|
-
|
|
534
|
+
const market = this.sdk.marketRegister.findByCreditManager(
|
|
535
|
+
account.creditManager
|
|
536
|
+
);
|
|
537
|
+
const cm = suite.creditManager;
|
|
538
|
+
const feeLiquidation = suite.isExpired ? cm.feeLiquidationExpired : cm.feeLiquidation;
|
|
539
|
+
const liquidationDiscount = suite.isExpired ? cm.liquidationDiscountExpired : cm.liquidationDiscount;
|
|
540
|
+
const discount = BigInt(liquidationDiscount) - BigInt(feeLiquidation);
|
|
541
|
+
const ltTokenOut = cm.liquidationThresholds.get(token);
|
|
542
|
+
if (ltTokenOut === void 0) {
|
|
543
|
+
throw new Error(
|
|
544
|
+
`token ${this.sdk.labelAddress(token)} is not a collateral token in credit manager ${this.sdk.labelAddress(account.creditManager)}`
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
const totalDebt = account.debt + account.accruedInterest + account.accruedFees;
|
|
548
|
+
const twvUnderlying = market.priceOracle.convertFromUSD(
|
|
549
|
+
market.underlying,
|
|
550
|
+
account.twvUSD
|
|
551
|
+
);
|
|
552
|
+
const denominator = discount * optimalHF / PERCENTAGE_FACTOR - BigInt(ltTokenOut);
|
|
553
|
+
if (denominator <= 0n) {
|
|
554
|
+
throw new Error(
|
|
555
|
+
"cannot compute optimal repaid amount: invalid liquidation parameters (discount * hfOptimal <= ltTokenOut)"
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
const numerator = totalDebt * optimalHF - twvUnderlying * PERCENTAGE_FACTOR;
|
|
559
|
+
if (numerator <= 0n) {
|
|
560
|
+
return 0n;
|
|
561
|
+
}
|
|
562
|
+
const optimalValueSeized = numerator / denominator;
|
|
563
|
+
let repaidAmount = optimalValueSeized * discount / PERCENTAGE_FACTOR;
|
|
564
|
+
const minDebt = suite.creditFacade.minDebt;
|
|
565
|
+
if (totalDebt < minDebt) {
|
|
566
|
+
return 0n;
|
|
567
|
+
}
|
|
568
|
+
const surplusDebt = totalDebt - minDebt;
|
|
569
|
+
if (repaidAmount > surplusDebt) {
|
|
570
|
+
repaidAmount = surplusDebt * 999n / 1000n;
|
|
571
|
+
}
|
|
572
|
+
return repaidAmount;
|
|
486
573
|
}
|
|
487
574
|
/**
|
|
488
575
|
* {@inheritDoc ICreditAccountsService.closeCreditAccount}
|
|
@@ -64,10 +64,6 @@ export declare class CreditAccountsServiceV310 extends SDKConstruct implements I
|
|
|
64
64
|
* {@inheritDoc ICreditAccountsService.fullyLiquidate}
|
|
65
65
|
**/
|
|
66
66
|
fullyLiquidate(props: FullyLiquidateProps): Promise<FullyLiquidateResult>;
|
|
67
|
-
/**
|
|
68
|
-
* {@inheritDoc ICreditAccountsService.calcMinSeizedAmount}
|
|
69
|
-
*/
|
|
70
|
-
calcMinSeizedAmount(props: PartiallyLiquidateProps): bigint;
|
|
71
67
|
/**
|
|
72
68
|
* {@inheritDoc ICreditAccountsService.partiallyLiquidate}
|
|
73
69
|
*/
|
|
@@ -488,41 +488,37 @@ export interface FullyLiquidateProps {
|
|
|
488
488
|
*/
|
|
489
489
|
debtOnly?: boolean;
|
|
490
490
|
}
|
|
491
|
-
export interface CalcMinSeizedAmountProps {
|
|
492
|
-
/**
|
|
493
|
-
* Credit account to liquidate
|
|
494
|
-
*/
|
|
495
|
-
account: RouterCASlice;
|
|
496
|
-
/**
|
|
497
|
-
* Collateral token to seize
|
|
498
|
-
*/
|
|
499
|
-
token: Address;
|
|
500
|
-
/**
|
|
501
|
-
* Amount of underlying token to repay
|
|
502
|
-
*/
|
|
503
|
-
repaidAmount: bigint;
|
|
504
|
-
}
|
|
505
491
|
export interface PartiallyLiquidateProps {
|
|
506
492
|
/**
|
|
507
493
|
* Credit account to liquidate
|
|
508
494
|
*/
|
|
509
|
-
account:
|
|
495
|
+
account: CreditAccountData;
|
|
510
496
|
/**
|
|
511
497
|
* Address to transfer underlying left after liquidation
|
|
512
498
|
*/
|
|
513
499
|
to: Address;
|
|
514
500
|
/**
|
|
515
|
-
* Collateral token to seize
|
|
501
|
+
* Collateral token to seize.
|
|
502
|
+
* If omitted, the most valuable enabled non-underlying collateral token
|
|
503
|
+
* (by oracle)
|
|
516
504
|
*/
|
|
517
|
-
|
|
505
|
+
tokenOut?: Address;
|
|
518
506
|
/**
|
|
519
|
-
* Amount of underlying token to repay
|
|
507
|
+
* Amount of underlying token to repay.
|
|
508
|
+
* If omitted, computed internally
|
|
520
509
|
*/
|
|
521
|
-
repaidAmount
|
|
510
|
+
repaidAmount?: bigint;
|
|
522
511
|
/**
|
|
523
|
-
* Minimum amount of `token` to seize from `creditAccount
|
|
512
|
+
* Minimum amount of `token` to seize from `creditAccount`.
|
|
513
|
+
* If omitted, computed internally
|
|
524
514
|
*/
|
|
525
|
-
minSeizedAmount
|
|
515
|
+
minSeizedAmount?: bigint;
|
|
516
|
+
/**
|
|
517
|
+
* Target health factor for partial liquidation (4 digits precision, 10000 = 100%).
|
|
518
|
+
* If omitted, defaults to {@link ICreditAccountsService.getOptimalHFForPartialLiquidation}.
|
|
519
|
+
* Only used when `repaidAmount` is not explicitly provided.
|
|
520
|
+
*/
|
|
521
|
+
optimalHF?: bigint;
|
|
526
522
|
}
|
|
527
523
|
/**
|
|
528
524
|
* EIP-2612 permit signature data for a token, enabling gasless approval for credit account operations.
|
|
@@ -717,13 +713,6 @@ export interface ICreditAccountsService extends Construct {
|
|
|
717
713
|
* @returns Transaction data and optional loss policy data
|
|
718
714
|
*/
|
|
719
715
|
fullyLiquidate(props: FullyLiquidateProps): Promise<FullyLiquidateResult>;
|
|
720
|
-
/**
|
|
721
|
-
* Calculates minimum amount of collateral token to seize from credit account
|
|
722
|
-
* for partial liquidation, can be passed to {@link partiallyLiquidate} as `minSeizedAmount`
|
|
723
|
-
* @param props - {@link CalcMinSeizedAmountProps}
|
|
724
|
-
* @returns Minimum amount of collateral token to seize
|
|
725
|
-
*/
|
|
726
|
-
calcMinSeizedAmount(props: CalcMinSeizedAmountProps): bigint;
|
|
727
716
|
/**
|
|
728
717
|
* Generates transaction to partially liquidate credit account;
|
|
729
718
|
*
|