@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
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_onchain_constants_math = require("../../constants/math.js");
3
- require("../../constants/index.js");
4
- const require_onchain_accounts_intents_refusal = require("./refusal.js");
2
+ const require_onchain_validation_checks = require("../../validation/checks.js");
3
+ const require_onchain_validation_refusal = require("../../validation/refusal.js");
4
+ const require_onchain_validation_token = require("../../validation/token.js");
5
5
  const require_onchain_accounts_intents_utils_common = require("./utils/common.js");
6
6
  const require_onchain_accounts_intents_utils_pick_token = require("./utils/pick-token.js");
7
7
  //#region src/onchain/accounts/intents/guards.ts
@@ -25,11 +25,15 @@ const require_onchain_accounts_intents_utils_pick_token = require("./utils/pick-
25
25
  */
26
26
  function assertMarketOperable(suite) {
27
27
  const creditManager = suite.creditManager.address;
28
- if (suite.isPaused) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("marketPaused", { creditManager }, `${creditManager} is paused`);
29
- if (suite.isExpired) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("marketExpired", {
28
+ require_onchain_validation_refusal.raise(require_onchain_validation_checks.checkCreditManagerPaused({
29
+ isPaused: suite.isPaused,
30
+ creditManager
31
+ }), `${creditManager} is paused`);
32
+ require_onchain_validation_refusal.raise(require_onchain_validation_checks.checkMarketExpired({
33
+ isExpired: suite.isExpired,
30
34
  creditManager,
31
35
  expirationDate: suite.creditFacade.expirationDate
32
- }, `${creditManager} expired at ${suite.creditFacade.expirationDate}`);
36
+ }), `${creditManager} expired at ${suite.creditFacade.expirationDate}`);
33
37
  }
34
38
  /**
35
39
  * What the pool will hand this manager in one transaction: the tightest of its
@@ -40,30 +44,35 @@ function assertMarketOperable(suite) {
40
44
  function borrowable(suite) {
41
45
  const { pool } = suite.market.pool;
42
46
  const { maxDebtPerBlockMultiplier, maxDebt } = suite.creditFacade;
43
- if (maxDebtPerBlockMultiplier === 0) return 0n;
47
+ if (maxDebtPerBlockMultiplier === 0) return {
48
+ limit: 0n,
49
+ binding: "facadePerBlockCap"
50
+ };
44
51
  const available = pool.creditManagerDebtParams.get(suite.creditManager.address)?.available;
45
52
  return [
46
- pool.availableLiquidity,
47
- maxDebt * BigInt(maxDebtPerBlockMultiplier),
48
- ...available === void 0 ? [] : [available]
49
- ].reduce((a, b) => a < b ? a : b);
53
+ {
54
+ limit: pool.availableLiquidity,
55
+ binding: "poolAvailableLiquidity"
56
+ },
57
+ {
58
+ limit: maxDebt * BigInt(maxDebtPerBlockMultiplier),
59
+ binding: "facadePerBlockCap"
60
+ },
61
+ ...available === void 0 ? [] : [{
62
+ limit: available,
63
+ binding: "managerDebtAvailable"
64
+ }]
65
+ ].reduce((a, b) => b.limit < a.limit ? b : a);
50
66
  }
51
67
  /** The pool has to be able to lend what the plan means to draw. */
52
- function assertCanBorrow(suite, amount) {
53
- const limit = borrowable(suite);
54
- if (amount > limit) {
55
- const token = suite.market.pool.underlying;
56
- throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientPoolLiquidity", {
57
- requested: {
58
- token,
59
- balance: amount
60
- },
61
- available: {
62
- token,
63
- balance: limit
64
- }
65
- }, `borrow: ${amount} exceeds what the pool can lend now (${limit})`);
66
- }
68
+ function assertCanBorrow(sdk, suite, amount) {
69
+ const { limit, binding } = borrowable(suite);
70
+ require_onchain_validation_refusal.raise(require_onchain_validation_checks.checkBorrowLimit({
71
+ requested: amount,
72
+ available: limit,
73
+ binding,
74
+ underlying: require_onchain_validation_token.toToken(sdk, suite.market.pool.underlying)
75
+ }), `borrow: ${amount} exceeds what the pool can lend now (${limit})`);
67
76
  }
68
77
  /**
69
78
  * What the account is allowed to end up holding more of than it started with.
@@ -83,16 +92,17 @@ function assertGrowthAllowed(args) {
83
92
  const underlying = market.pool.underlying;
84
93
  for (const { token, balance } of after) {
85
94
  if (balance <= (before.find((a) => require_onchain_accounts_intents_utils_common.eq(a.token, token))?.balance ?? 0n)) continue;
86
- if (forbidden.some((f) => require_onchain_accounts_intents_utils_common.eq(f, token))) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("forbiddenToken", { token }, `${token} is forbidden in this market and the plan buys more of it`);
95
+ require_onchain_validation_refusal.raise(require_onchain_validation_checks.checkForbiddenToken({
96
+ token: require_onchain_validation_token.toToken(sdk, token),
97
+ isForbidden: forbidden.some((f) => require_onchain_accounts_intents_utils_common.eq(f, token))
98
+ }), `${token} is forbidden in this market and the plan buys more of it`);
87
99
  if (require_onchain_accounts_intents_utils_common.eq(token, underlying) || require_onchain_accounts_intents_utils_pick_token.isPhantomToken(sdk, token)) continue;
88
- if (!market.pool.pqk.hasActiveQuota(token)) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("quotaLimitReached", {
89
- token,
100
+ if (!market.pool.pqk.hasActiveQuota(token)) require_onchain_validation_refusal.raise(require_onchain_validation_checks.checkQuotaLimit({
101
+ token: require_onchain_validation_token.toToken(sdk, token),
90
102
  requested: void 0,
91
- available: {
92
- token: underlying,
93
- balance: 0n
94
- }
95
- }, `${token} takes no quota in this market, so it counts as no collateral`);
103
+ available: 0n,
104
+ underlying: require_onchain_validation_token.toToken(sdk, underlying)
105
+ }), `${token} takes no quota in this market, so it counts as no collateral`);
96
106
  }
97
107
  }
98
108
  /**
@@ -107,7 +117,7 @@ function assertGrowthAllowed(args) {
107
117
  * - here, `1.0` — what the facade enforces, so what a plan must clear to land;
108
118
  * - `maxWithdrawCollateral` sizes at `MIN_HF_LIMITED + 2` — a *sizing* helper
109
119
  * leaving headroom, which is not the same as a validity check;
110
- * - `validateHF` refuses at or below `MIN_HF_LIMITED` — a form's own caution.
120
+ * - a form refuses at or below `MIN_HF_LIMITED` (`MIN_HEALTH_FACTOR_FORM`).
111
121
  *
112
122
  * Raising this one to `MIN_HF_LIMITED` was tried and reverted: it made
113
123
  * `maxWithdraw` hand back a ceiling this guard then refused, and it blocked
@@ -125,35 +135,30 @@ function assertGrowthAllowed(args) {
125
135
  * still be refused on-chain after passing here.
126
136
  */
127
137
  function assertCollateralised(healthFactorBps, safePrices) {
128
- const required = Number(require_onchain_constants_math.PERCENTAGE_FACTOR);
129
- if (healthFactorBps < required) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientCollateral", {
138
+ const required = require_onchain_validation_checks.MIN_HEALTH_FACTOR_FACADE;
139
+ require_onchain_validation_refusal.raise(require_onchain_validation_checks.checkCollateralised({
130
140
  healthFactor: healthFactorBps,
131
141
  required,
132
142
  safePrices
133
- }, `the account would end at a health factor of ${healthFactorBps}, below ${required}`);
143
+ }), `the account would end at a health factor of ${healthFactorBps}, below ${required}`);
134
144
  }
135
145
  /**
136
146
  * A quota can only be raised as far as the market still has room for: past the
137
147
  * token's limit the keeper takes nothing more, whoever is asking.
138
148
  */
139
- function assertQuotaHeadroom(market, increases) {
149
+ function assertQuotaHeadroom(sdk, market, increases) {
140
150
  const underlying = market.pool.underlying;
141
151
  for (const { token, balance } of increases) {
142
152
  if (balance <= 0n) continue;
143
153
  const quota = market.pool.pqk.quotas.get(token);
144
154
  if (!quota) continue;
145
155
  const left = quota.limit - quota.totalQuoted;
146
- if (balance > left) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("quotaLimitReached", {
147
- token,
148
- requested: {
149
- token: underlying,
150
- balance
151
- },
152
- available: {
153
- token: underlying,
154
- balance: left
155
- }
156
- }, `${token} has ${left} of quota left, the plan needs ${balance}`);
156
+ require_onchain_validation_refusal.raise(require_onchain_validation_checks.checkQuotaLimit({
157
+ token: require_onchain_validation_token.toToken(sdk, token),
158
+ requested: balance,
159
+ available: left,
160
+ underlying: require_onchain_validation_token.toToken(sdk, underlying)
161
+ }), `${token} has ${left} of quota left, the plan needs ${balance}`);
157
162
  }
158
163
  }
159
164
  //#endregion
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_base_SDKConstruct = require("../../base/SDKConstruct.js");
3
- const require_common_utils_utils_validation_validate_hf = require("../../../common-utils/utils/validation/validate-hf.js");
4
- const require_onchain_accounts_intents_refusal = require("./refusal.js");
3
+ const require_onchain_validation_checks = require("../../validation/checks.js");
4
+ const require_onchain_validation_refusal = require("../../validation/refusal.js");
5
5
  const require_onchain_accounts_intents_guards = require("./guards.js");
6
6
  const require_onchain_accounts_intents_utils_credit_account_slice = require("./utils/credit-account-slice.js");
7
7
  const require_onchain_accounts_intents_leverage_band = require("./leverage-band.js");
@@ -50,6 +50,10 @@ var CreditAccountOperationsService = class extends require_onchain_base_SDKConst
50
50
  * withdraw form should offer. Taking everything out is the same intent with
51
51
  * `MAX_UINT256` for an amount, and needs none of this arithmetic.
52
52
  *
53
+ * Takes no target health factor, unlike {@link maxWithdrawCollateral}: a
54
+ * proportional withdrawal leaves the factor where it found it, and the
55
+ * facade's `minDebt` is what bounds it.
56
+ *
53
57
  * @param props - Account slice and the SDK holding its market
54
58
  * @returns Amount in underlying units; `0n` when nothing can leave
55
59
  */
@@ -85,8 +89,9 @@ var CreditAccountOperationsService = class extends require_onchain_base_SDKConst
85
89
  * yet, and adjusting measures against the net value the caller already
86
90
  * holds. Nothing is fetched, so a form can ask on every keystroke.
87
91
  *
88
- * @param props - The manager, the SDK holding its market, and what stands
89
- * behind the position
92
+ * @param props - The manager, the SDK holding its market, what stands
93
+ * behind the position, and optionally the health factor the ceiling should
94
+ * leave
90
95
  * @returns The band, or nothing when the market has none to offer
91
96
  */
92
97
  leverageBand(props) {
@@ -94,19 +99,23 @@ var CreditAccountOperationsService = class extends require_onchain_base_SDKConst
94
99
  }
95
100
  /**
96
101
  * Largest `WITHDRAW_ASSET` amount of one token the account can take out
97
- * while its health factor stays at {@link MIN_HF_LIMITED} plus a basis
98
- * point — the ceiling a withdraw-collateral form should offer. Thresholds,
99
- * prices and quota activity come from the account's market, valued the way
100
- * the facade values a call that pays out; zero debt frees the whole balance.
102
+ * while its health factor stays at `targetHF` the ceiling a
103
+ * withdraw-collateral form should offer. Thresholds, prices and quota
104
+ * activity come from the account's market, valued the way the facade values
105
+ * a call that pays out; zero debt frees the whole balance.
106
+ *
107
+ * The default is {@link MIN_HF_LIMITED}, the bar a form holds an
108
+ * account to.
101
109
  *
102
- * @param props - Account slice, the SDK holding its market, and the
103
- * collateral to withdraw
110
+ * @param props - Account slice, the SDK holding its market, the collateral
111
+ * to withdraw, and optionally the health factor to leave behind
104
112
  * @returns Amount in the token's units; `0n` when nothing can leave
105
113
  */
106
114
  maxWithdrawCollateral(props) {
115
+ const { targetHF = require_onchain_validation_checks.MIN_HF_LIMITED, ...rest } = props;
107
116
  return require_onchain_accounts_intents_maxWithdrawCollateral.maxWithdrawCollateral({
108
- ...props,
109
- targetHF: require_common_utils_utils_validation_validate_hf.MIN_HF_LIMITED + 2n
117
+ ...rest,
118
+ targetHF: targetHF + 2n
110
119
  });
111
120
  }
112
121
  /**
@@ -289,8 +298,8 @@ function plain(result) {
289
298
  }
290
299
  /** Unviable requests are values; anything else is a genuine failure. */
291
300
  function asFailure(e) {
292
- if (e instanceof require_onchain_accounts_intents_refusal.IntentPreviewError) return require_onchain_accounts_intents_refusal.refuse(e.reason, e.detail);
293
- if (isUnroutable(e)) return require_onchain_accounts_intents_refusal.refuse("unsupportedTokenPair", void 0);
301
+ if (e instanceof require_onchain_validation_refusal.IntentPreviewError) return require_onchain_validation_refusal.refuse(e.reason, e.detail);
302
+ if (isUnroutable(e)) return require_onchain_validation_refusal.refuse("unsupportedTokenPair", void 0);
294
303
  throw e;
295
304
  }
296
305
  /**
@@ -307,7 +316,6 @@ function isUnroutable(e) {
307
316
  }
308
317
  //#endregion
309
318
  exports.CreditAccountOperationsService = CreditAccountOperationsService;
310
- exports.IntentPreviewError = require_onchain_accounts_intents_refusal.IntentPreviewError;
319
+ exports.borrowable = require_onchain_accounts_intents_guards.borrowable;
311
320
  exports.fetchCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.fetchCreditAccountSlice;
312
- exports.refuse = require_onchain_accounts_intents_refusal.refuse;
313
321
  exports.toCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.toCreditAccountSlice;
@@ -31,13 +31,13 @@ require("./utils/index.js");
31
31
  * calcLeverageBand({ sdk, creditManager, collateral }) // { min: 1.1, max: 9 }
32
32
  * ```
33
33
  **/
34
- function calcLeverageBand({ sdk, creditManager, collateral }) {
34
+ function calcLeverageBand({ sdk, creditManager, collateral, targetHF }) {
35
35
  const found = resolve(sdk, creditManager);
36
36
  if (!found) return;
37
37
  const { suite, market } = found;
38
38
  const target = suite.strategyTargetCollateral;
39
39
  if (!target) return;
40
- const ceiling = suite.creditManager.maxLeverage(target);
40
+ const ceiling = suite.creditManager.maxLeverage(target, targetHF);
41
41
  const underlying = market.pool.underlying;
42
42
  const convert = require_onchain_accounts_intents_utils_convert_amount.convertAmount(sdk, creditManager);
43
43
  const netValue = collateral.reduce((acc, a) => acc + convert(a.token, underlying, a.balance), 0n);
@@ -1,7 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_utils_bigint_math = require("../../utils/bigint-math.js");
3
3
  const require_onchain_constants_math = require("../../constants/math.js");
4
- const require_onchain_accounts_intents_refusal = require("./refusal.js");
4
+ const require_onchain_validation_checks = require("../../validation/checks.js");
5
+ const require_onchain_validation_refusal = require("../../validation/refusal.js");
6
+ const require_onchain_validation_token = require("../../validation/token.js");
5
7
  //#region src/onchain/accounts/intents/math.ts
6
8
  /** Debt that realises `leverage` on `collateral`: `D = C · (L − 1)`. */
7
9
  function debtForLeverage(collateral, leverage) {
@@ -15,7 +17,7 @@ function debtForLeverage(collateral, leverage) {
15
17
  * it, so no rounding is introduced on the way.
16
18
  */
17
19
  function proportionalDebt(position, collateralDelta) {
18
- if (position.collateral <= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "cannot preserve leverage on an account with no collateral");
20
+ if (position.collateral <= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "cannot preserve leverage on an account with no collateral");
19
21
  return position.debt * collateralDelta / position.collateral;
20
22
  }
21
23
  /**
@@ -38,32 +40,23 @@ function maxProportionalWithdrawal(position, band) {
38
40
  }
39
41
  /** Total leverage cannot drop below 1x — that would be negative debt. */
40
42
  function assertLeverageAtLeastOne(leverage) {
41
- if (leverage < 100n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("leverageOutOfRange", {
42
- requested: leverage,
43
+ require_onchain_validation_refusal.raise(require_onchain_validation_checks.checkLeverageAtLeastOne({
44
+ leverage,
43
45
  min: require_onchain_constants_math.LEVERAGE_DECIMALS
44
- }, `target leverage ${leverage} is below 1x`);
46
+ }), `target leverage ${leverage} is below 1x`);
45
47
  }
46
48
  /**
47
49
  * Rejects a debt the facade would revert on: zero is always fine (no loan at
48
50
  * all), anything else has to sit inside `[minDebt, maxDebt]`.
49
51
  */
50
- function assertDebtInBand(debt, band, underlying) {
51
- const detail = {
52
- requested: {
53
- token: underlying,
54
- balance: debt
55
- },
56
- minDebt: {
57
- token: underlying,
58
- balance: band.minDebt
59
- },
60
- maxDebt: {
61
- token: underlying,
62
- balance: band.maxDebt
63
- }
64
- };
65
- if (debt > band.maxDebt) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("debtOutOfRange", detail, `debt ${debt} exceeds maxDebt ${band.maxDebt}`);
66
- if (debt > 0n && debt < band.minDebt) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("debtOutOfRange", detail, `debt ${debt} is below minDebt ${band.minDebt}`);
52
+ function assertDebtInBand(sdk, debt, band, underlying) {
53
+ require_onchain_validation_refusal.raise(require_onchain_validation_checks.checkDebtInBand({
54
+ debt,
55
+ minDebt: band.minDebt,
56
+ maxDebt: band.maxDebt,
57
+ underlying: require_onchain_validation_token.toToken(sdk, underlying),
58
+ allowZero: true
59
+ }), debt > band.maxDebt ? `debt ${debt} exceeds maxDebt ${band.maxDebt}` : `debt ${debt} is below minDebt ${band.minDebt}`);
67
60
  }
68
61
  //#endregion
69
62
  exports.assertDebtInBand = assertDebtInBand;
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_onchain_accounts_intents_refusal = require("./refusal.js");
2
+ const require_onchain_validation_refusal = require("../../validation/refusal.js");
3
3
  const require_onchain_accounts_intents_utils_convert_amount = require("./utils/convert-amount.js");
4
4
  const require_onchain_accounts_intents_guards = require("./guards.js");
5
5
  const require_onchain_accounts_intents_utils_price_impact = require("./utils/price-impact.js");
@@ -30,7 +30,7 @@ async function previewOpenStrategy(props) {
30
30
  const underlying = market.pool.underlying.toLowerCase();
31
31
  const convert = require_onchain_accounts_intents_utils_convert_amount.convertAmount(sdk, creditManager);
32
32
  const margin = collateral.reduce((acc, a) => acc + convert(a.token, underlying, a.balance), 0n);
33
- if (margin <= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "openStrategy: collateral is worth nothing in underlying");
33
+ if (margin <= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "openStrategy: collateral is worth nothing in underlying");
34
34
  const debt = require_onchain_accounts_intents_math.debtForLeverage(margin, leverage);
35
35
  const account = {
36
36
  creditAccount: NO_ACCOUNT,
@@ -42,8 +42,8 @@ async function previewOpenStrategy(props) {
42
42
  accountDebt: 0n,
43
43
  tokens: []
44
44
  };
45
- require_onchain_accounts_intents_math.assertDebtInBand(debt, suite.creditFacade, underlying);
46
- require_onchain_accounts_intents_guards.assertCanBorrow(suite, debt);
45
+ require_onchain_accounts_intents_math.assertDebtInBand(sdk, debt, suite.creditFacade, underlying);
46
+ require_onchain_accounts_intents_guards.assertCanBorrow(sdk, suite, debt);
47
47
  const paths = require_onchain_accounts_intents_utils_router_path.createRouterPaths({
48
48
  sdk,
49
49
  creditAccount: account,
@@ -78,7 +78,7 @@ async function previewOpenStrategy(props) {
78
78
  before: [],
79
79
  after: averageAssets
80
80
  });
81
- require_onchain_accounts_intents_guards.assertQuotaHeadroom(market, averageQuota);
81
+ require_onchain_accounts_intents_guards.assertQuotaHeadroom(sdk, market, averageQuota);
82
82
  const snapshot = {
83
83
  creditManager,
84
84
  assets: averageAssets,
@@ -1,7 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_constants_math = require("../../constants/math.js");
3
3
  require("../../constants/index.js");
4
- const require_onchain_accounts_intents_refusal = require("./refusal.js");
4
+ const require_onchain_validation_refusal = require("../../validation/refusal.js");
5
+ const require_onchain_validation_token = require("../../validation/token.js");
5
6
  const require_onchain_accounts_intents_utils_common = require("./utils/common.js");
6
7
  const require_onchain_accounts_intents_math = require("./math.js");
7
8
  //#region src/onchain/accounts/intents/plan.ts
@@ -24,15 +25,9 @@ function planAdjustLeverage(intent, view) {
24
25
  const T = intent.token ?? positionToken(view, "adjustLeverage");
25
26
  if (delta > 0n) return [borrow(delta), convert(U, T, delta)];
26
27
  const shortfall = -delta - view.balanceOf(U);
27
- if (shortfall > 0n && require_onchain_accounts_intents_utils_common.eq(T, U)) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", {
28
- required: {
29
- token: U,
30
- balance: -delta
31
- },
32
- held: {
33
- token: U,
34
- balance: view.balanceOf(U)
35
- }
28
+ if (shortfall > 0n && require_onchain_accounts_intents_utils_common.eq(T, U)) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", {
29
+ required: require_onchain_validation_token.toTokenAmount(view.sdk, U, -delta),
30
+ held: require_onchain_validation_token.toTokenAmount(view.sdk, U, view.balanceOf(U))
36
31
  }, `adjustLeverage: needs ${-delta} underlying, account holds ${view.balanceOf(U)}`);
37
32
  return [...shortfall > 0n ? [convert(T, U, view.price(U, T, shortfall))] : [], repay(-delta)];
38
33
  }
@@ -40,11 +35,11 @@ function planAdjustLeverage(intent, view) {
40
35
  function planDeposit(intent, view) {
41
36
  assertPositive(intent.amount, "deposit");
42
37
  const U = view.underlying;
43
- if (!require_onchain_accounts_intents_utils_common.eq(intent.token, U) && !(view.rwaAsset && require_onchain_accounts_intents_utils_common.eq(intent.token, view.rwaAsset))) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("unsupportedCollateralToken", { token: intent.token }, `deposit: only ${U}${view.rwaAsset ? ` or ${view.rwaAsset}` : ""} can be deposited, got ${intent.token}`);
38
+ if (!require_onchain_accounts_intents_utils_common.eq(intent.token, U) && !(view.rwaAsset && require_onchain_accounts_intents_utils_common.eq(intent.token, view.rwaAsset))) throw new require_onchain_validation_refusal.IntentPreviewError("unsupportedCollateralToken", { token: require_onchain_validation_token.toToken(view.sdk, intent.token) }, `deposit: only ${U}${view.rwaAsset ? ` or ${view.rwaAsset}` : ""} can be deposited, got ${intent.token}`);
44
39
  const aU = view.price(intent.token, U, intent.amount);
45
40
  const debtDelta = intent.targetLeverage === void 0 ? require_onchain_accounts_intents_math.proportionalDebt(view, aU) : require_onchain_accounts_intents_math.debtForLeverage(view.collateral + aU, intent.targetLeverage) - view.debt;
46
- if (debtDelta < 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("leverageOutOfRange", void 0, `deposit: target leverage ${intent.targetLeverage} would require repaying debt`);
47
- require_onchain_accounts_intents_math.assertDebtInBand(view.debt + debtDelta, view.band, U);
41
+ if (debtDelta < 0n) throw new require_onchain_validation_refusal.IntentPreviewError("leverageOutOfRange", void 0, `deposit: target leverage ${intent.targetLeverage} would require repaying debt`);
42
+ require_onchain_accounts_intents_math.assertDebtInBand(view.sdk, view.debt + debtDelta, view.band, U);
48
43
  const T = intent.positionToken ?? positionToken(view, "deposit");
49
44
  const depositStays = require_onchain_accounts_intents_utils_common.eq(intent.token, T);
50
45
  return [
@@ -71,24 +66,15 @@ function planRepay(intent, view) {
71
66
  assertPositive(intent.amount, "repay");
72
67
  const U = view.underlying;
73
68
  const fundsInU = require_onchain_accounts_intents_utils_common.eq(intent.token, U);
74
- if (!fundsInU && !(view.rwaAsset && require_onchain_accounts_intents_utils_common.eq(intent.token, view.rwaAsset))) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("unsupportedCollateralToken", { token: intent.token }, `repay: only ${U}${view.rwaAsset ? ` or ${view.rwaAsset}` : ""} can be repaid with, got ${intent.token}`);
75
- if (view.debt <= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("debtOutOfRange", {
76
- requested: {
77
- token: U,
78
- balance: view.debt
79
- },
80
- minDebt: {
81
- token: U,
82
- balance: view.band.minDebt
83
- },
84
- maxDebt: {
85
- token: U,
86
- balance: view.band.maxDebt
87
- }
69
+ if (!fundsInU && !(view.rwaAsset && require_onchain_accounts_intents_utils_common.eq(intent.token, view.rwaAsset))) throw new require_onchain_validation_refusal.IntentPreviewError("unsupportedCollateralToken", { token: require_onchain_validation_token.toToken(view.sdk, intent.token) }, `repay: only ${U}${view.rwaAsset ? ` or ${view.rwaAsset}` : ""} can be repaid with, got ${intent.token}`);
70
+ if (view.debt <= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("debtOutOfRange", {
71
+ requested: require_onchain_validation_token.toTokenAmount(view.sdk, U, view.debt),
72
+ minDebt: require_onchain_validation_token.toTokenAmount(view.sdk, U, view.band.minDebt),
73
+ maxDebt: require_onchain_validation_token.toTokenAmount(view.sdk, U, view.band.maxDebt)
88
74
  }, "repay: the account owes nothing");
89
75
  const funding = everything(intent.amount) ? view.price(U, intent.token, withMargin(view.debt)) : intent.amount;
90
76
  const repaid = min(view.price(intent.token, U, funding), view.debt);
91
- require_onchain_accounts_intents_math.assertDebtInBand(view.debt - repaid, view.band, U);
77
+ require_onchain_accounts_intents_math.assertDebtInBand(view.sdk, view.debt - repaid, view.band, view.underlying);
92
78
  return [
93
79
  add(intent.token, funding, intent.value),
94
80
  ...fundsInU ? [] : [convert(intent.token, U, funding)],
@@ -144,7 +130,7 @@ function planWithdrawDelayed(intent, view) {
144
130
  const { U, T, S, WU, dD, all } = withdrawShape(intent, view);
145
131
  if (all) {
146
132
  const held = view.balanceOf(S);
147
- if (held <= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `withdraw: account holds no ${S} to redeem`);
133
+ if (held <= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `withdraw: account holds no ${S} to redeem`);
148
134
  return [{
149
135
  kind: "request",
150
136
  token: S,
@@ -156,7 +142,7 @@ function planWithdrawDelayed(intent, view) {
156
142
  }
157
143
  }];
158
144
  }
159
- if (!require_onchain_accounts_intents_utils_common.eq(T, U) && !(view.rwaAsset && require_onchain_accounts_intents_utils_common.eq(T, view.rwaAsset))) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("noDelayedRoute", { token: T }, `withdraw: a delayed route cannot pay out in ${T}`);
145
+ if (!require_onchain_accounts_intents_utils_common.eq(T, U) && !(view.rwaAsset && require_onchain_accounts_intents_utils_common.eq(T, view.rwaAsset))) throw new require_onchain_validation_refusal.IntentPreviewError("noDelayedRoute", { token: require_onchain_validation_token.toToken(view.sdk, T) }, `withdraw: a delayed route cannot pay out in ${T}`);
160
146
  const payoutIsSource = require_onchain_accounts_intents_utils_common.eq(T, S);
161
147
  return [{
162
148
  kind: "request",
@@ -182,9 +168,9 @@ function planWithdrawDelayed(intent, view) {
182
168
  */
183
169
  function planAdjustLeverageDelayed(intent, view) {
184
170
  const { U, delta } = leverageShape(intent, view);
185
- if (delta >= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("noDelayedRoute", void 0, "adjustLeverage: only deleveraging can settle with a delay");
171
+ if (delta >= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("noDelayedRoute", void 0, "adjustLeverage: only deleveraging can settle with a delay");
186
172
  const shortfall = -delta - view.balanceOf(U);
187
- if (shortfall <= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("noDelayedRoute", void 0, "adjustLeverage: idle underlying covers the repayment, nothing to redeem");
173
+ if (shortfall <= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("noDelayedRoute", void 0, "adjustLeverage: idle underlying covers the repayment, nothing to redeem");
188
174
  const T = intent.token ?? positionToken(view, "adjustLeverage");
189
175
  return [{
190
176
  kind: "request",
@@ -212,7 +198,7 @@ function planFinishWithdraw(intent, claimable, claimed, view) {
212
198
  const U = view.underlying;
213
199
  const T = intent.withdrawToken;
214
200
  const W = intent.withdrawAmount;
215
- if (!require_onchain_accounts_intents_utils_common.eq(T, U) && !(view.rwaAsset && require_onchain_accounts_intents_utils_common.eq(T, view.rwaAsset))) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("noDelayedRoute", { token: T }, `finishWithdraw: cannot pay out in ${T}`);
201
+ if (!require_onchain_accounts_intents_utils_common.eq(T, U) && !(view.rwaAsset && require_onchain_accounts_intents_utils_common.eq(T, view.rwaAsset))) throw new require_onchain_validation_refusal.IntentPreviewError("noDelayedRoute", { token: require_onchain_validation_token.toToken(view.sdk, T) }, `finishWithdraw: cannot pay out in ${T}`);
216
202
  if (intent.debtRepaid === 0n) return [
217
203
  claim(claimable),
218
204
  convert(claimed.token, T, claimed.amount),
@@ -304,7 +290,7 @@ function withdrawShape(intent, view) {
304
290
  };
305
291
  }
306
292
  const WU = view.price(T, U, intent.amount);
307
- if (WU <= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `withdraw: cannot price ${intent.amount} of ${T}`);
293
+ if (WU <= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `withdraw: cannot price ${intent.amount} of ${T}`);
308
294
  if (WU >= view.collateral) {
309
295
  assertHasValue(view);
310
296
  return {
@@ -317,7 +303,7 @@ function withdrawShape(intent, view) {
317
303
  };
318
304
  }
319
305
  const dD = require_onchain_accounts_intents_math.proportionalDebt(view, WU);
320
- require_onchain_accounts_intents_math.assertDebtInBand(view.debt - dD, view.band, U);
306
+ require_onchain_accounts_intents_math.assertDebtInBand(view.sdk, view.debt - dD, view.band, view.underlying);
321
307
  return {
322
308
  U,
323
309
  T,
@@ -334,9 +320,9 @@ function withdrawShape(intent, view) {
334
320
  */
335
321
  function leverageShape(intent, view) {
336
322
  require_onchain_accounts_intents_math.assertLeverageAtLeastOne(intent.targetLeverage);
337
- if (view.collateral <= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "adjustLeverage: account has no collateral to lever");
323
+ if (view.collateral <= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "adjustLeverage: account has no collateral to lever");
338
324
  const target = require_onchain_accounts_intents_math.debtForLeverage(view.collateral, intent.targetLeverage);
339
- require_onchain_accounts_intents_math.assertDebtInBand(target, view.band, view.underlying);
325
+ require_onchain_accounts_intents_math.assertDebtInBand(view.sdk, target, view.band, view.underlying);
340
326
  return {
341
327
  U: view.underlying,
342
328
  delta: target - view.debt
@@ -402,20 +388,20 @@ function payout(view, token, amount, to) {
402
388
  }
403
389
  function positionToken(view, flow) {
404
390
  const pick = view.fattest([view.underlying]);
405
- if (!pick) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `${flow}: no position token on the account`);
391
+ if (!pick) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `${flow}: no position token on the account`);
406
392
  return pick;
407
393
  }
408
394
  function sourceToken(view) {
409
395
  const pick = view.fattest();
410
- if (!pick) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "withdraw: account has no spendable balance");
396
+ if (!pick) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "withdraw: account has no spendable balance");
411
397
  return pick;
412
398
  }
413
399
  /** An account whose debt has eaten its collateral has nothing to hand over. */
414
400
  function assertHasValue(view) {
415
- if (view.collateral <= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `withdraw: nothing to withdraw, net value is ${view.collateral}`);
401
+ if (view.collateral <= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `withdraw: nothing to withdraw, net value is ${view.collateral}`);
416
402
  }
417
403
  function assertPositive(amount, flow) {
418
- if (amount <= 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `${flow}: amount must be positive`);
404
+ if (amount <= 0n) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, `${flow}: amount must be positive`);
419
405
  }
420
406
  //#endregion
421
407
  exports.RAISED = RAISED;
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_market_math = require("../../market/math.js");
3
- const require_onchain_accounts_intents_refusal = require("./refusal.js");
3
+ const require_onchain_validation_refusal = require("../../validation/refusal.js");
4
+ const require_onchain_validation_token = require("../../validation/token.js");
4
5
  const require_onchain_accounts_intents_utils_common = require("./utils/common.js");
5
6
  const require_onchain_accounts_intents_utils_convert_amount = require("./utils/convert-amount.js");
6
7
  const require_onchain_accounts_intents_utils_pick_token = require("./utils/pick-token.js");
@@ -63,15 +64,9 @@ async function realize(steps, props) {
63
64
  const amountOf = (a) => typeof a === "bigint" ? a : min(raised, a.max ?? raised);
64
65
  const assertHolds = (token, amount, what) => {
65
66
  const held = ledger.balanceOf(token);
66
- if (amount <= 0n || held < amount) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", {
67
- required: {
68
- token,
69
- balance: amount
70
- },
71
- held: {
72
- token,
73
- balance: held
74
- }
67
+ if (amount <= 0n || held < amount) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", {
68
+ required: require_onchain_validation_token.toTokenAmount(sdk, token, amount),
69
+ held: require_onchain_validation_token.toTokenAmount(sdk, token, held)
75
70
  }, `${what}: needs ${amount} of ${token}, account holds ${held}`);
76
71
  };
77
72
  for (const step of steps) switch (step.kind) {
@@ -85,7 +80,7 @@ async function realize(steps, props) {
85
80
  }));
86
81
  break;
87
82
  case "borrow":
88
- require_onchain_accounts_intents_guards.assertCanBorrow(suite, step.amount);
83
+ require_onchain_accounts_intents_guards.assertCanBorrow(sdk, suite, step.amount);
89
84
  push(require_onchain_accounts_intents_operations.buildIncreaseDebtOperation({
90
85
  amount: step.amount,
91
86
  creditAccount,
@@ -157,7 +152,7 @@ async function realize(steps, props) {
157
152
  case "closeAll": {
158
153
  const balances = ledger.snapshot().assets.filter((a) => !require_onchain_accounts_intents_utils_common.eq(a.token, underlying) && a.balance > DUST);
159
154
  const pending = balances.find((a) => require_onchain_accounts_intents_utils_pick_token.isRedemptionPhantomToken(sdk, a.token));
160
- if (pending) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("withdrawalInProgress", { inFlight: pending }, `closeAll: ${pending.token} is a pending withdrawal, claim it first`);
155
+ if (pending) throw new require_onchain_validation_refusal.IntentPreviewError("withdrawalInProgress", { inFlight: require_onchain_validation_token.toTokenAmount(sdk, pending.token, pending.balance) }, `closeAll: ${pending.token} is a pending withdrawal, claim it first`);
161
156
  if (balances.length > 0) {
162
157
  const leg = await paths.closeAll({ balances });
163
158
  if (leg.probe) probes.push(leg.probe);
@@ -186,10 +181,7 @@ async function realize(steps, props) {
186
181
  }
187
182
  case "request": {
188
183
  const asset = await delayedConfig(sdk, creditAccount, step.token);
189
- if (ledger.balanceOf(asset.withdrawalPhantomToken) > 0n) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("withdrawalInProgress", { inFlight: {
190
- token: asset.withdrawalPhantomToken,
191
- balance: ledger.balanceOf(asset.withdrawalPhantomToken)
192
- } }, `request: ${asset.withdrawalPhantomToken} already holds a pending withdrawal`);
184
+ if (ledger.balanceOf(asset.withdrawalPhantomToken) > 0n) throw new require_onchain_validation_refusal.IntentPreviewError("withdrawalInProgress", { inFlight: require_onchain_validation_token.toTokenAmount(sdk, asset.withdrawalPhantomToken, ledger.balanceOf(asset.withdrawalPhantomToken)) }, `request: ${asset.withdrawalPhantomToken} already holds a pending withdrawal`);
193
185
  assertHolds(step.token, step.amount + step.reserve, "request");
194
186
  const preview = await sdk.accounts.previewDelayedWithdrawal({
195
187
  creditAccount: creditAccount.creditAccount,
@@ -266,7 +258,7 @@ async function realize(steps, props) {
266
258
  convert: price
267
259
  });
268
260
  if (!cleared && quotas.quotaIncrease.length + quotas.quotaDecrease.length > 0) {
269
- require_onchain_accounts_intents_guards.assertQuotaHeadroom(market, quotas.quotaIncrease);
261
+ require_onchain_accounts_intents_guards.assertQuotaHeadroom(sdk, market, quotas.quotaIncrease);
270
262
  push(require_onchain_accounts_intents_operations.buildQuotaUpdateOperation({
271
263
  update: quotas,
272
264
  creditAccount,
@@ -284,6 +276,7 @@ async function realize(steps, props) {
284
276
  const projectedPool = { availableLiquidityChange: creditAccount.accountDebt - debt };
285
277
  const metrics = {
286
278
  healthFactor: sdk.positions.healthFactor(snapshot),
279
+ safeHealthFactor: paysOut ? sdk.positions.healthFactor(snapshot, { safePrices: true }) : void 0,
287
280
  borrowRate: sdk.positions.borrowRate(snapshot, projectedPool),
288
281
  timeToLiquidation: sdk.positions.timeToLiquidation(snapshot, projectedPool),
289
282
  liquidationPrice: sdk.positions.liquidationPrice(snapshot)
@@ -321,11 +314,11 @@ async function realize(steps, props) {
321
314
  */
322
315
  async function delayedConfig(sdk, creditAccount, token) {
323
316
  const compressor = sdk.withdrawalCompressor;
324
- if (!compressor) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("noDelayedRoute", { token }, "request: chain has no withdrawal compressor");
317
+ if (!compressor) throw new require_onchain_validation_refusal.IntentPreviewError("noDelayedRoute", { token: require_onchain_validation_token.toToken(sdk, token) }, "request: chain has no withdrawal compressor");
325
318
  const assets = await compressor.findWithdrawableAssets(creditAccount.creditManager, token);
326
- if (assets.length === 0) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("noDelayedRoute", { token }, `request: ${token} has no delayed withdrawal config`);
327
- if (assets.length > 1) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("multipleDelayedWithdrawals", {
328
- token,
319
+ if (assets.length === 0) throw new require_onchain_validation_refusal.IntentPreviewError("noDelayedRoute", { token: require_onchain_validation_token.toToken(sdk, token) }, `request: ${token} has no delayed withdrawal config`);
320
+ if (assets.length > 1) throw new require_onchain_validation_refusal.IntentPreviewError("multipleDelayedWithdrawals", {
321
+ token: require_onchain_validation_token.toToken(sdk, token),
329
322
  venues: assets.length
330
323
  }, `request: ${token} has ${assets.length} delayed withdrawal configs`);
331
324
  return assets[0];