@gearbox-protocol/sdk 17.0.0 → 17.1.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/onchain/accounts/intents/math.js +6 -3
- package/dist/cjs/onchain/pools/PoolService.js +7 -8
- package/dist/cjs/onchain/validation/bundles/checkPoolOperation.js +2 -8
- package/dist/cjs/onchain/validation/checks/checkPoolLiquidity.js +2 -9
- package/dist/esm/onchain/accounts/intents/math.js +7 -4
- package/dist/esm/onchain/pools/PoolService.js +7 -8
- package/dist/esm/onchain/validation/bundles/checkPoolOperation.js +2 -8
- package/dist/esm/onchain/validation/checks/checkPoolLiquidity.js +2 -9
- package/dist/types/onchain/accounts/intents/math.d.ts +3 -2
- package/dist/types/onchain/pools/PoolService.d.ts +5 -0
- package/dist/types/onchain/pools/types.d.ts +9 -2
- package/dist/types/onchain/validation/bundles/checkPoolOperation.d.ts +1 -7
- package/dist/types/onchain/validation/checks/checkPoolLiquidity.d.ts +1 -8
- package/package.json +1 -1
|
@@ -24,20 +24,23 @@ function proportionalDebt(position, collateralDelta) {
|
|
|
24
24
|
if (position.collateral <= 0n) throw new require_onchain_validation_raise.IntentPreviewError(require_model_errors_operation_errors.insufficientBalance(), "cannot preserve leverage on an account with no collateral");
|
|
25
25
|
return position.debt * collateralDelta / position.collateral;
|
|
26
26
|
}
|
|
27
|
+
/** Share of the debt kept above `minDebt` for interest accrued before sending. */
|
|
28
|
+
const WITHDRAW_DEBT_MARGIN = 1n;
|
|
27
29
|
/**
|
|
28
30
|
* Largest withdrawal (in underlying) that {@link proportionalDebt} can still
|
|
29
|
-
* pay for: the repayment it implies leaves debt at or above `minDebt
|
|
31
|
+
* pay for: the repayment it implies leaves debt at or above `minDebt` plus
|
|
32
|
+
* {@link WITHDRAW_DEBT_MARGIN} of the debt, and
|
|
30
33
|
* strictly less than the collateral goes — the last unit closes the account
|
|
31
34
|
* rather than shrinks it. `0n` when the debt already sits below `minDebt`.
|
|
32
35
|
*
|
|
33
|
-
* Solves `floor(D0 · W / C0) ≤ D0 − minDebt` for `W`.
|
|
36
|
+
* Solves `floor(D0 · W / C0) ≤ D0 − minDebt − margin` for `W`.
|
|
34
37
|
*/
|
|
35
38
|
function maxProportionalWithdrawal(position, debtLimits) {
|
|
36
39
|
const { debt, collateral } = position;
|
|
37
40
|
if (collateral <= 0n) return 0n;
|
|
38
41
|
const allButLast = collateral - 1n;
|
|
39
42
|
if (debt === 0n) return allButLast;
|
|
40
|
-
const repayable = debt - debtLimits.minDebt;
|
|
43
|
+
const repayable = debt - debtLimits.minDebt - debt * WITHDRAW_DEBT_MARGIN / require_onchain_constants_math.PERCENTAGE_FACTOR;
|
|
41
44
|
if (repayable < 0n) return 0n;
|
|
42
45
|
const bound = require_onchain_utils_bigint_math.BigIntMath.ceilDiv(collateral * (repayable + 1n), debt) - 1n;
|
|
43
46
|
return bound < allButLast ? bound : allButLast;
|
|
@@ -155,7 +155,7 @@ var PoolService = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
155
155
|
tokenIn: toTokenAmount(tokenIn, pool.pool.underlyingToShares(amount * require_onchain_constants_math.PERCENTAGE_FACTOR / (require_onchain_constants_math.PERCENTAGE_FACTOR - pool.pool.withdrawFee), true)),
|
|
156
156
|
tokenOut: toTokenAmount(tokenOut, amount),
|
|
157
157
|
zapper: zapper?.baseParams.addr,
|
|
158
|
-
availableLiquidity: this
|
|
158
|
+
availableLiquidity: this.withdrawableLiquidity(poolAddr)
|
|
159
159
|
};
|
|
160
160
|
}
|
|
161
161
|
/**
|
|
@@ -177,7 +177,7 @@ var PoolService = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
177
177
|
tokenIn: toTokenAmount(tokenIn, amount),
|
|
178
178
|
tokenOut: toTokenAmount(tokenOut, pool.pool.sharesToUnderlying(amount) * (require_onchain_constants_math.PERCENTAGE_FACTOR - pool.pool.withdrawFee) / require_onchain_constants_math.PERCENTAGE_FACTOR),
|
|
179
179
|
zapper: zapper?.baseParams.addr,
|
|
180
|
-
availableLiquidity: this
|
|
180
|
+
availableLiquidity: this.withdrawableLiquidity(poolAddr)
|
|
181
181
|
};
|
|
182
182
|
}
|
|
183
183
|
/**
|
|
@@ -406,12 +406,11 @@ var PoolService = class extends require_onchain_base_SDKConstruct.SDKConstruct {
|
|
|
406
406
|
};
|
|
407
407
|
}
|
|
408
408
|
/**
|
|
409
|
-
*
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
return market.priceOracle.toAmount(pool.underlying, pool.pool.availableLiquidity * 99999n / 100000n);
|
|
409
|
+
* {@inheritDoc IPoolsService.withdrawableLiquidity}
|
|
410
|
+
*/
|
|
411
|
+
withdrawableLiquidity(pool) {
|
|
412
|
+
const market = this.sdk.marketRegister.findByPool(pool);
|
|
413
|
+
return market.priceOracle.toAmount(market.pool.underlying, market.pool.pool.availableLiquidity * 99999n / 100000n);
|
|
415
414
|
}
|
|
416
415
|
};
|
|
417
416
|
//#endregion
|
|
@@ -4,13 +4,7 @@ const require_onchain_validation_checks_checkPoolPaused = require("../checks/che
|
|
|
4
4
|
const require_onchain_validation_checks_checkPoolSunset = require("../checks/checkPoolSunset.js");
|
|
5
5
|
require("../checks/index.js");
|
|
6
6
|
//#region src/onchain/validation/bundles/checkPoolOperation.ts
|
|
7
|
-
/**
|
|
8
|
-
* What the pool's own state stops, whichever side of it the wallet is on.
|
|
9
|
-
*
|
|
10
|
-
* The liquidity read is the market's rather than the trimmed figure a
|
|
11
|
-
* simulation carries: a withdrawal sized against that figure has to pass the
|
|
12
|
-
* check that follows it.
|
|
13
|
-
*/
|
|
7
|
+
/** What the pool's own state stops, whichever side of it the wallet is on. */
|
|
14
8
|
function checkPoolOperation(args) {
|
|
15
9
|
const { sdk, pool, isDeposit, tokenOut } = args;
|
|
16
10
|
const market = sdk.marketRegister.findByPool(pool);
|
|
@@ -26,7 +20,7 @@ function checkPoolOperation(args) {
|
|
|
26
20
|
}),
|
|
27
21
|
...isDeposit ? [] : require_onchain_validation_checks_checkPoolLiquidity.checkPoolLiquidity({
|
|
28
22
|
requested: tokenOut.value,
|
|
29
|
-
available:
|
|
23
|
+
available: sdk.pools.withdrawableLiquidity(pool).value,
|
|
30
24
|
underlying: tokenOut.token
|
|
31
25
|
})
|
|
32
26
|
];
|
|
@@ -4,17 +4,10 @@ require("../../../model/index.js");
|
|
|
4
4
|
const require_onchain_validation_helpers_amount = require("../helpers/amount.js");
|
|
5
5
|
require("../helpers/index.js");
|
|
6
6
|
//#region src/onchain/validation/checks/checkPoolLiquidity.ts
|
|
7
|
-
/**
|
|
8
|
-
* What the pool holds, against what is being taken out of it.
|
|
9
|
-
*
|
|
10
|
-
* The operator is not `checkBorrowLimit`'s: a pool holding exactly the amount
|
|
11
|
-
* requested still cannot serve it, so equality is already a refusal. That is
|
|
12
|
-
* the rule the legacy withdrawal validator enforced and it is preserved to the
|
|
13
|
-
* unit.
|
|
14
|
-
*/
|
|
7
|
+
/** What the pool can hand over, against what is being taken out of it. */
|
|
15
8
|
function checkPoolLiquidity(args) {
|
|
16
9
|
const { requested, available, underlying } = args;
|
|
17
|
-
if (requested
|
|
10
|
+
if (requested <= available) return [];
|
|
18
11
|
return [require_model_errors_operation_errors.insufficientPoolLiquidity({
|
|
19
12
|
requested: require_onchain_validation_helpers_amount.amountOf(underlying, requested),
|
|
20
13
|
available: require_onchain_validation_helpers_amount.amountOf(underlying, available),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BigIntMath } from "../../utils/bigint-math.js";
|
|
2
|
-
import { LEVERAGE_DECIMALS } from "../../constants/math.js";
|
|
2
|
+
import { LEVERAGE_DECIMALS, PERCENTAGE_FACTOR } from "../../constants/math.js";
|
|
3
3
|
import { insufficientBalance } from "../../../model/errors/operation-errors.js";
|
|
4
4
|
import "../../../model/index.js";
|
|
5
5
|
import { toToken } from "../../validation/helpers/token.js";
|
|
@@ -23,20 +23,23 @@ function proportionalDebt(position, collateralDelta) {
|
|
|
23
23
|
if (position.collateral <= 0n) throw new IntentPreviewError(insufficientBalance(), "cannot preserve leverage on an account with no collateral");
|
|
24
24
|
return position.debt * collateralDelta / position.collateral;
|
|
25
25
|
}
|
|
26
|
+
/** Share of the debt kept above `minDebt` for interest accrued before sending. */
|
|
27
|
+
const WITHDRAW_DEBT_MARGIN = 1n;
|
|
26
28
|
/**
|
|
27
29
|
* Largest withdrawal (in underlying) that {@link proportionalDebt} can still
|
|
28
|
-
* pay for: the repayment it implies leaves debt at or above `minDebt
|
|
30
|
+
* pay for: the repayment it implies leaves debt at or above `minDebt` plus
|
|
31
|
+
* {@link WITHDRAW_DEBT_MARGIN} of the debt, and
|
|
29
32
|
* strictly less than the collateral goes — the last unit closes the account
|
|
30
33
|
* rather than shrinks it. `0n` when the debt already sits below `minDebt`.
|
|
31
34
|
*
|
|
32
|
-
* Solves `floor(D0 · W / C0) ≤ D0 − minDebt` for `W`.
|
|
35
|
+
* Solves `floor(D0 · W / C0) ≤ D0 − minDebt − margin` for `W`.
|
|
33
36
|
*/
|
|
34
37
|
function maxProportionalWithdrawal(position, debtLimits) {
|
|
35
38
|
const { debt, collateral } = position;
|
|
36
39
|
if (collateral <= 0n) return 0n;
|
|
37
40
|
const allButLast = collateral - 1n;
|
|
38
41
|
if (debt === 0n) return allButLast;
|
|
39
|
-
const repayable = debt - debtLimits.minDebt;
|
|
42
|
+
const repayable = debt - debtLimits.minDebt - debt * WITHDRAW_DEBT_MARGIN / PERCENTAGE_FACTOR;
|
|
40
43
|
if (repayable < 0n) return 0n;
|
|
41
44
|
const bound = BigIntMath.ceilDiv(collateral * (repayable + 1n), debt) - 1n;
|
|
42
45
|
return bound < allButLast ? bound : allButLast;
|
|
@@ -154,7 +154,7 @@ var PoolService = class extends SDKConstruct {
|
|
|
154
154
|
tokenIn: toTokenAmount(tokenIn, pool.pool.underlyingToShares(amount * PERCENTAGE_FACTOR / (PERCENTAGE_FACTOR - pool.pool.withdrawFee), true)),
|
|
155
155
|
tokenOut: toTokenAmount(tokenOut, amount),
|
|
156
156
|
zapper: zapper?.baseParams.addr,
|
|
157
|
-
availableLiquidity: this
|
|
157
|
+
availableLiquidity: this.withdrawableLiquidity(poolAddr)
|
|
158
158
|
};
|
|
159
159
|
}
|
|
160
160
|
/**
|
|
@@ -176,7 +176,7 @@ var PoolService = class extends SDKConstruct {
|
|
|
176
176
|
tokenIn: toTokenAmount(tokenIn, amount),
|
|
177
177
|
tokenOut: toTokenAmount(tokenOut, pool.pool.sharesToUnderlying(amount) * (PERCENTAGE_FACTOR - pool.pool.withdrawFee) / PERCENTAGE_FACTOR),
|
|
178
178
|
zapper: zapper?.baseParams.addr,
|
|
179
|
-
availableLiquidity: this
|
|
179
|
+
availableLiquidity: this.withdrawableLiquidity(poolAddr)
|
|
180
180
|
};
|
|
181
181
|
}
|
|
182
182
|
/**
|
|
@@ -405,12 +405,11 @@ var PoolService = class extends SDKConstruct {
|
|
|
405
405
|
};
|
|
406
406
|
}
|
|
407
407
|
/**
|
|
408
|
-
*
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
return market.priceOracle.toAmount(pool.underlying, pool.pool.availableLiquidity * 99999n / 100000n);
|
|
408
|
+
* {@inheritDoc IPoolsService.withdrawableLiquidity}
|
|
409
|
+
*/
|
|
410
|
+
withdrawableLiquidity(pool) {
|
|
411
|
+
const market = this.sdk.marketRegister.findByPool(pool);
|
|
412
|
+
return market.priceOracle.toAmount(market.pool.underlying, market.pool.pool.availableLiquidity * 99999n / 100000n);
|
|
414
413
|
}
|
|
415
414
|
};
|
|
416
415
|
//#endregion
|
|
@@ -3,13 +3,7 @@ import { checkPoolPaused } from "../checks/checkPoolPaused.js";
|
|
|
3
3
|
import { checkPoolSunset } from "../checks/checkPoolSunset.js";
|
|
4
4
|
import "../checks/index.js";
|
|
5
5
|
//#region src/onchain/validation/bundles/checkPoolOperation.ts
|
|
6
|
-
/**
|
|
7
|
-
* What the pool's own state stops, whichever side of it the wallet is on.
|
|
8
|
-
*
|
|
9
|
-
* The liquidity read is the market's rather than the trimmed figure a
|
|
10
|
-
* simulation carries: a withdrawal sized against that figure has to pass the
|
|
11
|
-
* check that follows it.
|
|
12
|
-
*/
|
|
6
|
+
/** What the pool's own state stops, whichever side of it the wallet is on. */
|
|
13
7
|
function checkPoolOperation(args) {
|
|
14
8
|
const { sdk, pool, isDeposit, tokenOut } = args;
|
|
15
9
|
const market = sdk.marketRegister.findByPool(pool);
|
|
@@ -25,7 +19,7 @@ function checkPoolOperation(args) {
|
|
|
25
19
|
}),
|
|
26
20
|
...isDeposit ? [] : checkPoolLiquidity({
|
|
27
21
|
requested: tokenOut.value,
|
|
28
|
-
available:
|
|
22
|
+
available: sdk.pools.withdrawableLiquidity(pool).value,
|
|
29
23
|
underlying: tokenOut.token
|
|
30
24
|
})
|
|
31
25
|
];
|
|
@@ -3,17 +3,10 @@ import "../../../model/index.js";
|
|
|
3
3
|
import { amountOf } from "../helpers/amount.js";
|
|
4
4
|
import "../helpers/index.js";
|
|
5
5
|
//#region src/onchain/validation/checks/checkPoolLiquidity.ts
|
|
6
|
-
/**
|
|
7
|
-
* What the pool holds, against what is being taken out of it.
|
|
8
|
-
*
|
|
9
|
-
* The operator is not `checkBorrowLimit`'s: a pool holding exactly the amount
|
|
10
|
-
* requested still cannot serve it, so equality is already a refusal. That is
|
|
11
|
-
* the rule the legacy withdrawal validator enforced and it is preserved to the
|
|
12
|
-
* unit.
|
|
13
|
-
*/
|
|
6
|
+
/** What the pool can hand over, against what is being taken out of it. */
|
|
14
7
|
function checkPoolLiquidity(args) {
|
|
15
8
|
const { requested, available, underlying } = args;
|
|
16
|
-
if (requested
|
|
9
|
+
if (requested <= available) return [];
|
|
17
10
|
return [insufficientPoolLiquidity({
|
|
18
11
|
requested: amountOf(underlying, requested),
|
|
19
12
|
available: amountOf(underlying, available),
|
|
@@ -30,11 +30,12 @@ declare function debtForLeverage(collateral: bigint, leverage: bigint): bigint;
|
|
|
30
30
|
declare function proportionalDebt(position: Position, collateralDelta: bigint): bigint;
|
|
31
31
|
/**
|
|
32
32
|
* Largest withdrawal (in underlying) that {@link proportionalDebt} can still
|
|
33
|
-
* pay for: the repayment it implies leaves debt at or above `minDebt
|
|
33
|
+
* pay for: the repayment it implies leaves debt at or above `minDebt` plus
|
|
34
|
+
* {@link WITHDRAW_DEBT_MARGIN} of the debt, and
|
|
34
35
|
* strictly less than the collateral goes — the last unit closes the account
|
|
35
36
|
* rather than shrinks it. `0n` when the debt already sits below `minDebt`.
|
|
36
37
|
*
|
|
37
|
-
* Solves `floor(D0 · W / C0) ≤ D0 − minDebt` for `W`.
|
|
38
|
+
* Solves `floor(D0 · W / C0) ≤ D0 − minDebt − margin` for `W`.
|
|
38
39
|
*/
|
|
39
40
|
declare function maxProportionalWithdrawal(position: Position, debtLimits: DebtLimits): bigint;
|
|
40
41
|
/** Total leverage cannot drop below 1x — that would be negative debt. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Amount } from "../../model/primitives.js";
|
|
1
2
|
import { PoolPosition } from "../../model/positions.js";
|
|
2
3
|
import "../../model/index.js";
|
|
3
4
|
import { AddLiquidityProps, DepositMetadata, IPoolsService, ListPoolPositionsProps, PoolServiceCallResult, PoolSimulation, RemoveLiquidityProps, SimulatePoolOperationProps, WithdrawalMetadata } from "./types.js";
|
|
@@ -55,6 +56,10 @@ declare class PoolService extends SDKConstruct implements IPoolsService {
|
|
|
55
56
|
* {@inheritDoc IPoolsService.listPositions}
|
|
56
57
|
*/
|
|
57
58
|
listPositions(props: ListPoolPositionsProps): Promise<PoolPosition[]>;
|
|
59
|
+
/**
|
|
60
|
+
* {@inheritDoc IPoolsService.withdrawableLiquidity}
|
|
61
|
+
*/
|
|
62
|
+
withdrawableLiquidity(pool: Address): Amount;
|
|
58
63
|
}
|
|
59
64
|
//#endregion
|
|
60
65
|
export { PoolService };
|
|
@@ -147,8 +147,7 @@ interface PoolSimulation {
|
|
|
147
147
|
**/
|
|
148
148
|
zapper?: Address;
|
|
149
149
|
/**
|
|
150
|
-
* Withdrawals only:
|
|
151
|
-
* trimmed slightly so a withdrawal sized against it does not fail on rounding.
|
|
150
|
+
* Withdrawals only: {@link IPoolsService.withdrawableLiquidity}.
|
|
152
151
|
*
|
|
153
152
|
* The conversion is a rate, not a promise that the pool is liquid enough, so
|
|
154
153
|
* compare `tokenOut.value` against `availableLiquidity.value` to see if the
|
|
@@ -265,6 +264,14 @@ interface IPoolsService {
|
|
|
265
264
|
* several routes exist.
|
|
266
265
|
**/
|
|
267
266
|
simulateRedeem(props: SimulatePoolOperationProps): PoolSimulation;
|
|
267
|
+
/**
|
|
268
|
+
* The most the pool can hand over right now, trimmed so a share-sized
|
|
269
|
+
* withdrawal (redeem, zapper) survives the share price accruing before it is
|
|
270
|
+
* sent.
|
|
271
|
+
*
|
|
272
|
+
* @param pool - Pool address
|
|
273
|
+
**/
|
|
274
|
+
withdrawableLiquidity(pool: Address): Amount;
|
|
268
275
|
/**
|
|
269
276
|
* Returns contract call parameters for adding liquidity to a pool
|
|
270
277
|
* Or undefined if no deposit action is required (e.g. for RWA underlying on demand)
|
|
@@ -19,13 +19,7 @@ interface PoolOperationArgs {
|
|
|
19
19
|
*/
|
|
20
20
|
tokenOut: TokenAmount;
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
23
|
-
* What the pool's own state stops, whichever side of it the wallet is on.
|
|
24
|
-
*
|
|
25
|
-
* The liquidity read is the market's rather than the trimmed figure a
|
|
26
|
-
* simulation carries: a withdrawal sized against that figure has to pass the
|
|
27
|
-
* check that follows it.
|
|
28
|
-
*/
|
|
22
|
+
/** What the pool's own state stops, whichever side of it the wallet is on. */
|
|
29
23
|
declare function checkPoolOperation(args: PoolOperationArgs): PoolOperationError[];
|
|
30
24
|
//#endregion
|
|
31
25
|
export { PoolOperationArgs, PoolOperationError, checkPoolOperation };
|
|
@@ -7,14 +7,7 @@ interface PoolLiquidityArgs {
|
|
|
7
7
|
available: bigint;
|
|
8
8
|
underlying: Token;
|
|
9
9
|
}
|
|
10
|
-
/**
|
|
11
|
-
* What the pool holds, against what is being taken out of it.
|
|
12
|
-
*
|
|
13
|
-
* The operator is not `checkBorrowLimit`'s: a pool holding exactly the amount
|
|
14
|
-
* requested still cannot serve it, so equality is already a refusal. That is
|
|
15
|
-
* the rule the legacy withdrawal validator enforced and it is preserved to the
|
|
16
|
-
* unit.
|
|
17
|
-
*/
|
|
10
|
+
/** What the pool can hand over, against what is being taken out of it. */
|
|
18
11
|
declare function checkPoolLiquidity(args: PoolLiquidityArgs): InsufficientPoolLiquidityError[];
|
|
19
12
|
//#endregion
|
|
20
13
|
export { PoolLiquidityArgs, checkPoolLiquidity };
|