@gearbox-protocol/sdk 16.0.0-next.18 → 16.0.0-next.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/dist/cjs/common-utils/index.js +3 -21
  2. package/dist/cjs/common-utils/test-utils/index.js +4 -3
  3. package/dist/cjs/common-utils/utils/index.js +3 -22
  4. package/dist/cjs/common-utils/utils/strategies/index.js +3 -0
  5. package/dist/cjs/common-utils/utils/strategies/strategy-info/cm-availability-condition.js +5 -5
  6. package/dist/cjs/common-utils/utils/strategies/strategy-info/credit-manager-issues.js +135 -0
  7. package/dist/cjs/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +12 -23
  8. package/dist/cjs/common-utils/utils/strategies/strategy-info/index.js +3 -0
  9. package/dist/cjs/onchain/accounts/index.js +2 -3
  10. package/dist/cjs/onchain/accounts/intents/guards.js +55 -50
  11. package/dist/cjs/onchain/accounts/intents/index.js +7 -8
  12. package/dist/cjs/onchain/accounts/intents/math.js +15 -22
  13. package/dist/cjs/onchain/accounts/intents/open-strategy.js +5 -5
  14. package/dist/cjs/onchain/accounts/intents/plan.js +27 -41
  15. package/dist/cjs/onchain/accounts/intents/realize.js +14 -21
  16. package/dist/cjs/onchain/accounts/intents/tail.js +2 -2
  17. package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +1 -0
  18. package/dist/cjs/onchain/accounts/intents/view.js +1 -0
  19. package/dist/cjs/onchain/constants/index.js +1 -0
  20. package/dist/cjs/onchain/constants/math.js +11 -0
  21. package/dist/cjs/onchain/index.js +32 -3
  22. package/dist/cjs/onchain/validation/checks.js +250 -0
  23. package/dist/cjs/onchain/validation/index.js +29 -0
  24. package/dist/cjs/onchain/{accounts/intents → validation}/refusal.js +12 -1
  25. package/dist/cjs/onchain/validation/token.js +29 -0
  26. package/dist/cjs/preview/index.js +10 -0
  27. package/dist/cjs/preview/preview/buildDelayedPreview.js +1 -0
  28. package/dist/cjs/preview/preview/previewAdjustCreditAccount.js +1 -0
  29. package/dist/cjs/preview/preview/previewOpenCreditAccount.js +1 -0
  30. package/dist/cjs/preview/validate/checkOperation.js +173 -0
  31. package/dist/cjs/preview/validate/checkSimulation.js +52 -0
  32. package/dist/cjs/preview/validate/index.js +6 -0
  33. package/dist/cjs/sdk/index.js +4 -0
  34. package/dist/cjs/sdk/prepare/PrepareApi.js +17 -13
  35. package/dist/cjs/sdk/prepare/index.js +4 -0
  36. package/dist/cjs/sdk/prepare/types.js +4 -0
  37. package/dist/esm/common-utils/index.js +2 -11
  38. package/dist/esm/common-utils/test-utils/index.js +4 -3
  39. package/dist/esm/common-utils/utils/index.js +2 -12
  40. package/dist/esm/common-utils/utils/strategies/index.js +2 -1
  41. package/dist/esm/common-utils/utils/strategies/strategy-info/cm-availability-condition.js +5 -5
  42. package/dist/esm/common-utils/utils/strategies/strategy-info/credit-manager-issues.js +133 -0
  43. package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +12 -23
  44. package/dist/esm/common-utils/utils/strategies/strategy-info/index.js +2 -1
  45. package/dist/esm/dev/AccountOpener.js +1 -1
  46. package/dist/esm/dev/withdrawalUtils.js +1 -1
  47. package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +2 -2
  48. package/dist/esm/onchain/accounts/index.js +2 -2
  49. package/dist/esm/onchain/accounts/intents/guards.js +55 -50
  50. package/dist/esm/onchain/accounts/intents/index.js +5 -5
  51. package/dist/esm/onchain/accounts/intents/math.js +14 -21
  52. package/dist/esm/onchain/accounts/intents/open-strategy.js +4 -4
  53. package/dist/esm/onchain/accounts/intents/plan.js +15 -29
  54. package/dist/esm/onchain/accounts/intents/realize.js +12 -19
  55. package/dist/esm/onchain/accounts/intents/tail.js +1 -1
  56. package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +1 -0
  57. package/dist/esm/onchain/accounts/intents/view.js +1 -0
  58. package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +1 -1
  59. package/dist/esm/onchain/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  60. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  61. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  62. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  63. package/dist/esm/onchain/base/TokensMeta.js +3 -3
  64. package/dist/esm/onchain/chain/detectNetwork.js +1 -1
  65. package/dist/esm/onchain/constants/index.js +2 -2
  66. package/dist/esm/onchain/constants/math.js +11 -1
  67. package/dist/esm/onchain/core/createAddressProvider.js +1 -1
  68. package/dist/esm/onchain/index.js +7 -3
  69. package/dist/esm/onchain/market/adapters/contracts/AccountMigratorAdapterContract.js +1 -1
  70. package/dist/esm/onchain/market/adapters/contracts/ERC4626AdapterContract.js +1 -1
  71. package/dist/esm/onchain/market/credit/CreditFacadeV310BaseContract.js +1 -1
  72. package/dist/esm/onchain/market/pool/PoolV310Contract.js +1 -1
  73. package/dist/esm/onchain/market/zapper/IETHZapperContract.js +1 -1
  74. package/dist/esm/onchain/market/zapper/ZapperContract.js +1 -1
  75. package/dist/esm/onchain/pools/PoolService.js +1 -1
  76. package/dist/esm/onchain/utils/viem/simulateWithPriceUpdates.js +1 -1
  77. package/dist/esm/onchain/validation/checks.js +230 -0
  78. package/dist/esm/onchain/validation/index.js +4 -0
  79. package/dist/esm/onchain/{accounts/intents → validation}/refusal.js +12 -2
  80. package/dist/esm/onchain/validation/token.js +27 -0
  81. package/dist/esm/preview/index.js +5 -1
  82. package/dist/esm/preview/preview/buildDelayedPreview.js +1 -0
  83. package/dist/esm/preview/preview/previewAdjustCreditAccount.js +1 -0
  84. package/dist/esm/preview/preview/previewOpenCreditAccount.js +1 -0
  85. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  86. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  87. package/dist/esm/preview/validate/checkOperation.js +171 -0
  88. package/dist/esm/preview/validate/checkSimulation.js +51 -0
  89. package/dist/esm/preview/validate/index.js +3 -0
  90. package/dist/esm/sdk/index.js +2 -1
  91. package/dist/esm/sdk/prepare/PrepareApi.js +15 -11
  92. package/dist/esm/sdk/prepare/index.js +2 -1
  93. package/dist/esm/sdk/prepare/types.js +2 -1
  94. package/dist/types/common-utils/index.d.ts +2 -12
  95. package/dist/types/common-utils/utils/index.d.ts +2 -13
  96. package/dist/types/common-utils/utils/strategies/index.d.ts +2 -1
  97. package/dist/types/common-utils/utils/strategies/strategy-info/credit-manager-issues.d.ts +34 -0
  98. package/dist/types/common-utils/utils/strategies/strategy-info/index.d.ts +2 -1
  99. package/dist/types/model/previews.d.ts +22 -0
  100. package/dist/types/onchain/accounts/index.d.ts +2 -2
  101. package/dist/types/onchain/accounts/intents/guards.d.ts +8 -4
  102. package/dist/types/onchain/accounts/intents/index.d.ts +4 -3
  103. package/dist/types/onchain/accounts/intents/math.d.ts +2 -1
  104. package/dist/types/onchain/accounts/intents/plan.d.ts +3 -0
  105. package/dist/types/onchain/accounts/intents/types.d.ts +7 -1
  106. package/dist/types/onchain/constants/index.d.ts +2 -2
  107. package/dist/types/onchain/constants/math.d.ts +9 -1
  108. package/dist/types/onchain/index.d.ts +7 -3
  109. package/dist/types/onchain/validation/checks.d.ts +167 -0
  110. package/dist/types/onchain/validation/index.d.ts +4 -0
  111. package/dist/types/onchain/{accounts/intents → validation}/refusal.d.ts +100 -31
  112. package/dist/types/onchain/validation/token.d.ts +17 -0
  113. package/dist/types/preview/index.d.ts +5 -1
  114. package/dist/types/preview/validate/checkOperation.d.ts +46 -0
  115. package/dist/types/preview/validate/checkSimulation.d.ts +34 -0
  116. package/dist/types/preview/validate/index.d.ts +3 -0
  117. package/dist/types/sdk/index.d.ts +2 -2
  118. package/dist/types/sdk/prepare/index.d.ts +2 -2
  119. package/dist/types/sdk/prepare/types.d.ts +2 -2
  120. package/package.json +1 -1
  121. package/dist/cjs/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.js +0 -267
  122. package/dist/cjs/common-utils/utils/validation/index.js +0 -23
  123. package/dist/cjs/common-utils/utils/validation/is-zero-balance.js +0 -7
  124. package/dist/cjs/common-utils/utils/validation/validate-balance.js +0 -22
  125. package/dist/cjs/common-utils/utils/validation/validate-balance.spec.js +0 -54
  126. package/dist/cjs/common-utils/utils/validation/validate-balances.js +0 -17
  127. package/dist/cjs/common-utils/utils/validation/validate-balances.spec.js +0 -45
  128. package/dist/cjs/common-utils/utils/validation/validate-credit-manager.js +0 -8
  129. package/dist/cjs/common-utils/utils/validation/validate-credit-manager.spec.js +0 -36
  130. package/dist/cjs/common-utils/utils/validation/validate-hf.js +0 -10
  131. package/dist/cjs/common-utils/utils/validation/validate-hf.spec.js +0 -26
  132. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-quota-status.js +0 -14
  133. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.js +0 -29
  134. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.js +0 -37
  135. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.spec.js +0 -98
  136. package/dist/cjs/common-utils/utils/validation/validate-open-account.js +0 -18
  137. package/dist/cjs/common-utils/utils/validation/validate-open-account.spec.js +0 -56
  138. package/dist/cjs/common-utils/utils/validation/validate-quota.js +0 -23
  139. package/dist/cjs/common-utils/utils/validation/validate-quota.spec.js +0 -88
  140. package/dist/cjs/common-utils/utils/validation/validate-token-to-obtain.js +0 -18
  141. package/dist/cjs/common-utils/utils/validation/validate-token-to-obtain.spec.js +0 -36
  142. package/dist/cjs/common-utils/utils/validation/validation-types.js +0 -1
  143. package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.js +0 -264
  144. package/dist/esm/common-utils/utils/validation/index.js +0 -12
  145. package/dist/esm/common-utils/utils/validation/is-zero-balance.js +0 -6
  146. package/dist/esm/common-utils/utils/validation/validate-balance.js +0 -21
  147. package/dist/esm/common-utils/utils/validation/validate-balance.spec.js +0 -54
  148. package/dist/esm/common-utils/utils/validation/validate-balances.js +0 -16
  149. package/dist/esm/common-utils/utils/validation/validate-balances.spec.js +0 -45
  150. package/dist/esm/common-utils/utils/validation/validate-credit-manager.js +0 -7
  151. package/dist/esm/common-utils/utils/validation/validate-credit-manager.spec.js +0 -36
  152. package/dist/esm/common-utils/utils/validation/validate-hf.js +0 -8
  153. package/dist/esm/common-utils/utils/validation/validate-hf.spec.js +0 -26
  154. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-quota-status.js +0 -13
  155. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.js +0 -29
  156. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.js +0 -36
  157. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.spec.js +0 -98
  158. package/dist/esm/common-utils/utils/validation/validate-open-account.js +0 -17
  159. package/dist/esm/common-utils/utils/validation/validate-open-account.spec.js +0 -56
  160. package/dist/esm/common-utils/utils/validation/validate-quota.js +0 -22
  161. package/dist/esm/common-utils/utils/validation/validate-quota.spec.js +0 -88
  162. package/dist/esm/common-utils/utils/validation/validate-token-to-obtain.js +0 -17
  163. package/dist/esm/common-utils/utils/validation/validate-token-to-obtain.spec.js +0 -36
  164. package/dist/esm/common-utils/utils/validation/validation-types.js +0 -1
  165. package/dist/types/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.spec.d.ts +0 -1
  166. package/dist/types/common-utils/utils/validation/index.d.ts +0 -12
  167. package/dist/types/common-utils/utils/validation/is-zero-balance.d.ts +0 -4
  168. package/dist/types/common-utils/utils/validation/validate-balance.d.ts +0 -25
  169. package/dist/types/common-utils/utils/validation/validate-balance.spec.d.ts +0 -1
  170. package/dist/types/common-utils/utils/validation/validate-balances.d.ts +0 -13
  171. package/dist/types/common-utils/utils/validation/validate-balances.spec.d.ts +0 -1
  172. package/dist/types/common-utils/utils/validation/validate-credit-manager.d.ts +0 -13
  173. package/dist/types/common-utils/utils/validation/validate-credit-manager.spec.d.ts +0 -1
  174. package/dist/types/common-utils/utils/validation/validate-hf.d.ts +0 -12
  175. package/dist/types/common-utils/utils/validation/validate-hf.spec.d.ts +0 -1
  176. package/dist/types/common-utils/utils/validation/validate-open-account-pool-quota-status.d.ts +0 -10
  177. package/dist/types/common-utils/utils/validation/validate-open-account-pool-quota-status.spec.d.ts +0 -1
  178. package/dist/types/common-utils/utils/validation/validate-open-account-pool-status.d.ts +0 -26
  179. package/dist/types/common-utils/utils/validation/validate-open-account-pool-status.spec.d.ts +0 -1
  180. package/dist/types/common-utils/utils/validation/validate-open-account.d.ts +0 -25
  181. package/dist/types/common-utils/utils/validation/validate-open-account.spec.d.ts +0 -1
  182. package/dist/types/common-utils/utils/validation/validate-quota.d.ts +0 -24
  183. package/dist/types/common-utils/utils/validation/validate-quota.spec.d.ts +0 -1
  184. package/dist/types/common-utils/utils/validation/validate-token-to-obtain.d.ts +0 -17
  185. package/dist/types/common-utils/utils/validation/validate-token-to-obtain.spec.d.ts +0 -1
  186. package/dist/types/common-utils/utils/validation/validation-types.d.ts +0 -10
@@ -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");
@@ -104,7 +104,7 @@ var CreditAccountOperationsService = class extends require_onchain_base_SDKConst
104
104
  * activity come from the account's market, valued the way the facade values
105
105
  * a call that pays out; zero debt frees the whole balance.
106
106
  *
107
- * The default is {@link MIN_HF_LIMITED}, the bar `validateHF` holds an
107
+ * The default is {@link MIN_HF_LIMITED}, the bar a form holds an
108
108
  * account to.
109
109
  *
110
110
  * @param props - Account slice, the SDK holding its market, the collateral
@@ -112,7 +112,7 @@ var CreditAccountOperationsService = class extends require_onchain_base_SDKConst
112
112
  * @returns Amount in the token's units; `0n` when nothing can leave
113
113
  */
114
114
  maxWithdrawCollateral(props) {
115
- const { targetHF = require_common_utils_utils_validation_validate_hf.MIN_HF_LIMITED, ...rest } = props;
115
+ const { targetHF = require_onchain_validation_checks.MIN_HF_LIMITED, ...rest } = props;
116
116
  return require_onchain_accounts_intents_maxWithdrawCollateral.maxWithdrawCollateral({
117
117
  ...rest,
118
118
  targetHF: targetHF + 2n
@@ -298,8 +298,8 @@ function plain(result) {
298
298
  }
299
299
  /** Unviable requests are values; anything else is a genuine failure. */
300
300
  function asFailure(e) {
301
- if (e instanceof require_onchain_accounts_intents_refusal.IntentPreviewError) return require_onchain_accounts_intents_refusal.refuse(e.reason, e.detail);
302
- 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);
303
303
  throw e;
304
304
  }
305
305
  /**
@@ -316,7 +316,6 @@ function isUnroutable(e) {
316
316
  }
317
317
  //#endregion
318
318
  exports.CreditAccountOperationsService = CreditAccountOperationsService;
319
- exports.IntentPreviewError = require_onchain_accounts_intents_refusal.IntentPreviewError;
319
+ exports.borrowable = require_onchain_accounts_intents_guards.borrowable;
320
320
  exports.fetchCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.fetchCreditAccountSlice;
321
- exports.refuse = require_onchain_accounts_intents_refusal.refuse;
322
321
  exports.toCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.toCreditAccountSlice;
@@ -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];
@@ -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_router_path = require("./utils/router-path.js");
4
4
  const require_onchain_accounts_intents_plan = require("./plan.js");
5
5
  const require_onchain_accounts_intents_operations = require("./operations.js");
@@ -18,7 +18,7 @@ function planTail(args) {
18
18
  const { intent, claimable, view } = args;
19
19
  const claimed = () => {
20
20
  const output = require_onchain_accounts_intents_operations.instantOutput(claimable.outputs);
21
- if (!output) throw new require_onchain_accounts_intents_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "finishIntent: the claim credits nothing to spend");
21
+ if (!output) throw new require_onchain_validation_refusal.IntentPreviewError("insufficientSourceBalance", void 0, "finishIntent: the claim credits nothing to spend");
22
22
  return output;
23
23
  };
24
24
  switch (intent.type) {
@@ -297,6 +297,7 @@ function buildMockSdk(args) {
297
297
  decimals: decimalsOf(token),
298
298
  contractType: phantoms.has(token.toLowerCase()) ? "PHANTOM_TOKEN::SECURITIZE_RD" : void 0
299
299
  }),
300
+ getToken: tokenOf,
300
301
  mustGetToken: tokenOf,
301
302
  rwaUnderlyings: { get: (token) => {
302
303
  const asset = args.rwaAssets?.[token.toLowerCase()];
@@ -18,6 +18,7 @@ function accountView(creditAccount, sdk) {
18
18
  for (const t of creditAccount.tokens) totalValue += price(t.token, underlying, t.balance);
19
19
  return {
20
20
  underlying,
21
+ sdk,
21
22
  rwaAsset: sdk.tokensMeta.rwaUnderlyings.get(underlying)?.asset,
22
23
  debt: creditAccount.accountDebt,
23
24
  collateral: totalValue - creditAccount.accountDebt,
@@ -72,3 +72,4 @@ exports.botPermissionsToString = require_onchain_constants_bot_permissions.botPe
72
72
  exports.halfRAY = require_onchain_constants_math.halfRAY;
73
73
  exports.isV310 = require_onchain_constants_versions.isV310;
74
74
  exports.isVersionRange = require_onchain_constants_versions.isVersionRange;
75
+ exports.isZeroBalance = require_onchain_constants_math.isZeroBalance;
@@ -21,6 +21,16 @@ const SLIPPAGE_DECIMALS = 100n;
21
21
  * Token balances at or below this threshold are treated as dust and ignored.
22
22
  **/
23
23
  const DUST_THRESHOLD = 10n;
24
+ /**
25
+ * Whether a balance is nothing worth acting on.
26
+ *
27
+ * The threshold is a dust floor, not a zero test: rounding leaves amounts that
28
+ * are technically non-zero and worthless, and a form that offered to spend one
29
+ * would build a transaction nobody wants.
30
+ */
31
+ function isZeroBalance(balance) {
32
+ return (balance ?? 0n) <= DUST_THRESHOLD;
33
+ }
24
34
  //#endregion
25
35
  exports.DUST_THRESHOLD = DUST_THRESHOLD;
26
36
  exports.LEVERAGE_DECIMALS = LEVERAGE_DECIMALS;
@@ -40,3 +50,4 @@ exports.SLIPPAGE_DECIMALS = SLIPPAGE_DECIMALS;
40
50
  exports.WAD = WAD;
41
51
  exports.WAD_DECIMALS_POW = WAD_DECIMALS_POW;
42
52
  exports.halfRAY = halfRAY;
53
+ exports.isZeroBalance = isZeroBalance;