@gearbox-protocol/sdk 16.0.0-next.17 → 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 (197) 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 +24 -16
  12. package/dist/cjs/onchain/accounts/intents/leverage-band.js +2 -2
  13. package/dist/cjs/onchain/accounts/intents/math.js +15 -22
  14. package/dist/cjs/onchain/accounts/intents/open-strategy.js +5 -5
  15. package/dist/cjs/onchain/accounts/intents/plan.js +27 -41
  16. package/dist/cjs/onchain/accounts/intents/realize.js +14 -21
  17. package/dist/cjs/onchain/accounts/intents/tail.js +2 -2
  18. package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +2 -1
  19. package/dist/cjs/onchain/accounts/intents/view.js +1 -0
  20. package/dist/cjs/onchain/constants/index.js +1 -0
  21. package/dist/cjs/onchain/constants/math.js +11 -0
  22. package/dist/cjs/onchain/index.js +32 -3
  23. package/dist/cjs/onchain/market/credit/CreditManagerV310Contract.js +2 -2
  24. package/dist/cjs/onchain/market/math.js +23 -11
  25. package/dist/cjs/onchain/validation/checks.js +250 -0
  26. package/dist/cjs/onchain/validation/index.js +29 -0
  27. package/dist/cjs/onchain/{accounts/intents → validation}/refusal.js +12 -1
  28. package/dist/cjs/onchain/validation/token.js +29 -0
  29. package/dist/cjs/preview/index.js +10 -0
  30. package/dist/cjs/preview/preview/buildDelayedPreview.js +1 -0
  31. package/dist/cjs/preview/preview/previewAdjustCreditAccount.js +1 -0
  32. package/dist/cjs/preview/preview/previewOpenCreditAccount.js +1 -0
  33. package/dist/cjs/preview/validate/checkOperation.js +173 -0
  34. package/dist/cjs/preview/validate/checkSimulation.js +52 -0
  35. package/dist/cjs/preview/validate/index.js +6 -0
  36. package/dist/cjs/sdk/index.js +4 -0
  37. package/dist/cjs/sdk/prepare/PrepareApi.js +23 -17
  38. package/dist/cjs/sdk/prepare/index.js +4 -0
  39. package/dist/cjs/sdk/prepare/types.js +4 -0
  40. package/dist/esm/common-utils/index.js +2 -11
  41. package/dist/esm/common-utils/test-utils/index.js +4 -3
  42. package/dist/esm/common-utils/utils/index.js +2 -12
  43. package/dist/esm/common-utils/utils/strategies/index.js +2 -1
  44. package/dist/esm/common-utils/utils/strategies/strategy-info/cm-availability-condition.js +5 -5
  45. package/dist/esm/common-utils/utils/strategies/strategy-info/credit-manager-issues.js +133 -0
  46. package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +12 -23
  47. package/dist/esm/common-utils/utils/strategies/strategy-info/index.js +2 -1
  48. package/dist/esm/dev/AccountOpener.js +1 -1
  49. package/dist/esm/dev/withdrawalUtils.js +1 -1
  50. package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +2 -2
  51. package/dist/esm/onchain/accounts/index.js +2 -2
  52. package/dist/esm/onchain/accounts/intents/guards.js +55 -50
  53. package/dist/esm/onchain/accounts/intents/index.js +23 -14
  54. package/dist/esm/onchain/accounts/intents/leverage-band.js +2 -2
  55. package/dist/esm/onchain/accounts/intents/math.js +14 -21
  56. package/dist/esm/onchain/accounts/intents/open-strategy.js +4 -4
  57. package/dist/esm/onchain/accounts/intents/plan.js +15 -29
  58. package/dist/esm/onchain/accounts/intents/realize.js +12 -19
  59. package/dist/esm/onchain/accounts/intents/tail.js +1 -1
  60. package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +2 -1
  61. package/dist/esm/onchain/accounts/intents/view.js +1 -0
  62. package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +1 -1
  63. package/dist/esm/onchain/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  64. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  65. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  66. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  67. package/dist/esm/onchain/base/TokensMeta.js +3 -3
  68. package/dist/esm/onchain/chain/detectNetwork.js +1 -1
  69. package/dist/esm/onchain/constants/index.js +2 -2
  70. package/dist/esm/onchain/constants/math.js +11 -1
  71. package/dist/esm/onchain/core/createAddressProvider.js +1 -1
  72. package/dist/esm/onchain/index.js +7 -3
  73. package/dist/esm/onchain/market/adapters/contracts/AccountMigratorAdapterContract.js +1 -1
  74. package/dist/esm/onchain/market/adapters/contracts/ERC4626AdapterContract.js +1 -1
  75. package/dist/esm/onchain/market/credit/CreditFacadeV310BaseContract.js +1 -1
  76. package/dist/esm/onchain/market/credit/CreditManagerV310Contract.js +2 -2
  77. package/dist/esm/onchain/market/math.js +23 -11
  78. package/dist/esm/onchain/market/pool/PoolV310Contract.js +1 -1
  79. package/dist/esm/onchain/market/zapper/IETHZapperContract.js +1 -1
  80. package/dist/esm/onchain/market/zapper/ZapperContract.js +1 -1
  81. package/dist/esm/onchain/pools/PoolService.js +1 -1
  82. package/dist/esm/onchain/utils/viem/simulateWithPriceUpdates.js +1 -1
  83. package/dist/esm/onchain/validation/checks.js +230 -0
  84. package/dist/esm/onchain/validation/index.js +4 -0
  85. package/dist/esm/onchain/{accounts/intents → validation}/refusal.js +12 -2
  86. package/dist/esm/onchain/validation/token.js +27 -0
  87. package/dist/esm/preview/index.js +5 -1
  88. package/dist/esm/preview/preview/buildDelayedPreview.js +1 -0
  89. package/dist/esm/preview/preview/previewAdjustCreditAccount.js +1 -0
  90. package/dist/esm/preview/preview/previewOpenCreditAccount.js +1 -0
  91. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  92. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  93. package/dist/esm/preview/validate/checkOperation.js +171 -0
  94. package/dist/esm/preview/validate/checkSimulation.js +51 -0
  95. package/dist/esm/preview/validate/index.js +3 -0
  96. package/dist/esm/sdk/index.js +2 -1
  97. package/dist/esm/sdk/prepare/PrepareApi.js +21 -15
  98. package/dist/esm/sdk/prepare/index.js +2 -1
  99. package/dist/esm/sdk/prepare/types.js +2 -1
  100. package/dist/types/common-utils/index.d.ts +2 -12
  101. package/dist/types/common-utils/utils/index.d.ts +2 -13
  102. package/dist/types/common-utils/utils/strategies/index.d.ts +2 -1
  103. package/dist/types/common-utils/utils/strategies/strategy-info/credit-manager-issues.d.ts +34 -0
  104. package/dist/types/common-utils/utils/strategies/strategy-info/index.d.ts +2 -1
  105. package/dist/types/model/previews.d.ts +22 -0
  106. package/dist/types/onchain/accounts/index.d.ts +2 -2
  107. package/dist/types/onchain/accounts/intents/guards.d.ts +8 -4
  108. package/dist/types/onchain/accounts/intents/index.d.ts +20 -10
  109. package/dist/types/onchain/accounts/intents/leverage-band.d.ts +7 -2
  110. package/dist/types/onchain/accounts/intents/math.d.ts +2 -1
  111. package/dist/types/onchain/accounts/intents/plan.d.ts +3 -0
  112. package/dist/types/onchain/accounts/intents/types.d.ts +7 -1
  113. package/dist/types/onchain/constants/index.d.ts +2 -2
  114. package/dist/types/onchain/constants/math.d.ts +9 -1
  115. package/dist/types/onchain/index.d.ts +7 -3
  116. package/dist/types/onchain/market/credit/CreditManagerV310Contract.d.ts +1 -1
  117. package/dist/types/onchain/market/credit/types.d.ts +4 -3
  118. package/dist/types/onchain/market/math.d.ts +20 -9
  119. package/dist/types/onchain/validation/checks.d.ts +167 -0
  120. package/dist/types/onchain/validation/index.d.ts +4 -0
  121. package/dist/types/onchain/{accounts/intents → validation}/refusal.d.ts +100 -31
  122. package/dist/types/onchain/validation/token.d.ts +17 -0
  123. package/dist/types/preview/index.d.ts +5 -1
  124. package/dist/types/preview/validate/checkOperation.d.ts +46 -0
  125. package/dist/types/preview/validate/checkSimulation.d.ts +34 -0
  126. package/dist/types/preview/validate/index.d.ts +3 -0
  127. package/dist/types/sdk/index.d.ts +2 -2
  128. package/dist/types/sdk/prepare/PrepareApi.d.ts +3 -3
  129. package/dist/types/sdk/prepare/index.d.ts +2 -2
  130. package/dist/types/sdk/prepare/types.d.ts +8 -4
  131. package/package.json +1 -1
  132. package/dist/cjs/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.js +0 -267
  133. package/dist/cjs/common-utils/utils/validation/index.js +0 -23
  134. package/dist/cjs/common-utils/utils/validation/is-zero-balance.js +0 -7
  135. package/dist/cjs/common-utils/utils/validation/validate-balance.js +0 -22
  136. package/dist/cjs/common-utils/utils/validation/validate-balance.spec.js +0 -54
  137. package/dist/cjs/common-utils/utils/validation/validate-balances.js +0 -17
  138. package/dist/cjs/common-utils/utils/validation/validate-balances.spec.js +0 -45
  139. package/dist/cjs/common-utils/utils/validation/validate-credit-manager.js +0 -8
  140. package/dist/cjs/common-utils/utils/validation/validate-credit-manager.spec.js +0 -36
  141. package/dist/cjs/common-utils/utils/validation/validate-hf.js +0 -10
  142. package/dist/cjs/common-utils/utils/validation/validate-hf.spec.js +0 -26
  143. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-quota-status.js +0 -14
  144. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.js +0 -29
  145. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.js +0 -37
  146. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.spec.js +0 -98
  147. package/dist/cjs/common-utils/utils/validation/validate-open-account.js +0 -18
  148. package/dist/cjs/common-utils/utils/validation/validate-open-account.spec.js +0 -56
  149. package/dist/cjs/common-utils/utils/validation/validate-quota.js +0 -23
  150. package/dist/cjs/common-utils/utils/validation/validate-quota.spec.js +0 -88
  151. package/dist/cjs/common-utils/utils/validation/validate-token-to-obtain.js +0 -18
  152. package/dist/cjs/common-utils/utils/validation/validate-token-to-obtain.spec.js +0 -36
  153. package/dist/cjs/common-utils/utils/validation/validation-types.js +0 -1
  154. package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.js +0 -264
  155. package/dist/esm/common-utils/utils/validation/index.js +0 -12
  156. package/dist/esm/common-utils/utils/validation/is-zero-balance.js +0 -6
  157. package/dist/esm/common-utils/utils/validation/validate-balance.js +0 -21
  158. package/dist/esm/common-utils/utils/validation/validate-balance.spec.js +0 -54
  159. package/dist/esm/common-utils/utils/validation/validate-balances.js +0 -16
  160. package/dist/esm/common-utils/utils/validation/validate-balances.spec.js +0 -45
  161. package/dist/esm/common-utils/utils/validation/validate-credit-manager.js +0 -7
  162. package/dist/esm/common-utils/utils/validation/validate-credit-manager.spec.js +0 -36
  163. package/dist/esm/common-utils/utils/validation/validate-hf.js +0 -8
  164. package/dist/esm/common-utils/utils/validation/validate-hf.spec.js +0 -26
  165. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-quota-status.js +0 -13
  166. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.js +0 -29
  167. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.js +0 -36
  168. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.spec.js +0 -98
  169. package/dist/esm/common-utils/utils/validation/validate-open-account.js +0 -17
  170. package/dist/esm/common-utils/utils/validation/validate-open-account.spec.js +0 -56
  171. package/dist/esm/common-utils/utils/validation/validate-quota.js +0 -22
  172. package/dist/esm/common-utils/utils/validation/validate-quota.spec.js +0 -88
  173. package/dist/esm/common-utils/utils/validation/validate-token-to-obtain.js +0 -17
  174. package/dist/esm/common-utils/utils/validation/validate-token-to-obtain.spec.js +0 -36
  175. package/dist/esm/common-utils/utils/validation/validation-types.js +0 -1
  176. package/dist/types/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.d.ts +0 -1
  177. package/dist/types/common-utils/utils/validation/index.d.ts +0 -12
  178. package/dist/types/common-utils/utils/validation/is-zero-balance.d.ts +0 -4
  179. package/dist/types/common-utils/utils/validation/validate-balance.d.ts +0 -25
  180. package/dist/types/common-utils/utils/validation/validate-balance.spec.d.ts +0 -1
  181. package/dist/types/common-utils/utils/validation/validate-balances.d.ts +0 -13
  182. package/dist/types/common-utils/utils/validation/validate-balances.spec.d.ts +0 -1
  183. package/dist/types/common-utils/utils/validation/validate-credit-manager.d.ts +0 -13
  184. package/dist/types/common-utils/utils/validation/validate-credit-manager.spec.d.ts +0 -1
  185. package/dist/types/common-utils/utils/validation/validate-hf.d.ts +0 -12
  186. package/dist/types/common-utils/utils/validation/validate-hf.spec.d.ts +0 -1
  187. package/dist/types/common-utils/utils/validation/validate-open-account-pool-quota-status.d.ts +0 -10
  188. package/dist/types/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.d.ts +0 -1
  189. package/dist/types/common-utils/utils/validation/validate-open-account-pool-status.d.ts +0 -26
  190. package/dist/types/common-utils/utils/validation/validate-open-account-pool-status.spec.d.ts +0 -1
  191. package/dist/types/common-utils/utils/validation/validate-open-account.d.ts +0 -25
  192. package/dist/types/common-utils/utils/validation/validate-open-account.spec.d.ts +0 -1
  193. package/dist/types/common-utils/utils/validation/validate-quota.d.ts +0 -24
  194. package/dist/types/common-utils/utils/validation/validate-quota.spec.d.ts +0 -1
  195. package/dist/types/common-utils/utils/validation/validate-token-to-obtain.d.ts +0 -17
  196. package/dist/types/common-utils/utils/validation/validate-token-to-obtain.spec.d.ts +0 -1
  197. 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";
@@ -49,6 +49,10 @@ var CreditAccountOperationsService = class extends SDKConstruct {
49
49
  * withdraw form should offer. Taking everything out is the same intent with
50
50
  * `MAX_UINT256` for an amount, and needs none of this arithmetic.
51
51
  *
52
+ * Takes no target health factor, unlike {@link maxWithdrawCollateral}: a
53
+ * proportional withdrawal leaves the factor where it found it, and the
54
+ * facade's `minDebt` is what bounds it.
55
+ *
52
56
  * @param props - Account slice and the SDK holding its market
53
57
  * @returns Amount in underlying units; `0n` when nothing can leave
54
58
  */
@@ -84,8 +88,9 @@ var CreditAccountOperationsService = class extends SDKConstruct {
84
88
  * yet, and adjusting measures against the net value the caller already
85
89
  * holds. Nothing is fetched, so a form can ask on every keystroke.
86
90
  *
87
- * @param props - The manager, the SDK holding its market, and what stands
88
- * behind the position
91
+ * @param props - The manager, the SDK holding its market, what stands
92
+ * behind the position, and optionally the health factor the ceiling should
93
+ * leave
89
94
  * @returns The band, or nothing when the market has none to offer
90
95
  */
91
96
  leverageBand(props) {
@@ -93,19 +98,23 @@ var CreditAccountOperationsService = class extends SDKConstruct {
93
98
  }
94
99
  /**
95
100
  * Largest `WITHDRAW_ASSET` amount of one token the account can take out
96
- * while its health factor stays at {@link MIN_HF_LIMITED} plus a basis
97
- * point — the ceiling a withdraw-collateral form should offer. Thresholds,
98
- * prices and quota activity come from the account's market, valued the way
99
- * the facade values a call that pays out; zero debt frees the whole balance.
101
+ * while its health factor stays at `targetHF` the ceiling a
102
+ * withdraw-collateral form should offer. Thresholds, prices and quota
103
+ * activity come from the account's market, valued the way the facade values
104
+ * a call that pays out; zero debt frees the whole balance.
105
+ *
106
+ * The default is {@link MIN_HF_LIMITED}, the bar a form holds an
107
+ * account to.
100
108
  *
101
- * @param props - Account slice, the SDK holding its market, and the
102
- * collateral to withdraw
109
+ * @param props - Account slice, the SDK holding its market, the collateral
110
+ * to withdraw, and optionally the health factor to leave behind
103
111
  * @returns Amount in the token's units; `0n` when nothing can leave
104
112
  */
105
113
  maxWithdrawCollateral(props) {
114
+ const { targetHF = MIN_HF_LIMITED, ...rest } = props;
106
115
  return maxWithdrawCollateral({
107
- ...props,
108
- targetHF: MIN_HF_LIMITED + 2n
116
+ ...rest,
117
+ targetHF: targetHF + 2n
109
118
  });
110
119
  }
111
120
  /**
@@ -305,4 +314,4 @@ function isUnroutable(e) {
305
314
  return false;
306
315
  }
307
316
  //#endregion
308
- export { CreditAccountOperationsService, IntentPreviewError, fetchCreditAccountSlice, refuse, toCreditAccountSlice };
317
+ export { CreditAccountOperationsService, borrowable, fetchCreditAccountSlice, toCreditAccountSlice };
@@ -30,13 +30,13 @@ import "./utils/index.js";
30
30
  * calcLeverageBand({ sdk, creditManager, collateral }) // { min: 1.1, max: 9 }
31
31
  * ```
32
32
  **/
33
- function calcLeverageBand({ sdk, creditManager, collateral }) {
33
+ function calcLeverageBand({ sdk, creditManager, collateral, targetHF }) {
34
34
  const found = resolve(sdk, creditManager);
35
35
  if (!found) return;
36
36
  const { suite, market } = found;
37
37
  const target = suite.strategyTargetCollateral;
38
38
  if (!target) return;
39
- const ceiling = suite.creditManager.maxLeverage(target);
39
+ const ceiling = suite.creditManager.maxLeverage(target, targetHF);
40
40
  const underlying = market.pool.underlying;
41
41
  const convert = convertAmount(sdk, creditManager);
42
42
  const netValue = collateral.reduce((acc, a) => acc + convert(a.token, underlying, a.balance), 0n);
@@ -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,