@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.
Files changed (186) hide show
  1. package/dist/cjs/common-utils/index.js +3 -21
  2. package/dist/cjs/common-utils/test-utils/index.js +4 -3
  3. package/dist/cjs/common-utils/utils/index.js +3 -22
  4. package/dist/cjs/common-utils/utils/strategies/index.js +3 -0
  5. package/dist/cjs/common-utils/utils/strategies/strategy-info/cm-availability-condition.js +5 -5
  6. package/dist/cjs/common-utils/utils/strategies/strategy-info/credit-manager-issues.js +135 -0
  7. package/dist/cjs/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +12 -23
  8. package/dist/cjs/common-utils/utils/strategies/strategy-info/index.js +3 -0
  9. package/dist/cjs/onchain/accounts/index.js +2 -3
  10. package/dist/cjs/onchain/accounts/intents/guards.js +55 -50
  11. package/dist/cjs/onchain/accounts/intents/index.js +7 -8
  12. package/dist/cjs/onchain/accounts/intents/math.js +15 -22
  13. package/dist/cjs/onchain/accounts/intents/open-strategy.js +5 -5
  14. package/dist/cjs/onchain/accounts/intents/plan.js +27 -41
  15. package/dist/cjs/onchain/accounts/intents/realize.js +14 -21
  16. package/dist/cjs/onchain/accounts/intents/tail.js +2 -2
  17. package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +1 -0
  18. package/dist/cjs/onchain/accounts/intents/view.js +1 -0
  19. package/dist/cjs/onchain/constants/index.js +1 -0
  20. package/dist/cjs/onchain/constants/math.js +11 -0
  21. package/dist/cjs/onchain/index.js +32 -3
  22. package/dist/cjs/onchain/validation/checks.js +250 -0
  23. package/dist/cjs/onchain/validation/index.js +29 -0
  24. package/dist/cjs/onchain/{accounts/intents → validation}/refusal.js +12 -1
  25. package/dist/cjs/onchain/validation/token.js +29 -0
  26. package/dist/cjs/preview/index.js +10 -0
  27. package/dist/cjs/preview/preview/buildDelayedPreview.js +1 -0
  28. package/dist/cjs/preview/preview/previewAdjustCreditAccount.js +1 -0
  29. package/dist/cjs/preview/preview/previewOpenCreditAccount.js +1 -0
  30. package/dist/cjs/preview/validate/checkOperation.js +173 -0
  31. package/dist/cjs/preview/validate/checkSimulation.js +52 -0
  32. package/dist/cjs/preview/validate/index.js +6 -0
  33. package/dist/cjs/sdk/index.js +4 -0
  34. package/dist/cjs/sdk/prepare/PrepareApi.js +17 -13
  35. package/dist/cjs/sdk/prepare/index.js +4 -0
  36. package/dist/cjs/sdk/prepare/types.js +4 -0
  37. package/dist/esm/common-utils/index.js +2 -11
  38. package/dist/esm/common-utils/test-utils/index.js +4 -3
  39. package/dist/esm/common-utils/utils/index.js +2 -12
  40. package/dist/esm/common-utils/utils/strategies/index.js +2 -1
  41. package/dist/esm/common-utils/utils/strategies/strategy-info/cm-availability-condition.js +5 -5
  42. package/dist/esm/common-utils/utils/strategies/strategy-info/credit-manager-issues.js +133 -0
  43. package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +12 -23
  44. package/dist/esm/common-utils/utils/strategies/strategy-info/index.js +2 -1
  45. package/dist/esm/dev/AccountOpener.js +1 -1
  46. package/dist/esm/dev/withdrawalUtils.js +1 -1
  47. package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +2 -2
  48. package/dist/esm/onchain/accounts/index.js +2 -2
  49. package/dist/esm/onchain/accounts/intents/guards.js +55 -50
  50. package/dist/esm/onchain/accounts/intents/index.js +5 -5
  51. package/dist/esm/onchain/accounts/intents/math.js +14 -21
  52. package/dist/esm/onchain/accounts/intents/open-strategy.js +4 -4
  53. package/dist/esm/onchain/accounts/intents/plan.js +15 -29
  54. package/dist/esm/onchain/accounts/intents/realize.js +12 -19
  55. package/dist/esm/onchain/accounts/intents/tail.js +1 -1
  56. package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +1 -0
  57. package/dist/esm/onchain/accounts/intents/view.js +1 -0
  58. package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +1 -1
  59. package/dist/esm/onchain/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  60. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  61. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  62. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  63. package/dist/esm/onchain/base/TokensMeta.js +3 -3
  64. package/dist/esm/onchain/chain/detectNetwork.js +1 -1
  65. package/dist/esm/onchain/constants/index.js +2 -2
  66. package/dist/esm/onchain/constants/math.js +11 -1
  67. package/dist/esm/onchain/core/createAddressProvider.js +1 -1
  68. package/dist/esm/onchain/index.js +7 -3
  69. package/dist/esm/onchain/market/adapters/contracts/AccountMigratorAdapterContract.js +1 -1
  70. package/dist/esm/onchain/market/adapters/contracts/ERC4626AdapterContract.js +1 -1
  71. package/dist/esm/onchain/market/credit/CreditFacadeV310BaseContract.js +1 -1
  72. package/dist/esm/onchain/market/pool/PoolV310Contract.js +1 -1
  73. package/dist/esm/onchain/market/zapper/IETHZapperContract.js +1 -1
  74. package/dist/esm/onchain/market/zapper/ZapperContract.js +1 -1
  75. package/dist/esm/onchain/pools/PoolService.js +1 -1
  76. package/dist/esm/onchain/utils/viem/simulateWithPriceUpdates.js +1 -1
  77. package/dist/esm/onchain/validation/checks.js +230 -0
  78. package/dist/esm/onchain/validation/index.js +4 -0
  79. package/dist/esm/onchain/{accounts/intents → validation}/refusal.js +12 -2
  80. package/dist/esm/onchain/validation/token.js +27 -0
  81. package/dist/esm/preview/index.js +5 -1
  82. package/dist/esm/preview/preview/buildDelayedPreview.js +1 -0
  83. package/dist/esm/preview/preview/previewAdjustCreditAccount.js +1 -0
  84. package/dist/esm/preview/preview/previewOpenCreditAccount.js +1 -0
  85. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  86. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  87. package/dist/esm/preview/validate/checkOperation.js +171 -0
  88. package/dist/esm/preview/validate/checkSimulation.js +51 -0
  89. package/dist/esm/preview/validate/index.js +3 -0
  90. package/dist/esm/sdk/index.js +2 -1
  91. package/dist/esm/sdk/prepare/PrepareApi.js +15 -11
  92. package/dist/esm/sdk/prepare/index.js +2 -1
  93. package/dist/esm/sdk/prepare/types.js +2 -1
  94. package/dist/types/common-utils/index.d.ts +2 -12
  95. package/dist/types/common-utils/utils/index.d.ts +2 -13
  96. package/dist/types/common-utils/utils/strategies/index.d.ts +2 -1
  97. package/dist/types/common-utils/utils/strategies/strategy-info/credit-manager-issues.d.ts +34 -0
  98. package/dist/types/common-utils/utils/strategies/strategy-info/index.d.ts +2 -1
  99. package/dist/types/model/previews.d.ts +22 -0
  100. package/dist/types/onchain/accounts/index.d.ts +2 -2
  101. package/dist/types/onchain/accounts/intents/guards.d.ts +8 -4
  102. package/dist/types/onchain/accounts/intents/index.d.ts +4 -3
  103. package/dist/types/onchain/accounts/intents/math.d.ts +2 -1
  104. package/dist/types/onchain/accounts/intents/plan.d.ts +3 -0
  105. package/dist/types/onchain/accounts/intents/types.d.ts +7 -1
  106. package/dist/types/onchain/constants/index.d.ts +2 -2
  107. package/dist/types/onchain/constants/math.d.ts +9 -1
  108. package/dist/types/onchain/index.d.ts +7 -3
  109. package/dist/types/onchain/validation/checks.d.ts +167 -0
  110. package/dist/types/onchain/validation/index.d.ts +4 -0
  111. package/dist/types/onchain/{accounts/intents → validation}/refusal.d.ts +100 -31
  112. package/dist/types/onchain/validation/token.d.ts +17 -0
  113. package/dist/types/preview/index.d.ts +5 -1
  114. package/dist/types/preview/validate/checkOperation.d.ts +46 -0
  115. package/dist/types/preview/validate/checkSimulation.d.ts +34 -0
  116. package/dist/types/preview/validate/index.d.ts +3 -0
  117. package/dist/types/sdk/index.d.ts +2 -2
  118. package/dist/types/sdk/prepare/index.d.ts +2 -2
  119. package/dist/types/sdk/prepare/types.d.ts +2 -2
  120. package/package.json +1 -1
  121. package/dist/cjs/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.js +0 -267
  122. package/dist/cjs/common-utils/utils/validation/index.js +0 -23
  123. package/dist/cjs/common-utils/utils/validation/is-zero-balance.js +0 -7
  124. package/dist/cjs/common-utils/utils/validation/validate-balance.js +0 -22
  125. package/dist/cjs/common-utils/utils/validation/validate-balance.spec.js +0 -54
  126. package/dist/cjs/common-utils/utils/validation/validate-balances.js +0 -17
  127. package/dist/cjs/common-utils/utils/validation/validate-balances.spec.js +0 -45
  128. package/dist/cjs/common-utils/utils/validation/validate-credit-manager.js +0 -8
  129. package/dist/cjs/common-utils/utils/validation/validate-credit-manager.spec.js +0 -36
  130. package/dist/cjs/common-utils/utils/validation/validate-hf.js +0 -10
  131. package/dist/cjs/common-utils/utils/validation/validate-hf.spec.js +0 -26
  132. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-quota-status.js +0 -14
  133. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.js +0 -29
  134. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.js +0 -37
  135. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.spec.js +0 -98
  136. package/dist/cjs/common-utils/utils/validation/validate-open-account.js +0 -18
  137. package/dist/cjs/common-utils/utils/validation/validate-open-account.spec.js +0 -56
  138. package/dist/cjs/common-utils/utils/validation/validate-quota.js +0 -23
  139. package/dist/cjs/common-utils/utils/validation/validate-quota.spec.js +0 -88
  140. package/dist/cjs/common-utils/utils/validation/validate-token-to-obtain.js +0 -18
  141. package/dist/cjs/common-utils/utils/validation/validate-token-to-obtain.spec.js +0 -36
  142. package/dist/cjs/common-utils/utils/validation/validation-types.js +0 -1
  143. package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.js +0 -264
  144. package/dist/esm/common-utils/utils/validation/index.js +0 -12
  145. package/dist/esm/common-utils/utils/validation/is-zero-balance.js +0 -6
  146. package/dist/esm/common-utils/utils/validation/validate-balance.js +0 -21
  147. package/dist/esm/common-utils/utils/validation/validate-balance.spec.js +0 -54
  148. package/dist/esm/common-utils/utils/validation/validate-balances.js +0 -16
  149. package/dist/esm/common-utils/utils/validation/validate-balances.spec.js +0 -45
  150. package/dist/esm/common-utils/utils/validation/validate-credit-manager.js +0 -7
  151. package/dist/esm/common-utils/utils/validation/validate-credit-manager.spec.js +0 -36
  152. package/dist/esm/common-utils/utils/validation/validate-hf.js +0 -8
  153. package/dist/esm/common-utils/utils/validation/validate-hf.spec.js +0 -26
  154. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-quota-status.js +0 -13
  155. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.js +0 -29
  156. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.js +0 -36
  157. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.spec.js +0 -98
  158. package/dist/esm/common-utils/utils/validation/validate-open-account.js +0 -17
  159. package/dist/esm/common-utils/utils/validation/validate-open-account.spec.js +0 -56
  160. package/dist/esm/common-utils/utils/validation/validate-quota.js +0 -22
  161. package/dist/esm/common-utils/utils/validation/validate-quota.spec.js +0 -88
  162. package/dist/esm/common-utils/utils/validation/validate-token-to-obtain.js +0 -17
  163. package/dist/esm/common-utils/utils/validation/validate-token-to-obtain.spec.js +0 -36
  164. package/dist/esm/common-utils/utils/validation/validation-types.js +0 -1
  165. package/dist/types/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.d.ts +0 -1
  166. package/dist/types/common-utils/utils/validation/index.d.ts +0 -12
  167. package/dist/types/common-utils/utils/validation/is-zero-balance.d.ts +0 -4
  168. package/dist/types/common-utils/utils/validation/validate-balance.d.ts +0 -25
  169. package/dist/types/common-utils/utils/validation/validate-balance.spec.d.ts +0 -1
  170. package/dist/types/common-utils/utils/validation/validate-balances.d.ts +0 -13
  171. package/dist/types/common-utils/utils/validation/validate-balances.spec.d.ts +0 -1
  172. package/dist/types/common-utils/utils/validation/validate-credit-manager.d.ts +0 -13
  173. package/dist/types/common-utils/utils/validation/validate-credit-manager.spec.d.ts +0 -1
  174. package/dist/types/common-utils/utils/validation/validate-hf.d.ts +0 -12
  175. package/dist/types/common-utils/utils/validation/validate-hf.spec.d.ts +0 -1
  176. package/dist/types/common-utils/utils/validation/validate-open-account-pool-quota-status.d.ts +0 -10
  177. package/dist/types/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.d.ts +0 -1
  178. package/dist/types/common-utils/utils/validation/validate-open-account-pool-status.d.ts +0 -26
  179. package/dist/types/common-utils/utils/validation/validate-open-account-pool-status.spec.d.ts +0 -1
  180. package/dist/types/common-utils/utils/validation/validate-open-account.d.ts +0 -25
  181. package/dist/types/common-utils/utils/validation/validate-open-account.spec.d.ts +0 -1
  182. package/dist/types/common-utils/utils/validation/validate-quota.d.ts +0 -24
  183. package/dist/types/common-utils/utils/validation/validate-quota.spec.d.ts +0 -1
  184. package/dist/types/common-utils/utils/validation/validate-token-to-obtain.d.ts +0 -17
  185. package/dist/types/common-utils/utils/validation/validate-token-to-obtain.spec.d.ts +0 -1
  186. 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 { validateOpenAccountPoolStatus } from "../../validation/validate-open-account-pool-status.js";
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 = validateCreditManager({ creditManager }) || validateOpenAccountPoolStatus({
180
- pool,
174
+ const error = collateral.some((a) => isZeroBalance(a.balance)) ? { reason: "insufficientSourceBalance" } : checkCreditManagerUsable({
181
175
  creditManager,
176
+ pool,
182
177
  debt,
183
- targetToken: targetTokenAddress
184
- }) || validateTokenToObtain({
185
- targetToken: strategy.tokenOutAddress,
186
- creditManager
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
- debt,
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.message}`,
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 { IntentPreviewError, refuse } from "./intents/refusal.js";
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, IntentPreviewError, InvalidDelayedIntentError, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService, PeripheryCompressorV310Contract, RedemptionLoggerV310Contract, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, encodeDelayedIntent, fetchCreditAccountSlice, getWithdrawalCompressorAddress, iCreditAccountAbi, refuse, toClaimableWithdrawal, toCreditAccountSlice, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
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 { PERCENTAGE_FACTOR } from "../../constants/math.js";
2
- import "../../constants/index.js";
3
- import { IntentPreviewError } from "./refusal.js";
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
- if (suite.isPaused) throw new IntentPreviewError("marketPaused", { creditManager }, `${creditManager} is paused`);
28
- if (suite.isExpired) throw new IntentPreviewError("marketExpired", {
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 0n;
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
- pool.availableLiquidity,
46
- maxDebt * BigInt(maxDebtPerBlockMultiplier),
47
- ...available === void 0 ? [] : [available]
48
- ].reduce((a, b) => a < b ? a : b);
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
- if (amount > limit) {
54
- const token = suite.market.pool.underlying;
55
- throw new IntentPreviewError("insufficientPoolLiquidity", {
56
- requested: {
57
- token,
58
- balance: amount
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
- if (forbidden.some((f) => eq(f, token))) throw new IntentPreviewError("forbiddenToken", { token }, `${token} is forbidden in this market and the plan buys more of it`);
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)) throw new IntentPreviewError("quotaLimitReached", {
88
- token,
99
+ if (!market.pool.pqk.hasActiveQuota(token)) raise(checkQuotaLimit({
100
+ token: toToken(sdk, token),
89
101
  requested: void 0,
90
- available: {
91
- token: underlying,
92
- balance: 0n
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
- * - `validateHF` refuses at or below `MIN_HF_LIMITED` — a form's own caution.
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 = Number(PERCENTAGE_FACTOR);
128
- if (healthFactorBps < required) throw new IntentPreviewError("insufficientCollateral", {
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
- if (balance > left) throw new IntentPreviewError("quotaLimitReached", {
146
- token,
147
- requested: {
148
- token: underlying,
149
- balance
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 "../../../common-utils/utils/validation/validate-hf.js";
3
- import { IntentPreviewError, refuse } from "./refusal.js";
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 `validateHF` holds an
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, IntentPreviewError, fetchCreditAccountSlice, refuse, toCreditAccountSlice };
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 { IntentPreviewError } from "./refusal.js";
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
- if (leverage < 100n) throw new IntentPreviewError("leverageOutOfRange", {
41
- requested: leverage,
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
- const detail = {
51
- requested: {
52
- token: underlying,
53
- balance: debt
54
- },
55
- minDebt: {
56
- token: underlying,
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 "./refusal.js";
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 "./refusal.js";
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
- token: U,
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
- token: U,
77
- balance: view.debt
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, U);
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, U);
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