@gearbox-protocol/sdk 16.0.0-next.18 → 16.0.0-next.19
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/common-utils/index.js +3 -21
- package/dist/cjs/common-utils/test-utils/index.js +4 -3
- package/dist/cjs/common-utils/utils/index.js +3 -22
- package/dist/cjs/common-utils/utils/strategies/index.js +3 -0
- package/dist/cjs/common-utils/utils/strategies/strategy-info/cm-availability-condition.js +5 -5
- package/dist/cjs/common-utils/utils/strategies/strategy-info/credit-manager-issues.js +135 -0
- package/dist/cjs/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +12 -23
- package/dist/cjs/common-utils/utils/strategies/strategy-info/index.js +3 -0
- package/dist/cjs/onchain/accounts/index.js +2 -3
- package/dist/cjs/onchain/accounts/intents/guards.js +55 -50
- package/dist/cjs/onchain/accounts/intents/index.js +7 -8
- package/dist/cjs/onchain/accounts/intents/math.js +15 -22
- package/dist/cjs/onchain/accounts/intents/open-strategy.js +5 -5
- package/dist/cjs/onchain/accounts/intents/plan.js +27 -41
- package/dist/cjs/onchain/accounts/intents/realize.js +14 -21
- package/dist/cjs/onchain/accounts/intents/tail.js +2 -2
- package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +1 -0
- package/dist/cjs/onchain/accounts/intents/view.js +1 -0
- package/dist/cjs/onchain/constants/index.js +1 -0
- package/dist/cjs/onchain/constants/math.js +11 -0
- package/dist/cjs/onchain/index.js +32 -3
- package/dist/cjs/onchain/validation/checks.js +250 -0
- package/dist/cjs/onchain/validation/index.js +29 -0
- package/dist/cjs/onchain/{accounts/intents → validation}/refusal.js +12 -1
- package/dist/cjs/onchain/validation/token.js +29 -0
- package/dist/cjs/preview/index.js +10 -0
- package/dist/cjs/preview/preview/buildDelayedPreview.js +1 -0
- package/dist/cjs/preview/preview/previewAdjustCreditAccount.js +1 -0
- package/dist/cjs/preview/preview/previewOpenCreditAccount.js +1 -0
- package/dist/cjs/preview/validate/checkOperation.js +173 -0
- package/dist/cjs/preview/validate/checkSimulation.js +52 -0
- package/dist/cjs/preview/validate/index.js +6 -0
- package/dist/cjs/sdk/index.js +4 -0
- package/dist/cjs/sdk/prepare/PrepareApi.js +17 -13
- package/dist/cjs/sdk/prepare/index.js +4 -0
- package/dist/cjs/sdk/prepare/types.js +4 -0
- package/dist/esm/common-utils/index.js +2 -11
- package/dist/esm/common-utils/test-utils/index.js +4 -3
- package/dist/esm/common-utils/utils/index.js +2 -12
- package/dist/esm/common-utils/utils/strategies/index.js +2 -1
- package/dist/esm/common-utils/utils/strategies/strategy-info/cm-availability-condition.js +5 -5
- package/dist/esm/common-utils/utils/strategies/strategy-info/credit-manager-issues.js +133 -0
- package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +12 -23
- package/dist/esm/common-utils/utils/strategies/strategy-info/index.js +2 -1
- package/dist/esm/dev/AccountOpener.js +1 -1
- package/dist/esm/dev/withdrawalUtils.js +1 -1
- package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +2 -2
- package/dist/esm/onchain/accounts/index.js +2 -2
- package/dist/esm/onchain/accounts/intents/guards.js +55 -50
- package/dist/esm/onchain/accounts/intents/index.js +5 -5
- package/dist/esm/onchain/accounts/intents/math.js +14 -21
- package/dist/esm/onchain/accounts/intents/open-strategy.js +4 -4
- package/dist/esm/onchain/accounts/intents/plan.js +15 -29
- package/dist/esm/onchain/accounts/intents/realize.js +12 -19
- package/dist/esm/onchain/accounts/intents/tail.js +1 -1
- package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +1 -0
- package/dist/esm/onchain/accounts/intents/view.js +1 -0
- package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +1 -1
- package/dist/esm/onchain/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
- package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
- package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
- package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
- package/dist/esm/onchain/base/TokensMeta.js +3 -3
- package/dist/esm/onchain/chain/detectNetwork.js +1 -1
- package/dist/esm/onchain/constants/index.js +2 -2
- package/dist/esm/onchain/constants/math.js +11 -1
- package/dist/esm/onchain/core/createAddressProvider.js +1 -1
- package/dist/esm/onchain/index.js +7 -3
- package/dist/esm/onchain/market/adapters/contracts/AccountMigratorAdapterContract.js +1 -1
- package/dist/esm/onchain/market/adapters/contracts/ERC4626AdapterContract.js +1 -1
- package/dist/esm/onchain/market/credit/CreditFacadeV310BaseContract.js +1 -1
- package/dist/esm/onchain/market/pool/PoolV310Contract.js +1 -1
- package/dist/esm/onchain/market/zapper/IETHZapperContract.js +1 -1
- package/dist/esm/onchain/market/zapper/ZapperContract.js +1 -1
- package/dist/esm/onchain/pools/PoolService.js +1 -1
- package/dist/esm/onchain/utils/viem/simulateWithPriceUpdates.js +1 -1
- package/dist/esm/onchain/validation/checks.js +230 -0
- package/dist/esm/onchain/validation/index.js +4 -0
- package/dist/esm/onchain/{accounts/intents → validation}/refusal.js +12 -2
- package/dist/esm/onchain/validation/token.js +27 -0
- package/dist/esm/preview/index.js +5 -1
- package/dist/esm/preview/preview/buildDelayedPreview.js +1 -0
- package/dist/esm/preview/preview/previewAdjustCreditAccount.js +1 -0
- package/dist/esm/preview/preview/previewOpenCreditAccount.js +1 -0
- package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
- package/dist/esm/preview/trace/extractTransfers.js +1 -1
- package/dist/esm/preview/validate/checkOperation.js +171 -0
- package/dist/esm/preview/validate/checkSimulation.js +51 -0
- package/dist/esm/preview/validate/index.js +3 -0
- package/dist/esm/sdk/index.js +2 -1
- package/dist/esm/sdk/prepare/PrepareApi.js +15 -11
- package/dist/esm/sdk/prepare/index.js +2 -1
- package/dist/esm/sdk/prepare/types.js +2 -1
- package/dist/types/common-utils/index.d.ts +2 -12
- package/dist/types/common-utils/utils/index.d.ts +2 -13
- package/dist/types/common-utils/utils/strategies/index.d.ts +2 -1
- package/dist/types/common-utils/utils/strategies/strategy-info/credit-manager-issues.d.ts +34 -0
- package/dist/types/common-utils/utils/strategies/strategy-info/index.d.ts +2 -1
- package/dist/types/model/previews.d.ts +22 -0
- package/dist/types/onchain/accounts/index.d.ts +2 -2
- package/dist/types/onchain/accounts/intents/guards.d.ts +8 -4
- package/dist/types/onchain/accounts/intents/index.d.ts +4 -3
- package/dist/types/onchain/accounts/intents/math.d.ts +2 -1
- package/dist/types/onchain/accounts/intents/plan.d.ts +3 -0
- package/dist/types/onchain/accounts/intents/types.d.ts +7 -1
- package/dist/types/onchain/constants/index.d.ts +2 -2
- package/dist/types/onchain/constants/math.d.ts +9 -1
- package/dist/types/onchain/index.d.ts +7 -3
- package/dist/types/onchain/validation/checks.d.ts +167 -0
- package/dist/types/onchain/validation/index.d.ts +4 -0
- package/dist/types/onchain/{accounts/intents → validation}/refusal.d.ts +100 -31
- package/dist/types/onchain/validation/token.d.ts +17 -0
- package/dist/types/preview/index.d.ts +5 -1
- package/dist/types/preview/validate/checkOperation.d.ts +46 -0
- package/dist/types/preview/validate/checkSimulation.d.ts +34 -0
- package/dist/types/preview/validate/index.d.ts +3 -0
- package/dist/types/sdk/index.d.ts +2 -2
- package/dist/types/sdk/prepare/index.d.ts +2 -2
- package/dist/types/sdk/prepare/types.d.ts +2 -2
- package/package.json +1 -1
- package/dist/cjs/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.js +0 -267
- package/dist/cjs/common-utils/utils/validation/index.js +0 -23
- package/dist/cjs/common-utils/utils/validation/is-zero-balance.js +0 -7
- package/dist/cjs/common-utils/utils/validation/validate-balance.js +0 -22
- package/dist/cjs/common-utils/utils/validation/validate-balance.spec.js +0 -54
- package/dist/cjs/common-utils/utils/validation/validate-balances.js +0 -17
- package/dist/cjs/common-utils/utils/validation/validate-balances.spec.js +0 -45
- package/dist/cjs/common-utils/utils/validation/validate-credit-manager.js +0 -8
- package/dist/cjs/common-utils/utils/validation/validate-credit-manager.spec.js +0 -36
- package/dist/cjs/common-utils/utils/validation/validate-hf.js +0 -10
- package/dist/cjs/common-utils/utils/validation/validate-hf.spec.js +0 -26
- package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-quota-status.js +0 -14
- package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.js +0 -29
- package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.js +0 -37
- package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.spec.js +0 -98
- package/dist/cjs/common-utils/utils/validation/validate-open-account.js +0 -18
- package/dist/cjs/common-utils/utils/validation/validate-open-account.spec.js +0 -56
- package/dist/cjs/common-utils/utils/validation/validate-quota.js +0 -23
- package/dist/cjs/common-utils/utils/validation/validate-quota.spec.js +0 -88
- package/dist/cjs/common-utils/utils/validation/validate-token-to-obtain.js +0 -18
- package/dist/cjs/common-utils/utils/validation/validate-token-to-obtain.spec.js +0 -36
- package/dist/cjs/common-utils/utils/validation/validation-types.js +0 -1
- package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.js +0 -264
- package/dist/esm/common-utils/utils/validation/index.js +0 -12
- package/dist/esm/common-utils/utils/validation/is-zero-balance.js +0 -6
- package/dist/esm/common-utils/utils/validation/validate-balance.js +0 -21
- package/dist/esm/common-utils/utils/validation/validate-balance.spec.js +0 -54
- package/dist/esm/common-utils/utils/validation/validate-balances.js +0 -16
- package/dist/esm/common-utils/utils/validation/validate-balances.spec.js +0 -45
- package/dist/esm/common-utils/utils/validation/validate-credit-manager.js +0 -7
- package/dist/esm/common-utils/utils/validation/validate-credit-manager.spec.js +0 -36
- package/dist/esm/common-utils/utils/validation/validate-hf.js +0 -8
- package/dist/esm/common-utils/utils/validation/validate-hf.spec.js +0 -26
- package/dist/esm/common-utils/utils/validation/validate-open-account-pool-quota-status.js +0 -13
- package/dist/esm/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.js +0 -29
- package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.js +0 -36
- package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.spec.js +0 -98
- package/dist/esm/common-utils/utils/validation/validate-open-account.js +0 -17
- package/dist/esm/common-utils/utils/validation/validate-open-account.spec.js +0 -56
- package/dist/esm/common-utils/utils/validation/validate-quota.js +0 -22
- package/dist/esm/common-utils/utils/validation/validate-quota.spec.js +0 -88
- package/dist/esm/common-utils/utils/validation/validate-token-to-obtain.js +0 -17
- package/dist/esm/common-utils/utils/validation/validate-token-to-obtain.spec.js +0 -36
- package/dist/esm/common-utils/utils/validation/validation-types.js +0 -1
- package/dist/types/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/index.d.ts +0 -12
- package/dist/types/common-utils/utils/validation/is-zero-balance.d.ts +0 -4
- package/dist/types/common-utils/utils/validation/validate-balance.d.ts +0 -25
- package/dist/types/common-utils/utils/validation/validate-balance.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/validate-balances.d.ts +0 -13
- package/dist/types/common-utils/utils/validation/validate-balances.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/validate-credit-manager.d.ts +0 -13
- package/dist/types/common-utils/utils/validation/validate-credit-manager.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/validate-hf.d.ts +0 -12
- package/dist/types/common-utils/utils/validation/validate-hf.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/validate-open-account-pool-quota-status.d.ts +0 -10
- package/dist/types/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/validate-open-account-pool-status.d.ts +0 -26
- package/dist/types/common-utils/utils/validation/validate-open-account-pool-status.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/validate-open-account.d.ts +0 -25
- package/dist/types/common-utils/utils/validation/validate-open-account.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/validate-quota.d.ts +0 -24
- package/dist/types/common-utils/utils/validation/validate-quota.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/validate-token-to-obtain.d.ts +0 -17
- package/dist/types/common-utils/utils/validation/validate-token-to-obtain.spec.d.ts +0 -1
- package/dist/types/common-utils/utils/validation/validation-types.d.ts +0 -10
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { BigIntMath } from "../../../../onchain/utils/bigint-math.js";
|
|
2
|
+
import { checkBorrowLimit, checkCollateralised, checkCreditManagerPaused, checkDebtInBand, checkForbiddenToken, checkFunding, checkQuotaCount, checkQuotaLimit } from "../../../../onchain/validation/checks.js";
|
|
3
|
+
import "../../../../onchain/index.js";
|
|
4
|
+
//#region src/common-utils/utils/strategies/strategy-info/credit-manager-issues.ts
|
|
5
|
+
/**
|
|
6
|
+
* The ladders below are the order the strategy lists report in, which is theirs
|
|
7
|
+
* to decide — the engine weighs the same ceilings differently and says so.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The lists hold no token registry, so only the address is real here — these
|
|
11
|
+
* issues are read as a reason, not rendered as an amount.
|
|
12
|
+
*/
|
|
13
|
+
function tokenOf(chainId, address) {
|
|
14
|
+
return {
|
|
15
|
+
chainId,
|
|
16
|
+
address,
|
|
17
|
+
symbol: address,
|
|
18
|
+
name: "",
|
|
19
|
+
decimals: 0
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The debt ceilings an account opening runs into, in the order a form reports
|
|
24
|
+
* them. The minimum debt is what is weighed — asking for less does not make it
|
|
25
|
+
* fit.
|
|
26
|
+
*/
|
|
27
|
+
function checkOpenAccountCeilings(args) {
|
|
28
|
+
const { creditManager, pool, debt, targetToken } = args;
|
|
29
|
+
const underlying = tokenOf(creditManager.chainId, creditManager.underlyingToken);
|
|
30
|
+
const effectiveDebt = BigIntMath.max(creditManager.minDebt, debt);
|
|
31
|
+
const debtLimitLeft = BigIntMath.max(creditManager.totalDebtLimit - creditManager.totalDebt, 0n);
|
|
32
|
+
const { totalDebtLimit = 0n, totalBorrowed = 0n } = pool || {};
|
|
33
|
+
const poolDebtLimitLeft = totalDebtLimit - totalBorrowed;
|
|
34
|
+
const canOpenMinDebt = creditManager.minDebt <= debtLimitLeft && creditManager.minDebt <= poolDebtLimitLeft && creditManager.minDebt <= creditManager.availableToBorrow;
|
|
35
|
+
const minPositionSize = BigIntMath.min(BigIntMath.min(debtLimitLeft, poolDebtLimitLeft), creditManager.availableToBorrow);
|
|
36
|
+
const ceilings = [
|
|
37
|
+
...creditManager.totalDebtLimit >= 0n ? [{
|
|
38
|
+
available: debtLimitLeft,
|
|
39
|
+
binding: "managerDebtAvailable"
|
|
40
|
+
}] : [],
|
|
41
|
+
...totalDebtLimit > 0n ? [{
|
|
42
|
+
available: poolDebtLimitLeft,
|
|
43
|
+
binding: "poolDebtLimit"
|
|
44
|
+
}] : [],
|
|
45
|
+
{
|
|
46
|
+
available: creditManager.availableToBorrow,
|
|
47
|
+
binding: "poolAvailableLiquidity"
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
for (const { available, binding } of ceilings) {
|
|
51
|
+
const issue = checkBorrowLimit({
|
|
52
|
+
requested: effectiveDebt,
|
|
53
|
+
available,
|
|
54
|
+
binding,
|
|
55
|
+
underlying,
|
|
56
|
+
solutionAmount: canOpenMinDebt ? minPositionSize : void 0
|
|
57
|
+
});
|
|
58
|
+
if (issue) return issue;
|
|
59
|
+
}
|
|
60
|
+
if (targetToken !== null) return quotaIssue(creditManager, targetToken, effectiveDebt, underlying);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
/** The room the keeper has left for a token, read off a slice. */
|
|
64
|
+
function quotaIssue(creditManager, token, requested, underlying) {
|
|
65
|
+
const quota = creditManager.quotas[token];
|
|
66
|
+
if (!quota) return null;
|
|
67
|
+
const realLimit = quota.isActive ? quota.limit : 0n;
|
|
68
|
+
return checkQuotaLimit({
|
|
69
|
+
token: tokenOf(creditManager.chainId, token),
|
|
70
|
+
requested,
|
|
71
|
+
available: realLimit - quota.totalQuoted,
|
|
72
|
+
underlying
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/** Everything the lists weigh before calling a manager usable, in their order. */
|
|
76
|
+
function checkCreditManagerUsable(args) {
|
|
77
|
+
const { creditManager, pool, debt, targetToken } = args;
|
|
78
|
+
const { chainId } = creditManager;
|
|
79
|
+
const underlying = tokenOf(chainId, creditManager.underlyingToken);
|
|
80
|
+
return checkCreditManagerPaused({
|
|
81
|
+
isPaused: creditManager.isPaused,
|
|
82
|
+
creditManager: creditManager.address
|
|
83
|
+
}) || checkOpenAccountCeilings({
|
|
84
|
+
creditManager,
|
|
85
|
+
pool,
|
|
86
|
+
debt,
|
|
87
|
+
targetToken
|
|
88
|
+
}) || (args.tokenToObtain === null ? null : checkForbiddenToken({
|
|
89
|
+
token: tokenOf(chainId, args.tokenToObtain),
|
|
90
|
+
isForbidden: creditManager.isForbidden(args.tokenToObtain)
|
|
91
|
+
})) || fundingIssue(chainId, args.collateral, args.balances) || checkDebtInBand({
|
|
92
|
+
debt,
|
|
93
|
+
minDebt: creditManager.minDebt,
|
|
94
|
+
maxDebt: creditManager.maxDebt,
|
|
95
|
+
underlying,
|
|
96
|
+
allowZero: false
|
|
97
|
+
}) || checkQuotaCount({
|
|
98
|
+
count: Object.values(args.desiredQuota).filter((a) => a.balance > 0n).length,
|
|
99
|
+
max: creditManager.maxEnabledTokensLength
|
|
100
|
+
}) || quotaUpdateIssue(creditManager, args.quotaUpdate, underlying) || checkCollateralised({
|
|
101
|
+
healthFactor: args.healthFactor,
|
|
102
|
+
required: 10101,
|
|
103
|
+
safePrices: false
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The first asset the wallet cannot fund.
|
|
108
|
+
*
|
|
109
|
+
* The lookup lowercases because the balance map is keyed that way while a
|
|
110
|
+
* market names its tokens as it spells them.
|
|
111
|
+
*/
|
|
112
|
+
function fundingIssue(chainId, collateral, balances) {
|
|
113
|
+
for (const { token, balance } of collateral) {
|
|
114
|
+
const held = balances[token.toLowerCase()] || 0n;
|
|
115
|
+
const issue = checkFunding({
|
|
116
|
+
token: tokenOf(chainId, token),
|
|
117
|
+
required: balance,
|
|
118
|
+
held
|
|
119
|
+
});
|
|
120
|
+
if (issue) return issue;
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
function quotaUpdateIssue(creditManager, quotaUpdate, underlying) {
|
|
125
|
+
for (const { token, balance: updateBy } of quotaUpdate) {
|
|
126
|
+
if (updateBy <= 0n) continue;
|
|
127
|
+
const issue = quotaIssue(creditManager, token, updateBy, underlying);
|
|
128
|
+
if (issue) return issue;
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
export { checkCreditManagerUsable, checkOpenAccountCeilings };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BigIntMath } from "../../../../onchain/utils/bigint-math.js";
|
|
2
|
-
import { LEVERAGE_DECIMALS } from "../../../../onchain/constants/math.js";
|
|
2
|
+
import { LEVERAGE_DECIMALS, isZeroBalance } from "../../../../onchain/constants/math.js";
|
|
3
3
|
import { formatBN, toBN, toBigInt } from "../../../../onchain/utils/formatter.js";
|
|
4
|
-
import { validateHF } from "../../validation/validate-hf.js";
|
|
5
4
|
import { calcQuotaUpdate } from "../../creditAccount/quota-utils.js";
|
|
5
|
+
import "../../../../onchain/index.js";
|
|
6
6
|
import { PriceUtils } from "../../price-math.js";
|
|
7
7
|
import { calculateEarnings } from "../../apy/calculate-earnings.js";
|
|
8
8
|
import { calculateEffectiveBorrowRate } from "../../apy/calculate-effective-borrow-rate.js";
|
|
@@ -19,14 +19,9 @@ import { getListWithAmountInTarget } from "../tokens/get-list-with-amount-in-tar
|
|
|
19
19
|
import { getWalletBalancesAllowedOnCM } from "../credit-managers/get-wallet-balances-allowed-on-cm.js";
|
|
20
20
|
import { getComplexPointsList } from "../points/get-complex-points-list.js";
|
|
21
21
|
import { getPointsInfo } from "../points/get-points-info.js";
|
|
22
|
-
import {
|
|
22
|
+
import { checkCreditManagerUsable } from "./credit-manager-issues.js";
|
|
23
23
|
import { calculateTotalAPY } from "./calculate-total-apy.js";
|
|
24
24
|
import { calculateTotalPoints } from "./calculate-total-points.js";
|
|
25
|
-
import { isZeroBalance } from "../../validation/is-zero-balance.js";
|
|
26
|
-
import { validateBalances } from "../../validation/validate-balances.js";
|
|
27
|
-
import { validateCreditManager } from "../../validation/validate-credit-manager.js";
|
|
28
|
-
import { validateOpenAccount } from "../../validation/validate-open-account.js";
|
|
29
|
-
import { validateTokenToObtain } from "../../validation/validate-token-to-obtain.js";
|
|
30
25
|
//#region src/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.ts
|
|
31
26
|
function getCMYouCanEarn({ allPrices, creditManager, tokensList, delayedPhantoms, nativeTokenAddress, wrappedNativeTokenAddress, walletBalances, strategy, slippage, quotaReserve, apyList, pools }) {
|
|
32
27
|
const baseInfo = {
|
|
@@ -176,27 +171,21 @@ function getCMYouCanEarn({ allPrices, creditManager, tokensList, delayedPhantoms
|
|
|
176
171
|
tokensList
|
|
177
172
|
});
|
|
178
173
|
const pool = pools?.[creditManager.pool];
|
|
179
|
-
const error =
|
|
180
|
-
pool,
|
|
174
|
+
const error = collateral.some((a) => isZeroBalance(a.balance)) ? { reason: "insufficientSourceBalance" } : checkCreditManagerUsable({
|
|
181
175
|
creditManager,
|
|
176
|
+
pool,
|
|
182
177
|
debt,
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}) || validateBalances({
|
|
178
|
+
healthFactor: hf,
|
|
179
|
+
targetToken: targetTokenAddress,
|
|
180
|
+
tokenToObtain: strategy.tokenOutAddress,
|
|
181
|
+
collateral,
|
|
188
182
|
balances: walletBalances,
|
|
189
|
-
assets: collateral
|
|
190
|
-
}) || validateOpenAccount({
|
|
191
183
|
desiredQuota,
|
|
192
|
-
quotaUpdate
|
|
193
|
-
|
|
194
|
-
creditManager,
|
|
195
|
-
loading: false
|
|
196
|
-
}) || validateHF({ hf });
|
|
184
|
+
quotaUpdate
|
|
185
|
+
});
|
|
197
186
|
if (error) return {
|
|
198
187
|
status: "error",
|
|
199
|
-
description: `Resulting CA did not pass validation: ${error.
|
|
188
|
+
description: `Resulting CA did not pass validation: ${error.reason}`,
|
|
200
189
|
otherInfo: {
|
|
201
190
|
...baseInfo,
|
|
202
191
|
hf
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isStrategyCMDisabled } from "./is-strategy-cm-disabled.js";
|
|
2
|
+
import { checkCreditManagerUsable, checkOpenAccountCeilings } from "./credit-manager-issues.js";
|
|
2
3
|
import { cmAvailabilityCondition } from "./cm-availability-condition.js";
|
|
3
4
|
import { getStrategyMaxAPY } from "./get-strategy-max-apy.js";
|
|
4
5
|
import { calculateTotalAPY } from "./calculate-total-apy.js";
|
|
@@ -8,4 +9,4 @@ import { getStrategyInfoCore } from "./get-strategy-info-core.js";
|
|
|
8
9
|
import { getStrategyInfo } from "./get-strategy-info.js";
|
|
9
10
|
import { getStrategyYouCanEarn } from "./get-strategy-you-can-earn.js";
|
|
10
11
|
import "./types.js";
|
|
11
|
-
export { calculateTotalAPY, calculateTotalPoints, cmAvailabilityCondition, getCMYouCanEarn, getStrategyInfo, getStrategyInfoCore, getStrategyMaxAPY, getStrategyYouCanEarn, isStrategyCMDisabled };
|
|
12
|
+
export { calculateTotalAPY, calculateTotalPoints, checkCreditManagerUsable, checkOpenAccountCeilings, cmAvailabilityCondition, getCMYouCanEarn, getStrategyInfo, getStrategyInfoCore, getStrategyMaxAPY, getStrategyYouCanEarn, isStrategyCMDisabled };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { ierc20Abi } from "../abi/iERC20.js";
|
|
1
2
|
import { iCreditFacadeV310Abi } from "../abi/310/generated.js";
|
|
2
3
|
import { AddressMap } from "../onchain/utils/AddressMap.js";
|
|
3
4
|
import { AddressSet } from "../onchain/utils/AddressSet.js";
|
|
4
5
|
import { AssetsMap } from "../onchain/utils/AssetsMap.js";
|
|
5
6
|
import { childLogger } from "../onchain/utils/childLogger.js";
|
|
6
|
-
import { ierc20Abi } from "../abi/iERC20.js";
|
|
7
7
|
import "../onchain/constants/addresses.js";
|
|
8
8
|
import { MAX_UINT256, PERCENTAGE_FACTOR } from "../onchain/constants/math.js";
|
|
9
9
|
import { SDKConstruct } from "../onchain/base/SDKConstruct.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { iWithdrawalCompressorV313Abi } from "../abi/IWithdrawalCompressorV313.js";
|
|
1
2
|
import { getNetworkType } from "../onchain/chain/chains.js";
|
|
2
3
|
import { getWithdrawalCompressorAddress } from "../onchain/accounts/withdrawal-compressor/addresses.js";
|
|
3
|
-
import { iWithdrawalCompressorV313Abi } from "../abi/IWithdrawalCompressorV313.js";
|
|
4
4
|
import "../onchain/index.js";
|
|
5
5
|
import { iMidasDataFeedAbi, iMidasRedemptionVaultAbi, midasGatewayAbi, midasRedeemerAbi, midasRedemptionVaultPhantomTokenAbi, securitizeRedeemerAbi, securitizeRedemptionGatewayAbi, securitizeRedemptionPhantomTokenAbi } from "./withdrawalAbi.js";
|
|
6
6
|
import { erc20Abi, hexToString, parseAbi, parseEther } from "viem";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { iBaseRewardPoolAbi } from "../../abi/iBaseRewardPool.js";
|
|
2
|
+
import { ierc4626AdapterAbi } from "../../abi/ierc4626Adapter.js";
|
|
1
3
|
import { AP_REWARDS_COMPRESSOR } from "../constants/address-provider.js";
|
|
2
4
|
import { ADDRESS_0X0 } from "../constants/addresses.js";
|
|
3
5
|
import { MAX_UINT256 } from "../constants/math.js";
|
|
@@ -8,8 +10,6 @@ import "../base/index.js";
|
|
|
8
10
|
import { AccountBotsService } from "./bots/AccountBotsService.js";
|
|
9
11
|
import "./bots/index.js";
|
|
10
12
|
import { rewardsCompressorAbi } from "../../abi/compressors/rewardsCompressor.js";
|
|
11
|
-
import { iBaseRewardPoolAbi } from "../../abi/iBaseRewardPool.js";
|
|
12
|
-
import { ierc4626AdapterAbi } from "../../abi/ierc4626Adapter.js";
|
|
13
13
|
import { expectedBalanceDeltas } from "../market/credit/expectedBalanceDeltas.js";
|
|
14
14
|
import "../market/index.js";
|
|
15
15
|
import { CreditAccountCompressor } from "./credit-account-compressor/CreditAccountCompressor.js";
|
|
@@ -5,7 +5,7 @@ import { CreditAccountCompressorV310Contract } from "./credit-account-compressor
|
|
|
5
5
|
import { CreditAccountCompressor } from "./credit-account-compressor/CreditAccountCompressor.js";
|
|
6
6
|
import "./credit-account-compressor/index.js";
|
|
7
7
|
import { CreditAccountsServiceV310 } from "./CreditAccountsServiceV310.js";
|
|
8
|
-
import {
|
|
8
|
+
import { borrowable } from "./intents/guards.js";
|
|
9
9
|
import { fetchCreditAccountSlice, toCreditAccountSlice } from "./intents/utils/credit-account-slice.js";
|
|
10
10
|
import { CreditAccountOperationsService } from "./intents/index.js";
|
|
11
11
|
import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./liquidations/constants.js";
|
|
@@ -25,4 +25,4 @@ import { toWithdrawalStatus } from "./withdrawal-compressor/types.js";
|
|
|
25
25
|
import { WithdrawalCompressorV313Contract } from "./withdrawal-compressor/WithdrawalCompressorV313Contract.js";
|
|
26
26
|
import { createWithdrawalCompressor } from "./withdrawal-compressor/createWithdrawalCompressor.js";
|
|
27
27
|
import "./withdrawal-compressor/index.js";
|
|
28
|
-
export { AbstractWithdrawalCompressorContract, AccountBotsService, CreditAccountCompressor, CreditAccountCompressorV310Contract, CreditAccountOperationsService, CreditAccountsServiceV310, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION,
|
|
28
|
+
export { AbstractWithdrawalCompressorContract, AccountBotsService, CreditAccountCompressor, CreditAccountCompressorV310Contract, CreditAccountOperationsService, CreditAccountsServiceV310, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, InvalidDelayedIntentError, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService, PeripheryCompressorV310Contract, RedemptionLoggerV310Contract, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, borrowable, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, encodeDelayedIntent, fetchCreditAccountSlice, getWithdrawalCompressorAddress, iCreditAccountAbi, toClaimableWithdrawal, toCreditAccountSlice, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "../../
|
|
3
|
-
import {
|
|
1
|
+
import { MIN_HEALTH_FACTOR_FACADE, checkBorrowLimit, checkCollateralised, checkCreditManagerPaused, checkForbiddenToken, checkMarketExpired, checkQuotaLimit } from "../../validation/checks.js";
|
|
2
|
+
import { raise } from "../../validation/refusal.js";
|
|
3
|
+
import { toToken } from "../../validation/token.js";
|
|
4
4
|
import { eq } from "./utils/common.js";
|
|
5
5
|
import { isPhantomToken } from "./utils/pick-token.js";
|
|
6
6
|
//#region src/onchain/accounts/intents/guards.ts
|
|
@@ -24,11 +24,15 @@ import { isPhantomToken } from "./utils/pick-token.js";
|
|
|
24
24
|
*/
|
|
25
25
|
function assertMarketOperable(suite) {
|
|
26
26
|
const creditManager = suite.creditManager.address;
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
raise(checkCreditManagerPaused({
|
|
28
|
+
isPaused: suite.isPaused,
|
|
29
|
+
creditManager
|
|
30
|
+
}), `${creditManager} is paused`);
|
|
31
|
+
raise(checkMarketExpired({
|
|
32
|
+
isExpired: suite.isExpired,
|
|
29
33
|
creditManager,
|
|
30
34
|
expirationDate: suite.creditFacade.expirationDate
|
|
31
|
-
}, `${creditManager} expired at ${suite.creditFacade.expirationDate}`);
|
|
35
|
+
}), `${creditManager} expired at ${suite.creditFacade.expirationDate}`);
|
|
32
36
|
}
|
|
33
37
|
/**
|
|
34
38
|
* What the pool will hand this manager in one transaction: the tightest of its
|
|
@@ -39,30 +43,35 @@ function assertMarketOperable(suite) {
|
|
|
39
43
|
function borrowable(suite) {
|
|
40
44
|
const { pool } = suite.market.pool;
|
|
41
45
|
const { maxDebtPerBlockMultiplier, maxDebt } = suite.creditFacade;
|
|
42
|
-
if (maxDebtPerBlockMultiplier === 0) return
|
|
46
|
+
if (maxDebtPerBlockMultiplier === 0) return {
|
|
47
|
+
limit: 0n,
|
|
48
|
+
binding: "facadePerBlockCap"
|
|
49
|
+
};
|
|
43
50
|
const available = pool.creditManagerDebtParams.get(suite.creditManager.address)?.available;
|
|
44
51
|
return [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
{
|
|
53
|
+
limit: pool.availableLiquidity,
|
|
54
|
+
binding: "poolAvailableLiquidity"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
limit: maxDebt * BigInt(maxDebtPerBlockMultiplier),
|
|
58
|
+
binding: "facadePerBlockCap"
|
|
59
|
+
},
|
|
60
|
+
...available === void 0 ? [] : [{
|
|
61
|
+
limit: available,
|
|
62
|
+
binding: "managerDebtAvailable"
|
|
63
|
+
}]
|
|
64
|
+
].reduce((a, b) => b.limit < a.limit ? b : a);
|
|
49
65
|
}
|
|
50
66
|
/** The pool has to be able to lend what the plan means to draw. */
|
|
51
|
-
function assertCanBorrow(suite, amount) {
|
|
52
|
-
const limit = borrowable(suite);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
},
|
|
60
|
-
available: {
|
|
61
|
-
token,
|
|
62
|
-
balance: limit
|
|
63
|
-
}
|
|
64
|
-
}, `borrow: ${amount} exceeds what the pool can lend now (${limit})`);
|
|
65
|
-
}
|
|
67
|
+
function assertCanBorrow(sdk, suite, amount) {
|
|
68
|
+
const { limit, binding } = borrowable(suite);
|
|
69
|
+
raise(checkBorrowLimit({
|
|
70
|
+
requested: amount,
|
|
71
|
+
available: limit,
|
|
72
|
+
binding,
|
|
73
|
+
underlying: toToken(sdk, suite.market.pool.underlying)
|
|
74
|
+
}), `borrow: ${amount} exceeds what the pool can lend now (${limit})`);
|
|
66
75
|
}
|
|
67
76
|
/**
|
|
68
77
|
* What the account is allowed to end up holding more of than it started with.
|
|
@@ -82,16 +91,17 @@ function assertGrowthAllowed(args) {
|
|
|
82
91
|
const underlying = market.pool.underlying;
|
|
83
92
|
for (const { token, balance } of after) {
|
|
84
93
|
if (balance <= (before.find((a) => eq(a.token, token))?.balance ?? 0n)) continue;
|
|
85
|
-
|
|
94
|
+
raise(checkForbiddenToken({
|
|
95
|
+
token: toToken(sdk, token),
|
|
96
|
+
isForbidden: forbidden.some((f) => eq(f, token))
|
|
97
|
+
}), `${token} is forbidden in this market and the plan buys more of it`);
|
|
86
98
|
if (eq(token, underlying) || isPhantomToken(sdk, token)) continue;
|
|
87
|
-
if (!market.pool.pqk.hasActiveQuota(token))
|
|
88
|
-
token,
|
|
99
|
+
if (!market.pool.pqk.hasActiveQuota(token)) raise(checkQuotaLimit({
|
|
100
|
+
token: toToken(sdk, token),
|
|
89
101
|
requested: void 0,
|
|
90
|
-
available:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
}, `${token} takes no quota in this market, so it counts as no collateral`);
|
|
102
|
+
available: 0n,
|
|
103
|
+
underlying: toToken(sdk, underlying)
|
|
104
|
+
}), `${token} takes no quota in this market, so it counts as no collateral`);
|
|
95
105
|
}
|
|
96
106
|
}
|
|
97
107
|
/**
|
|
@@ -106,7 +116,7 @@ function assertGrowthAllowed(args) {
|
|
|
106
116
|
* - here, `1.0` — what the facade enforces, so what a plan must clear to land;
|
|
107
117
|
* - `maxWithdrawCollateral` sizes at `MIN_HF_LIMITED + 2` — a *sizing* helper
|
|
108
118
|
* leaving headroom, which is not the same as a validity check;
|
|
109
|
-
* -
|
|
119
|
+
* - a form refuses at or below `MIN_HF_LIMITED` (`MIN_HEALTH_FACTOR_FORM`).
|
|
110
120
|
*
|
|
111
121
|
* Raising this one to `MIN_HF_LIMITED` was tried and reverted: it made
|
|
112
122
|
* `maxWithdraw` hand back a ceiling this guard then refused, and it blocked
|
|
@@ -124,35 +134,30 @@ function assertGrowthAllowed(args) {
|
|
|
124
134
|
* still be refused on-chain after passing here.
|
|
125
135
|
*/
|
|
126
136
|
function assertCollateralised(healthFactorBps, safePrices) {
|
|
127
|
-
const required =
|
|
128
|
-
|
|
137
|
+
const required = MIN_HEALTH_FACTOR_FACADE;
|
|
138
|
+
raise(checkCollateralised({
|
|
129
139
|
healthFactor: healthFactorBps,
|
|
130
140
|
required,
|
|
131
141
|
safePrices
|
|
132
|
-
}, `the account would end at a health factor of ${healthFactorBps}, below ${required}`);
|
|
142
|
+
}), `the account would end at a health factor of ${healthFactorBps}, below ${required}`);
|
|
133
143
|
}
|
|
134
144
|
/**
|
|
135
145
|
* A quota can only be raised as far as the market still has room for: past the
|
|
136
146
|
* token's limit the keeper takes nothing more, whoever is asking.
|
|
137
147
|
*/
|
|
138
|
-
function assertQuotaHeadroom(market, increases) {
|
|
148
|
+
function assertQuotaHeadroom(sdk, market, increases) {
|
|
139
149
|
const underlying = market.pool.underlying;
|
|
140
150
|
for (const { token, balance } of increases) {
|
|
141
151
|
if (balance <= 0n) continue;
|
|
142
152
|
const quota = market.pool.pqk.quotas.get(token);
|
|
143
153
|
if (!quota) continue;
|
|
144
154
|
const left = quota.limit - quota.totalQuoted;
|
|
145
|
-
|
|
146
|
-
token,
|
|
147
|
-
requested:
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
available: {
|
|
152
|
-
token: underlying,
|
|
153
|
-
balance: left
|
|
154
|
-
}
|
|
155
|
-
}, `${token} has ${left} of quota left, the plan needs ${balance}`);
|
|
155
|
+
raise(checkQuotaLimit({
|
|
156
|
+
token: toToken(sdk, token),
|
|
157
|
+
requested: balance,
|
|
158
|
+
available: left,
|
|
159
|
+
underlying: toToken(sdk, underlying)
|
|
160
|
+
}), `${token} has ${left} of quota left, the plan needs ${balance}`);
|
|
156
161
|
}
|
|
157
162
|
}
|
|
158
163
|
//#endregion
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SDKConstruct } from "../../base/SDKConstruct.js";
|
|
2
|
-
import { MIN_HF_LIMITED } from "
|
|
3
|
-
import { IntentPreviewError, refuse } from "
|
|
4
|
-
import { assertMarketOperable } from "./guards.js";
|
|
2
|
+
import { MIN_HF_LIMITED } from "../../validation/checks.js";
|
|
3
|
+
import { IntentPreviewError, refuse } from "../../validation/refusal.js";
|
|
4
|
+
import { assertMarketOperable, borrowable } from "./guards.js";
|
|
5
5
|
import { fetchCreditAccountSlice, toCreditAccountSlice } from "./utils/credit-account-slice.js";
|
|
6
6
|
import { calcLeverageBand } from "./leverage-band.js";
|
|
7
7
|
import { maxProportionalWithdrawal } from "./math.js";
|
|
@@ -103,7 +103,7 @@ var CreditAccountOperationsService = class extends SDKConstruct {
|
|
|
103
103
|
* activity come from the account's market, valued the way the facade values
|
|
104
104
|
* a call that pays out; zero debt frees the whole balance.
|
|
105
105
|
*
|
|
106
|
-
* The default is {@link MIN_HF_LIMITED}, the bar
|
|
106
|
+
* The default is {@link MIN_HF_LIMITED}, the bar a form holds an
|
|
107
107
|
* account to.
|
|
108
108
|
*
|
|
109
109
|
* @param props - Account slice, the SDK holding its market, the collateral
|
|
@@ -314,4 +314,4 @@ function isUnroutable(e) {
|
|
|
314
314
|
return false;
|
|
315
315
|
}
|
|
316
316
|
//#endregion
|
|
317
|
-
export { CreditAccountOperationsService,
|
|
317
|
+
export { CreditAccountOperationsService, borrowable, fetchCreditAccountSlice, toCreditAccountSlice };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { BigIntMath } from "../../utils/bigint-math.js";
|
|
2
2
|
import { LEVERAGE_DECIMALS } from "../../constants/math.js";
|
|
3
|
-
import {
|
|
3
|
+
import { checkDebtInBand, checkLeverageAtLeastOne } from "../../validation/checks.js";
|
|
4
|
+
import { IntentPreviewError, raise } from "../../validation/refusal.js";
|
|
5
|
+
import { toToken } from "../../validation/token.js";
|
|
4
6
|
//#region src/onchain/accounts/intents/math.ts
|
|
5
7
|
/** Debt that realises `leverage` on `collateral`: `D = C · (L − 1)`. */
|
|
6
8
|
function debtForLeverage(collateral, leverage) {
|
|
@@ -37,32 +39,23 @@ function maxProportionalWithdrawal(position, band) {
|
|
|
37
39
|
}
|
|
38
40
|
/** Total leverage cannot drop below 1x — that would be negative debt. */
|
|
39
41
|
function assertLeverageAtLeastOne(leverage) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
raise(checkLeverageAtLeastOne({
|
|
43
|
+
leverage,
|
|
42
44
|
min: LEVERAGE_DECIMALS
|
|
43
|
-
}, `target leverage ${leverage} is below 1x`);
|
|
45
|
+
}), `target leverage ${leverage} is below 1x`);
|
|
44
46
|
}
|
|
45
47
|
/**
|
|
46
48
|
* Rejects a debt the facade would revert on: zero is always fine (no loan at
|
|
47
49
|
* all), anything else has to sit inside `[minDebt, maxDebt]`.
|
|
48
50
|
*/
|
|
49
|
-
function assertDebtInBand(debt, band, underlying) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
balance: band.minDebt
|
|
58
|
-
},
|
|
59
|
-
maxDebt: {
|
|
60
|
-
token: underlying,
|
|
61
|
-
balance: band.maxDebt
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
if (debt > band.maxDebt) throw new IntentPreviewError("debtOutOfRange", detail, `debt ${debt} exceeds maxDebt ${band.maxDebt}`);
|
|
65
|
-
if (debt > 0n && debt < band.minDebt) throw new IntentPreviewError("debtOutOfRange", detail, `debt ${debt} is below minDebt ${band.minDebt}`);
|
|
51
|
+
function assertDebtInBand(sdk, debt, band, underlying) {
|
|
52
|
+
raise(checkDebtInBand({
|
|
53
|
+
debt,
|
|
54
|
+
minDebt: band.minDebt,
|
|
55
|
+
maxDebt: band.maxDebt,
|
|
56
|
+
underlying: toToken(sdk, underlying),
|
|
57
|
+
allowZero: true
|
|
58
|
+
}), debt > band.maxDebt ? `debt ${debt} exceeds maxDebt ${band.maxDebt}` : `debt ${debt} is below minDebt ${band.minDebt}`);
|
|
66
59
|
}
|
|
67
60
|
//#endregion
|
|
68
61
|
export { assertDebtInBand, assertLeverageAtLeastOne, debtForLeverage, maxProportionalWithdrawal, proportionalDebt };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IntentPreviewError } from "
|
|
1
|
+
import { IntentPreviewError } from "../../validation/refusal.js";
|
|
2
2
|
import { convertAmount } from "./utils/convert-amount.js";
|
|
3
3
|
import { assertCanBorrow, assertCollateralised, assertGrowthAllowed, assertMarketOperable, assertQuotaHeadroom } from "./guards.js";
|
|
4
4
|
import { collectPriceImpact } from "./utils/price-impact.js";
|
|
@@ -41,8 +41,8 @@ async function previewOpenStrategy(props) {
|
|
|
41
41
|
accountDebt: 0n,
|
|
42
42
|
tokens: []
|
|
43
43
|
};
|
|
44
|
-
assertDebtInBand(debt, suite.creditFacade, underlying);
|
|
45
|
-
assertCanBorrow(suite, debt);
|
|
44
|
+
assertDebtInBand(sdk, debt, suite.creditFacade, underlying);
|
|
45
|
+
assertCanBorrow(sdk, suite, debt);
|
|
46
46
|
const paths = createRouterPaths({
|
|
47
47
|
sdk,
|
|
48
48
|
creditAccount: account,
|
|
@@ -77,7 +77,7 @@ async function previewOpenStrategy(props) {
|
|
|
77
77
|
before: [],
|
|
78
78
|
after: averageAssets
|
|
79
79
|
});
|
|
80
|
-
assertQuotaHeadroom(market, averageQuota);
|
|
80
|
+
assertQuotaHeadroom(sdk, market, averageQuota);
|
|
81
81
|
const snapshot = {
|
|
82
82
|
creditManager,
|
|
83
83
|
assets: averageAssets,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MAX_UINT256, PERCENTAGE_FACTOR } from "../../constants/math.js";
|
|
2
2
|
import "../../constants/index.js";
|
|
3
|
-
import { IntentPreviewError } from "
|
|
3
|
+
import { IntentPreviewError } from "../../validation/refusal.js";
|
|
4
|
+
import { toToken, toTokenAmount } from "../../validation/token.js";
|
|
4
5
|
import { eq } from "./utils/common.js";
|
|
5
6
|
import { assertDebtInBand, assertLeverageAtLeastOne, debtForLeverage, proportionalDebt } from "./math.js";
|
|
6
7
|
//#region src/onchain/accounts/intents/plan.ts
|
|
@@ -24,14 +25,8 @@ function planAdjustLeverage(intent, view) {
|
|
|
24
25
|
if (delta > 0n) return [borrow(delta), convert(U, T, delta)];
|
|
25
26
|
const shortfall = -delta - view.balanceOf(U);
|
|
26
27
|
if (shortfall > 0n && eq(T, U)) throw new IntentPreviewError("insufficientSourceBalance", {
|
|
27
|
-
required:
|
|
28
|
-
|
|
29
|
-
balance: -delta
|
|
30
|
-
},
|
|
31
|
-
held: {
|
|
32
|
-
token: U,
|
|
33
|
-
balance: view.balanceOf(U)
|
|
34
|
-
}
|
|
28
|
+
required: toTokenAmount(view.sdk, U, -delta),
|
|
29
|
+
held: toTokenAmount(view.sdk, U, view.balanceOf(U))
|
|
35
30
|
}, `adjustLeverage: needs ${-delta} underlying, account holds ${view.balanceOf(U)}`);
|
|
36
31
|
return [...shortfall > 0n ? [convert(T, U, view.price(U, T, shortfall))] : [], repay(-delta)];
|
|
37
32
|
}
|
|
@@ -39,11 +34,11 @@ function planAdjustLeverage(intent, view) {
|
|
|
39
34
|
function planDeposit(intent, view) {
|
|
40
35
|
assertPositive(intent.amount, "deposit");
|
|
41
36
|
const U = view.underlying;
|
|
42
|
-
if (!eq(intent.token, U) && !(view.rwaAsset && eq(intent.token, view.rwaAsset))) throw new IntentPreviewError("unsupportedCollateralToken", { token: intent.token }, `deposit: only ${U}${view.rwaAsset ? ` or ${view.rwaAsset}` : ""} can be deposited, got ${intent.token}`);
|
|
37
|
+
if (!eq(intent.token, U) && !(view.rwaAsset && eq(intent.token, view.rwaAsset))) throw new IntentPreviewError("unsupportedCollateralToken", { token: toToken(view.sdk, intent.token) }, `deposit: only ${U}${view.rwaAsset ? ` or ${view.rwaAsset}` : ""} can be deposited, got ${intent.token}`);
|
|
43
38
|
const aU = view.price(intent.token, U, intent.amount);
|
|
44
39
|
const debtDelta = intent.targetLeverage === void 0 ? proportionalDebt(view, aU) : debtForLeverage(view.collateral + aU, intent.targetLeverage) - view.debt;
|
|
45
40
|
if (debtDelta < 0n) throw new IntentPreviewError("leverageOutOfRange", void 0, `deposit: target leverage ${intent.targetLeverage} would require repaying debt`);
|
|
46
|
-
assertDebtInBand(view.debt + debtDelta, view.band, U);
|
|
41
|
+
assertDebtInBand(view.sdk, view.debt + debtDelta, view.band, U);
|
|
47
42
|
const T = intent.positionToken ?? positionToken(view, "deposit");
|
|
48
43
|
const depositStays = eq(intent.token, T);
|
|
49
44
|
return [
|
|
@@ -70,24 +65,15 @@ function planRepay(intent, view) {
|
|
|
70
65
|
assertPositive(intent.amount, "repay");
|
|
71
66
|
const U = view.underlying;
|
|
72
67
|
const fundsInU = eq(intent.token, U);
|
|
73
|
-
if (!fundsInU && !(view.rwaAsset && eq(intent.token, view.rwaAsset))) throw new IntentPreviewError("unsupportedCollateralToken", { token: intent.token }, `repay: only ${U}${view.rwaAsset ? ` or ${view.rwaAsset}` : ""} can be repaid with, got ${intent.token}`);
|
|
68
|
+
if (!fundsInU && !(view.rwaAsset && eq(intent.token, view.rwaAsset))) throw new IntentPreviewError("unsupportedCollateralToken", { token: toToken(view.sdk, intent.token) }, `repay: only ${U}${view.rwaAsset ? ` or ${view.rwaAsset}` : ""} can be repaid with, got ${intent.token}`);
|
|
74
69
|
if (view.debt <= 0n) throw new IntentPreviewError("debtOutOfRange", {
|
|
75
|
-
requested:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
},
|
|
79
|
-
minDebt: {
|
|
80
|
-
token: U,
|
|
81
|
-
balance: view.band.minDebt
|
|
82
|
-
},
|
|
83
|
-
maxDebt: {
|
|
84
|
-
token: U,
|
|
85
|
-
balance: view.band.maxDebt
|
|
86
|
-
}
|
|
70
|
+
requested: toTokenAmount(view.sdk, U, view.debt),
|
|
71
|
+
minDebt: toTokenAmount(view.sdk, U, view.band.minDebt),
|
|
72
|
+
maxDebt: toTokenAmount(view.sdk, U, view.band.maxDebt)
|
|
87
73
|
}, "repay: the account owes nothing");
|
|
88
74
|
const funding = everything(intent.amount) ? view.price(U, intent.token, withMargin(view.debt)) : intent.amount;
|
|
89
75
|
const repaid = min(view.price(intent.token, U, funding), view.debt);
|
|
90
|
-
assertDebtInBand(view.debt - repaid, view.band,
|
|
76
|
+
assertDebtInBand(view.sdk, view.debt - repaid, view.band, view.underlying);
|
|
91
77
|
return [
|
|
92
78
|
add(intent.token, funding, intent.value),
|
|
93
79
|
...fundsInU ? [] : [convert(intent.token, U, funding)],
|
|
@@ -155,7 +141,7 @@ function planWithdrawDelayed(intent, view) {
|
|
|
155
141
|
}
|
|
156
142
|
}];
|
|
157
143
|
}
|
|
158
|
-
if (!eq(T, U) && !(view.rwaAsset && eq(T, view.rwaAsset))) throw new IntentPreviewError("noDelayedRoute", { token: T }, `withdraw: a delayed route cannot pay out in ${T}`);
|
|
144
|
+
if (!eq(T, U) && !(view.rwaAsset && eq(T, view.rwaAsset))) throw new IntentPreviewError("noDelayedRoute", { token: toToken(view.sdk, T) }, `withdraw: a delayed route cannot pay out in ${T}`);
|
|
159
145
|
const payoutIsSource = eq(T, S);
|
|
160
146
|
return [{
|
|
161
147
|
kind: "request",
|
|
@@ -211,7 +197,7 @@ function planFinishWithdraw(intent, claimable, claimed, view) {
|
|
|
211
197
|
const U = view.underlying;
|
|
212
198
|
const T = intent.withdrawToken;
|
|
213
199
|
const W = intent.withdrawAmount;
|
|
214
|
-
if (!eq(T, U) && !(view.rwaAsset && eq(T, view.rwaAsset))) throw new IntentPreviewError("noDelayedRoute", { token: T }, `finishWithdraw: cannot pay out in ${T}`);
|
|
200
|
+
if (!eq(T, U) && !(view.rwaAsset && eq(T, view.rwaAsset))) throw new IntentPreviewError("noDelayedRoute", { token: toToken(view.sdk, T) }, `finishWithdraw: cannot pay out in ${T}`);
|
|
215
201
|
if (intent.debtRepaid === 0n) return [
|
|
216
202
|
claim(claimable),
|
|
217
203
|
convert(claimed.token, T, claimed.amount),
|
|
@@ -316,7 +302,7 @@ function withdrawShape(intent, view) {
|
|
|
316
302
|
};
|
|
317
303
|
}
|
|
318
304
|
const dD = proportionalDebt(view, WU);
|
|
319
|
-
assertDebtInBand(view.debt - dD, view.band,
|
|
305
|
+
assertDebtInBand(view.sdk, view.debt - dD, view.band, view.underlying);
|
|
320
306
|
return {
|
|
321
307
|
U,
|
|
322
308
|
T,
|
|
@@ -335,7 +321,7 @@ function leverageShape(intent, view) {
|
|
|
335
321
|
assertLeverageAtLeastOne(intent.targetLeverage);
|
|
336
322
|
if (view.collateral <= 0n) throw new IntentPreviewError("insufficientSourceBalance", void 0, "adjustLeverage: account has no collateral to lever");
|
|
337
323
|
const target = debtForLeverage(view.collateral, intent.targetLeverage);
|
|
338
|
-
assertDebtInBand(target, view.band, view.underlying);
|
|
324
|
+
assertDebtInBand(view.sdk, target, view.band, view.underlying);
|
|
339
325
|
return {
|
|
340
326
|
U: view.underlying,
|
|
341
327
|
delta: target - view.debt
|