@gearbox-protocol/sdk 16.0.0-next.26 → 16.0.0-next.28

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 (71) hide show
  1. package/dist/cjs/model/index.js +1 -0
  2. package/dist/cjs/model/previews.js +23 -0
  3. package/dist/cjs/onchain/accounts/index.js +2 -0
  4. package/dist/cjs/onchain/accounts/intents/index.js +2 -0
  5. package/dist/cjs/onchain/accounts/intents/open-strategy.js +4 -18
  6. package/dist/cjs/onchain/accounts/intents/realize.js +77 -50
  7. package/dist/cjs/onchain/accounts/intents/testing/market.js +1 -0
  8. package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +13 -5
  9. package/dist/cjs/onchain/index.js +2 -0
  10. package/dist/cjs/onchain/positions/PositionsService.js +79 -0
  11. package/dist/cjs/preview/index.js +6 -6
  12. package/dist/cjs/preview/preview/{buildDelayedPreview.js → buildDelayedStrategyVerify.js} +6 -25
  13. package/dist/cjs/preview/preview/index.js +6 -6
  14. package/dist/cjs/preview/preview/{previewAdjustCreditAccount.js → previewAdjustStrategyVerify.js} +6 -24
  15. package/dist/cjs/preview/preview/{previewCloseOrRepayCreditAccount.js → previewExitOrRepayStrategyVerify.js} +3 -3
  16. package/dist/cjs/preview/preview/{previewPoolOperation.js → previewLpVerify.js} +3 -3
  17. package/dist/cjs/preview/preview/{previewOpenCreditAccount.js → previewOpenStrategyVerify.js} +6 -26
  18. package/dist/cjs/preview/preview/previewOperation.js +10 -10
  19. package/dist/cjs/preview/validate/checkOperation.js +13 -9
  20. package/dist/cjs/rewards/rewards/api.js +15 -7
  21. package/dist/cjs/sdk/prepare/PrepareApi.js +7 -0
  22. package/dist/cjs/sdk/prepare/withdrawable-collaterals.js +23 -0
  23. package/dist/esm/model/index.js +2 -2
  24. package/dist/esm/model/previews.js +23 -1
  25. package/dist/esm/onchain/accounts/index.js +2 -1
  26. package/dist/esm/onchain/accounts/intents/index.js +2 -1
  27. package/dist/esm/onchain/accounts/intents/open-strategy.js +4 -18
  28. package/dist/esm/onchain/accounts/intents/realize.js +77 -50
  29. package/dist/esm/onchain/accounts/intents/testing/market.js +1 -0
  30. package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +13 -5
  31. package/dist/esm/onchain/index.js +2 -1
  32. package/dist/esm/onchain/positions/PositionsService.js +79 -0
  33. package/dist/esm/preview/index.js +4 -4
  34. package/dist/esm/preview/preview/{buildDelayedPreview.js → buildDelayedStrategyVerify.js} +7 -26
  35. package/dist/esm/preview/preview/index.js +4 -4
  36. package/dist/esm/preview/preview/{previewAdjustCreditAccount.js → previewAdjustStrategyVerify.js} +7 -25
  37. package/dist/esm/preview/preview/{previewCloseOrRepayCreditAccount.js → previewExitOrRepayStrategyVerify.js} +3 -3
  38. package/dist/esm/preview/preview/{previewPoolOperation.js → previewLpVerify.js} +3 -3
  39. package/dist/esm/preview/preview/{previewOpenCreditAccount.js → previewOpenStrategyVerify.js} +7 -27
  40. package/dist/esm/preview/preview/previewOperation.js +10 -10
  41. package/dist/esm/preview/validate/checkOperation.js +13 -9
  42. package/dist/esm/rewards/rewards/api.js +16 -8
  43. package/dist/esm/sdk/prepare/PrepareApi.js +7 -0
  44. package/dist/esm/sdk/prepare/withdrawable-collaterals.js +22 -0
  45. package/dist/types/model/index.d.ts +2 -2
  46. package/dist/types/model/previews.d.ts +202 -76
  47. package/dist/types/onchain/accounts/index.d.ts +2 -1
  48. package/dist/types/onchain/accounts/intents/index.d.ts +2 -1
  49. package/dist/types/onchain/accounts/intents/open-strategy.d.ts +1 -7
  50. package/dist/types/onchain/accounts/intents/testing/market.d.ts +1 -0
  51. package/dist/types/onchain/accounts/intents/testing/sdk-mock.d.ts +7 -0
  52. package/dist/types/onchain/accounts/intents/utils/index.d.ts +1 -1
  53. package/dist/types/onchain/index.d.ts +2 -1
  54. package/dist/types/onchain/positions/PositionsService.d.ts +30 -0
  55. package/dist/types/preview/index.d.ts +5 -5
  56. package/dist/types/preview/preview/{buildDelayedPreview.d.ts → buildDelayedStrategyVerify.d.ts} +4 -4
  57. package/dist/types/preview/preview/index.d.ts +4 -4
  58. package/dist/types/preview/preview/{previewAdjustCreditAccount.d.ts → previewAdjustStrategyVerify.d.ts} +4 -4
  59. package/dist/types/preview/preview/{previewCloseOrRepayCreditAccount.d.ts → previewExitOrRepayStrategyVerify.d.ts} +4 -4
  60. package/dist/types/preview/preview/previewLpVerify.d.ts +11 -0
  61. package/dist/types/preview/preview/previewOpenStrategyVerify.d.ts +12 -0
  62. package/dist/types/preview/validate/checkOperation.d.ts +12 -4
  63. package/dist/types/preview/validate/index.d.ts +2 -2
  64. package/dist/types/rewards/rewards/api.d.ts +12 -6
  65. package/dist/types/rewards/rewards/merkl-api.d.ts +6 -0
  66. package/dist/types/sdk/prepare/PrepareApi.d.ts +5 -0
  67. package/dist/types/sdk/prepare/types.d.ts +18 -1
  68. package/dist/types/sdk/prepare/withdrawable-collaterals.d.ts +11 -0
  69. package/package.json +1 -1
  70. package/dist/types/preview/preview/previewOpenCreditAccount.d.ts +0 -12
  71. package/dist/types/preview/preview/previewPoolOperation.d.ts +0 -11
@@ -38,6 +38,7 @@ exports.STRATEGY_POSITION_CHART_METRICS = require_model_charts.STRATEGY_POSITION
38
38
  exports.STRATEGY_POSITION_COLLATERAL_ERROR = require_model_positions.STRATEGY_POSITION_COLLATERAL_ERROR;
39
39
  exports.amountSchema = require_model_primitives_schema.amountSchema;
40
40
  exports.apyBreakdownSchema = require_model_opportunities_schema.apyBreakdownSchema;
41
+ exports.asEstimated = require_model_previews.asEstimated;
41
42
  exports.assetTypeSchema = require_model_primitives_schema.assetTypeSchema;
42
43
  exports.backendPreferred = require_model_compare_schema.backendPreferred;
43
44
  exports.booleanParamSchema = require_model_filters_schema.booleanParamSchema;
@@ -33,6 +33,28 @@ const ERROR_UNSUPPORTED_OUT_OF_BRACKET_CALL = 1005;
33
33
  const ERROR_INVALID_TRANSACTION_VALUE = 1006;
34
34
  /** A token in the preview could not be priced by the oracle */
35
35
  const ERROR_UNPRICEABLE_TOKEN = 2001;
36
+ /**
37
+ * Renames a projection's routed fields, for a caller that built one from floor
38
+ * balances.
39
+ *
40
+ * Lives beside the type so the two cannot drift: a field added to
41
+ * {@link RoutedField} fails to compile until it is renamed here too.
42
+ **/
43
+ function asEstimated(p) {
44
+ const { totalValue, netValue, assets, healthFactor, safeHealthFactor, borrowRate, timeToLiquidation, liquidationPrice, leverage, ...settled } = p;
45
+ return {
46
+ ...settled,
47
+ estTotalValue: totalValue,
48
+ estNetValue: netValue,
49
+ estAssets: assets,
50
+ estHealthFactor: healthFactor,
51
+ estSafeHealthFactor: safeHealthFactor,
52
+ estBorrowRate: borrowRate,
53
+ estTimeToLiquidation: timeToLiquidation,
54
+ estLiquidationPrice: liquidationPrice,
55
+ estLeverage: leverage
56
+ };
57
+ }
36
58
  //#endregion
37
59
  exports.ERROR_ADAPTER_CALL_OUTSIDE_BRACKET = ERROR_ADAPTER_CALL_OUTSIDE_BRACKET;
38
60
  exports.ERROR_INVALID_TRANSACTION_VALUE = ERROR_INVALID_TRANSACTION_VALUE;
@@ -41,3 +63,4 @@ exports.ERROR_NON_ADAPTER_CALL_IN_BRACKET = ERROR_NON_ADAPTER_CALL_IN_BRACKET;
41
63
  exports.ERROR_UNPREVIEWABLE_ADAPTER_CALL = ERROR_UNPREVIEWABLE_ADAPTER_CALL;
42
64
  exports.ERROR_UNPRICEABLE_TOKEN = ERROR_UNPRICEABLE_TOKEN;
43
65
  exports.ERROR_UNSUPPORTED_OUT_OF_BRACKET_CALL = ERROR_UNSUPPORTED_OUT_OF_BRACKET_CALL;
66
+ exports.asEstimated = asEstimated;
@@ -6,6 +6,7 @@ const require_onchain_accounts_credit_account_compressor_CreditAccountCompressor
6
6
  const require_onchain_accounts_credit_account_compressor_CreditAccountCompressor = require("./credit-account-compressor/CreditAccountCompressor.js");
7
7
  require("./credit-account-compressor/index.js");
8
8
  const require_onchain_accounts_CreditAccountsServiceV310 = require("./CreditAccountsServiceV310.js");
9
+ const require_onchain_accounts_intents_utils_pick_token = require("./intents/utils/pick-token.js");
9
10
  const require_onchain_accounts_intents_guards = require("./intents/guards.js");
10
11
  const require_onchain_accounts_intents_utils_credit_account_slice = require("./intents/utils/credit-account-slice.js");
11
12
  const require_onchain_accounts_quota_utils = require("./quota-utils.js");
@@ -56,6 +57,7 @@ exports.encodeDelayedIntent = require_onchain_accounts_withdrawal_compressor_int
56
57
  exports.fetchCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.fetchCreditAccountSlice;
57
58
  exports.getWithdrawalCompressorAddress = require_onchain_accounts_withdrawal_compressor_addresses.getWithdrawalCompressorAddress;
58
59
  exports.iCreditAccountAbi = require_onchain_accounts_withdrawal_compressor_AbstractWithdrawalCompressorContract.iCreditAccountAbi;
60
+ exports.isPhantomToken = require_onchain_accounts_intents_utils_pick_token.isPhantomToken;
59
61
  exports.roundUpQuota = require_onchain_accounts_quota_utils.roundUpQuota;
60
62
  exports.toClaimableWithdrawal = require_onchain_accounts_withdrawal_compressor_AbstractWithdrawalCompressorContract.toClaimableWithdrawal;
61
63
  exports.toCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.toCreditAccountSlice;
@@ -2,6 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_base_SDKConstruct = require("../../base/SDKConstruct.js");
3
3
  const require_onchain_validation_checks = require("../../validation/checks.js");
4
4
  const require_onchain_validation_refusal = require("../../validation/refusal.js");
5
+ const require_onchain_accounts_intents_utils_pick_token = require("./utils/pick-token.js");
5
6
  const require_onchain_accounts_intents_guards = require("./guards.js");
6
7
  const require_onchain_accounts_intents_leverage_band = require("./leverage-band.js");
7
8
  const require_onchain_accounts_intents_math = require("./math.js");
@@ -318,4 +319,5 @@ function isUnroutable(e) {
318
319
  exports.CreditAccountOperationsService = CreditAccountOperationsService;
319
320
  exports.borrowable = require_onchain_accounts_intents_guards.borrowable;
320
321
  exports.fetchCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.fetchCreditAccountSlice;
322
+ exports.isPhantomToken = require_onchain_accounts_intents_utils_pick_token.isPhantomToken;
321
323
  exports.toCreditAccountSlice = require_onchain_accounts_intents_utils_credit_account_slice.toCreditAccountSlice;
@@ -1,5 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_onchain_market_math = require("../../market/math.js");
3
2
  const require_onchain_validation_refusal = require("../../validation/refusal.js");
4
3
  const require_onchain_accounts_intents_guards = require("./guards.js");
5
4
  const require_onchain_accounts_intents_math = require("./math.js");
@@ -86,34 +85,21 @@ async function previewOpenStrategy(props) {
86
85
  totalDebt: debt,
87
86
  totalValue: margin + debt
88
87
  };
89
- const projectedPool = { availableLiquidityChange: -debt };
90
- const metrics = {
91
- healthFactor: sdk.positions.healthFactor(snapshot),
92
- safeHealthFactor: sdk.positions.healthFactor(snapshot, { safePrices: true }),
93
- borrowRate: sdk.positions.borrowRate(snapshot, projectedPool),
94
- timeToLiquidation: sdk.positions.timeToLiquidation(snapshot, projectedPool),
95
- liquidationPrice: sdk.positions.liquidationPrice(snapshot)
96
- };
97
- require_onchain_accounts_intents_guards.assertCollateralised(metrics.healthFactor, false);
88
+ const { assets: _assets, quotas: _quotas, ...projection } = sdk.positions.projection(snapshot, { availableLiquidityChange: -debt });
89
+ require_onchain_accounts_intents_guards.assertCollateralised(projection.healthFactor, false);
98
90
  const priceImpact = await require_onchain_accounts_intents_utils_price_impact.collectPriceImpact(leg.probe ? [leg.probe] : [], {
99
91
  totalValue: margin + debt,
100
92
  netValue: margin,
101
93
  toUnderlying: (from, amount) => convert(from, underlying, amount)
102
94
  });
103
95
  return {
104
- creditManager,
105
- name: suite.name,
106
- totalDebt: market.toUnderlyingAmount(debt),
107
- netValue: market.toUnderlyingAmount(margin),
108
- totalValue: market.toUnderlyingAmount(margin + debt),
109
- leverage: require_onchain_market_math.calcPositionLeverage(margin + debt, debt),
96
+ ...projection,
110
97
  priceImpact,
111
98
  averageAssets: averageAssets.map(priced),
112
99
  minAssets: minAssets.map(priced),
113
100
  averageQuota,
114
101
  minQuota,
115
- calls: [...leg.calls],
116
- ...metrics
102
+ calls: [...leg.calls]
117
103
  };
118
104
  }
119
105
  /** Collateral plus the borrowed underlying, folded into one balance per token. */
@@ -1,5 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_onchain_market_math = require("../../market/math.js");
3
2
  const require_onchain_validation_refusal = require("../../validation/refusal.js");
4
3
  const require_onchain_validation_token = require("../../validation/token.js");
5
4
  const require_onchain_accounts_intents_utils_common = require("./utils/common.js");
@@ -33,16 +32,36 @@ async function realize(steps, props) {
33
32
  const market = sdk.marketRegister.findByCreditManager(creditAccount.creditManager);
34
33
  const price = (from, to, amount) => market.priceOracle.safeConvert(from, to, amount) ?? 0n;
35
34
  const suite = sdk.marketRegister.findCreditManager(creditAccount.creditManager);
36
- const ledger = new require_onchain_accounts_intents_utils_ledger.OperationLedger({
35
+ const start = {
37
36
  initialAssets: creditAccount.tokens,
38
37
  underlying,
39
38
  debt: creditAccount.totalDebt,
40
39
  convert: price
41
- });
40
+ };
41
+ /**
42
+ * The floor: every routed leg counted at the amount it guarantees. This is
43
+ * what the calls are built from — a repayment may only spend underlying the
44
+ * route promises to have raised — and what the guards are answered on, since
45
+ * a floor that does not clear the facade's bar is a transaction that can
46
+ * revert.
47
+ */
48
+ const ledger = new require_onchain_accounts_intents_utils_ledger.OperationLedger(start);
49
+ /**
50
+ * The same walk with every routed leg counted at the amount the pathfinder
51
+ * expects to return. Nothing is built from it: it is where the position
52
+ * actually lands, so it is what the reported state is read off.
53
+ */
54
+ const expected = new require_onchain_accounts_intents_utils_ledger.OperationLedger(start);
42
55
  const operations = [];
43
- const push = (op) => {
56
+ /**
57
+ * @param asExpected - The operation as the expected branch sees it, for the
58
+ * legs where the two differ. Defaults to the operation itself, which is the
59
+ * case for everything whose amount the calldata fixes.
60
+ */
61
+ const push = (op, asExpected = op) => {
44
62
  operations.push(op);
45
63
  ledger.apply(op);
64
+ expected.apply(asExpected);
46
65
  };
47
66
  /** One per routed leg, each already awaiting its quote; folded after the guards. */
48
67
  const probes = [];
@@ -138,13 +157,17 @@ async function realize(steps, props) {
138
157
  keep: held - amount
139
158
  });
140
159
  if (leg.probe) probes.push(leg.probe);
141
- push(require_onchain_accounts_intents_operations.buildSwapOperation({
160
+ const swap = require_onchain_accounts_intents_operations.buildSwapOperation({
142
161
  tokenIn: step.from,
143
162
  amountIn: amount,
144
163
  tokenOut: step.to,
145
164
  amountOut: leg.minAmount,
146
165
  calls: leg.calls
147
- }));
166
+ });
167
+ push(swap, {
168
+ ...swap,
169
+ amountOut: leg.amount
170
+ });
148
171
  raised = leg.minAmount;
149
172
  break;
150
173
  }
@@ -155,12 +178,22 @@ async function realize(steps, props) {
155
178
  if (balances.length > 0) {
156
179
  const leg = await paths.closeAll({ balances });
157
180
  if (leg.probe) probes.push(leg.probe);
158
- if (leg.calls.length > 0 || leg.minAmount > 0n) push(require_onchain_accounts_intents_operations.buildCloseSwapOperation({
159
- from: balances,
160
- tokenOut: underlying,
161
- amountOut: leg.minAmount,
162
- calls: leg.calls
163
- }));
181
+ if (leg.calls.length > 0 || leg.minAmount > 0n) {
182
+ const sale = require_onchain_accounts_intents_operations.buildCloseSwapOperation({
183
+ from: balances,
184
+ tokenOut: underlying,
185
+ amountOut: leg.minAmount,
186
+ calls: leg.calls
187
+ });
188
+ push(sale, {
189
+ ...sale,
190
+ from: balances.map((a) => ({
191
+ token: a.token,
192
+ balance: expected.balanceOf(a.token)
193
+ })),
194
+ amountOut: leg.amount
195
+ });
196
+ }
164
197
  }
165
198
  raised = ledger.balanceOf(underlying);
166
199
  break;
@@ -226,24 +259,32 @@ async function realize(steps, props) {
226
259
  creditAccount,
227
260
  sdk
228
261
  }));
229
- for (const { token, balance } of ledger.snapshot().assets) push(require_onchain_accounts_intents_operations.buildWithdrawCollateralOperation({
230
- token,
231
- amount: balance,
232
- to: step.to,
233
- all: true,
234
- creditAccount,
235
- sdk
236
- }));
262
+ for (const { token, balance } of ledger.snapshot().assets) {
263
+ const payout = require_onchain_accounts_intents_operations.buildWithdrawCollateralOperation({
264
+ token,
265
+ amount: balance,
266
+ to: step.to,
267
+ all: true,
268
+ creditAccount,
269
+ sdk
270
+ });
271
+ push(payout, {
272
+ ...payout,
273
+ amount: expected.balanceOf(token)
274
+ });
275
+ }
237
276
  break;
238
277
  }
239
278
  }
240
- const { assets, totalValue, debt } = ledger.snapshot();
279
+ const floor = ledger.snapshot();
280
+ const { assets, debt } = floor;
281
+ const projected = expected.snapshot();
241
282
  require_onchain_accounts_intents_guards.assertGrowthAllowed({
242
283
  sdk,
243
284
  suite,
244
285
  market,
245
286
  before: creditAccount.tokens,
246
- after: assets
287
+ after: projected.assets
247
288
  });
248
289
  const quotas = cleared ?? require_onchain_accounts_intents_utils_quotas_for_update.getQuotasForUpdate({
249
290
  assetsBefore: creditAccount.tokens,
@@ -265,42 +306,28 @@ async function realize(steps, props) {
265
306
  }));
266
307
  }
267
308
  const quotasAfter = require_onchain_accounts_intents_utils_quotas_for_update.quotasAfterUpdate(creditAccount.tokens, quotas.desiredQuota);
309
+ const quoted = Object.values(quotasAfter);
268
310
  const snapshot = {
269
311
  creditManager: creditAccount.creditManager,
270
- assets,
271
- quotas: Object.values(quotasAfter),
312
+ assets: projected.assets,
313
+ quotas: quoted,
272
314
  totalDebt: debt,
273
- totalValue
274
- };
275
- const projectedPool = { availableLiquidityChange: creditAccount.totalDebt - debt };
276
- const metrics = {
277
- healthFactor: sdk.positions.healthFactor(snapshot),
278
- safeHealthFactor: paysOut ? sdk.positions.healthFactor(snapshot, { safePrices: true }) : void 0,
279
- borrowRate: sdk.positions.borrowRate(snapshot, projectedPool),
280
- timeToLiquidation: sdk.positions.timeToLiquidation(snapshot, projectedPool),
281
- liquidationPrice: sdk.positions.liquidationPrice(snapshot)
315
+ totalValue: projected.totalValue
282
316
  };
283
- require_onchain_accounts_intents_guards.assertCollateralised(paysOut ? sdk.positions.healthFactor(snapshot, { safePrices: true }) : metrics.healthFactor, paysOut);
317
+ const projection = sdk.positions.projection(snapshot, { availableLiquidityChange: creditAccount.totalDebt - debt });
318
+ require_onchain_accounts_intents_guards.assertCollateralised(sdk.positions.healthFactor({
319
+ ...snapshot,
320
+ assets,
321
+ totalValue: floor.totalValue
322
+ }, { safePrices: paysOut }), paysOut);
284
323
  const priceImpact = await require_onchain_accounts_intents_utils_price_impact.collectPriceImpact(probes, {
285
- totalValue,
286
- netValue: totalValue - debt,
324
+ totalValue: projected.totalValue,
325
+ netValue: projected.totalValue - debt,
287
326
  toUnderlying: (from, amount) => price(from, underlying, amount)
288
327
  });
289
- const oracle = market.priceOracle;
290
328
  const state = {
291
- creditManager: creditAccount.creditManager,
292
- name: suite.name,
293
- totalValue: market.toUnderlyingAmount(totalValue),
294
- totalDebt: market.toUnderlyingAmount(debt),
295
- netValue: market.toUnderlyingAmount(totalValue - debt),
296
- leverage: require_onchain_market_math.calcPositionLeverage(totalValue, debt),
297
- assets: assets.map((a) => oracle.toTokenAmount(a.token, a.balance)),
298
- quotas: Object.values(quotasAfter).map((q) => ({
299
- token: sdk.tokensMeta.mustGetToken(q.token),
300
- ...oracle.toAmount(underlying, q.balance)
301
- })),
302
- priceImpact,
303
- ...metrics
329
+ ...projection,
330
+ priceImpact
304
331
  };
305
332
  return {
306
333
  operations,
@@ -96,6 +96,7 @@ function buildMarketSdk(extras) {
96
96
  creditFacade: CREDIT_FACADE,
97
97
  underlying: UND,
98
98
  routeQuote: extras?.routeQuote,
99
+ routeFloor: extras?.routeFloor,
99
100
  rwaAssets: extras?.rwaAssets,
100
101
  phantoms: extras?.phantoms,
101
102
  creditAccounts: extras?.creditAccounts,
@@ -155,6 +155,8 @@ function buildMockSdk(args) {
155
155
  };
156
156
  const market = {
157
157
  toUnderlyingAmount,
158
+ /** {@inheritDoc MarketSuite.underlying} */
159
+ underlying: args.underlying,
158
160
  priceOracle: {
159
161
  convert,
160
162
  safeConvert,
@@ -238,10 +240,12 @@ function buildMockSdk(args) {
238
240
  };
239
241
  /** Linear unless the case says otherwise — see `routeQuote`. */
240
242
  const quote = args.routeQuote ?? ((amount) => amount);
243
+ /** Slippage-free unless the case says otherwise — see `routeFloor`. */
244
+ const floor = args.routeFloor ?? ((amount) => amount);
241
245
  const router = {
242
246
  findOneTokenPath: vitest.vi.fn(async ({ amount, tokenIn, tokenOut }) => ({
243
247
  amount: quote(amount),
244
- minAmount: quote(amount),
248
+ minAmount: floor(quote(amount)),
245
249
  calls: routeCalls(tokenIn, tokenOut)
246
250
  })),
247
251
  findManyToOnePath: vitest.vi.fn(async ({ expectedBalances, leftoverBalances, target }) => {
@@ -249,7 +253,7 @@ function buildMockSdk(args) {
249
253
  const tokenIn = expectedBalances[0]?.token ?? target;
250
254
  return {
251
255
  amount: quote(spent),
252
- minAmount: quote(spent),
256
+ minAmount: floor(quote(spent)),
253
257
  calls: routeCalls(tokenIn, target)
254
258
  };
255
259
  }),
@@ -270,11 +274,15 @@ function buildMockSdk(args) {
270
274
  amount += convert(token, targetLc, spend);
271
275
  }
272
276
  balances[targetLc] = (balances[targetLc] ?? 0n) + amount;
277
+ const untouched = (balances[targetLc] ?? 0n) - amount;
273
278
  return {
274
279
  amount,
275
- minAmount: amount,
280
+ minAmount: floor(amount),
276
281
  balances,
277
- minBalances: { ...balances },
282
+ minBalances: {
283
+ ...balances,
284
+ [targetLc]: untouched + floor(amount)
285
+ },
278
286
  calls: [MOCK_ROUTER_CALL]
279
287
  };
280
288
  }),
@@ -284,7 +292,7 @@ function buildMockSdk(args) {
284
292
  const amount = sold.reduce((acc, a) => acc + convert(a.token, underlying, a.balance), 0n);
285
293
  return {
286
294
  amount,
287
- minAmount: amount,
295
+ minAmount: floor(amount),
288
296
  underlyingBalance: amount,
289
297
  calls: sold.length === 0 ? [] : [MOCK_CLOSE_CALL]
290
298
  };
@@ -197,6 +197,7 @@ const require_onchain_accounts_CreditAccountsServiceV310 = require("./accounts/C
197
197
  const require_onchain_validation_checks = require("./validation/checks.js");
198
198
  const require_onchain_validation_refusal = require("./validation/refusal.js");
199
199
  const require_onchain_validation_token = require("./validation/token.js");
200
+ const require_onchain_accounts_intents_utils_pick_token = require("./accounts/intents/utils/pick-token.js");
200
201
  const require_onchain_accounts_intents_guards = require("./accounts/intents/guards.js");
201
202
  const require_onchain_accounts_intents_utils_credit_account_slice = require("./accounts/intents/utils/credit-account-slice.js");
202
203
  const require_onchain_accounts_quota_utils = require("./accounts/quota-utils.js");
@@ -652,6 +653,7 @@ exports.iVelodromeV2RouterAdapterAbi = require_onchain_market_adapters_abi_adapt
652
653
  exports.isDust = require_onchain_utils_isDust.isDust;
653
654
  exports.isLPPriceFeed = require_onchain_market_pricefeeds_AbstractLPPriceFeed.isLPPriceFeed;
654
655
  exports.isMalformedPreviewError = require_onchain_validation_checks.isMalformedPreviewError;
656
+ exports.isPhantomToken = require_onchain_accounts_intents_utils_pick_token.isPhantomToken;
655
657
  exports.isPublicNetwork = require_onchain_chain_chains.isPublicNetwork;
656
658
  exports.isRWAFactory = require_onchain_market_rwa_types.isRWAFactory;
657
659
  exports.isRWAToken = require_onchain_chain_chains.isRWAToken;
@@ -164,6 +164,85 @@ var PositionsService = class extends require_onchain_base_SDKConstruct.SDKConstr
164
164
  });
165
165
  }
166
166
  /**
167
+ * Every derived number of an account state at once — the whole
168
+ * {@link AccountMetrics} half of a projection.
169
+ *
170
+ * This is what both halves of the SDK fill their answers from: `prepare`, for
171
+ * a state it walked an intent into, and `preview`, for one it replayed out of
172
+ * calldata. One snapshot in, one set of metrics out, so the two descriptions
173
+ * of the same operation cannot disagree because one of them grew its own
174
+ * formula.
175
+ *
176
+ * Identical to the four methods above field for field, and cheaper than
177
+ * calling them one by one: the market data is collected once, and the health
178
+ * factor and borrow rate the time to liquidation decays at are the very ones
179
+ * reported beside it.
180
+ **/
181
+ metrics(snapshot, options) {
182
+ const data = this.#marketData(snapshot);
183
+ const factor = (safePrices) => require_onchain_positions_calcHealthFactor.calcHealthFactor({
184
+ snapshot,
185
+ underlying: data.underlying,
186
+ decimals: data.decimals,
187
+ prices: data.prices,
188
+ reservePrices: data.reservePrices,
189
+ safePrices,
190
+ liquidationThresholds: data.liquidationThresholds,
191
+ activeQuotas: data.activeQuotas
192
+ });
193
+ const healthFactor = factor(false);
194
+ const borrowRate = require_onchain_positions_calcBorrowRate.calcBorrowRate({
195
+ snapshot,
196
+ baseInterestRate: this.#baseInterestRate(snapshot, data, options),
197
+ feeInterest: data.feeInterest,
198
+ quotaRates: data.quotaRates,
199
+ resolveToken: (address) => this.sdk.tokensMeta.mustGetToken(address)
200
+ });
201
+ return {
202
+ healthFactor,
203
+ safeHealthFactor: factor(true),
204
+ borrowRate,
205
+ timeToLiquidation: require_onchain_positions_calcTimeToLiquidationMs.calcTimeToLiquidationMs(healthFactor, BigInt(borrowRate.totalOnDebt)),
206
+ liquidationPrice: require_onchain_positions_calcLiquidationPrice.calcLiquidationPrice({
207
+ snapshot,
208
+ underlying: data.underlying,
209
+ decimals: data.decimals,
210
+ liquidationThresholds: data.liquidationThresholds
211
+ }),
212
+ leverage: require_onchain_market_math.calcPositionLeverage(snapshot.totalValue, snapshot.totalDebt)
213
+ };
214
+ }
215
+ /**
216
+ * A projected account state as both halves of the SDK report it: the holdings
217
+ * priced and named, and the metrics of {@link PositionsService.metrics}.
218
+ *
219
+ * The snapshot is taken at its word — what it lists is what comes back, so a
220
+ * caller that drops dust before the walk reports an account without it, and
221
+ * one that keeps wei reports them. That is the whole of the policy left to
222
+ * the caller; everything downstream of the balances is decided here.
223
+ *
224
+ * @param options - The operation's effect on the pool, for the rate the
225
+ * metrics are quoted at, see {@link ProjectedPoolOptions}.
226
+ **/
227
+ projection(snapshot, options) {
228
+ const { creditManager, totalValue, totalDebt } = snapshot;
229
+ const market = this.sdk.marketRegister.findByCreditManager(creditManager);
230
+ const { priceOracle } = market;
231
+ return {
232
+ creditManager,
233
+ name: this.sdk.marketRegister.findCreditManager(creditManager).name,
234
+ totalValue: market.toUnderlyingAmount(totalValue),
235
+ totalDebt: market.toUnderlyingAmount(totalDebt),
236
+ netValue: market.toUnderlyingAmount(totalValue - totalDebt),
237
+ assets: snapshot.assets.map((a) => priceOracle.toTokenAmount(a.token, a.balance)),
238
+ quotas: snapshot.quotas.map((q) => ({
239
+ token: this.sdk.tokensMeta.mustGetToken(q.token),
240
+ ...priceOracle.toAmount(market.underlying, q.balance)
241
+ })),
242
+ ...this.metrics(snapshot, options)
243
+ };
244
+ }
245
+ /**
167
246
  * Builds one strategy position from an account snapshot.
168
247
  *
169
248
  * @param withdrawals - Delayed withdrawals of the account, keyed by the
@@ -20,7 +20,7 @@ const require_preview_prerequisites_BalancePrerequisite = require("./prerequisit
20
20
  const require_preview_prerequisites_RWAOpenRequirementsPrerequisite = require("./prerequisites/RWAOpenRequirementsPrerequisite.js");
21
21
  const require_preview_prerequisites_checkPrerequisites = require("./prerequisites/checkPrerequisites.js");
22
22
  require("./prerequisites/index.js");
23
- const require_preview_preview_buildDelayedPreview = require("./preview/buildDelayedPreview.js");
23
+ const require_preview_preview_buildDelayedStrategyVerify = require("./preview/buildDelayedStrategyVerify.js");
24
24
  const require_preview_preview_CreditAccountState = require("./preview/CreditAccountState.js");
25
25
  const require_preview_preview_detectCloseOrRepay = require("./preview/detectCloseOrRepay.js");
26
26
  const require_preview_preview_detectDelayedClaim = require("./preview/detectDelayedClaim.js");
@@ -28,8 +28,8 @@ const require_preview_preview_detectDelayedOperation = require("./preview/detect
28
28
  const require_preview_preview_errors = require("./preview/errors.js");
29
29
  const require_preview_preview_replayInnerOperations = require("./preview/replayInnerOperations.js");
30
30
  const require_preview_preview_replayMulticall = require("./preview/replayMulticall.js");
31
- const require_preview_preview_previewAdjustCreditAccount = require("./preview/previewAdjustCreditAccount.js");
32
- const require_preview_preview_previewCloseOrRepayCreditAccount = require("./preview/previewCloseOrRepayCreditAccount.js");
31
+ const require_preview_preview_previewAdjustStrategyVerify = require("./preview/previewAdjustStrategyVerify.js");
32
+ const require_preview_preview_previewExitOrRepayStrategyVerify = require("./preview/previewExitOrRepayStrategyVerify.js");
33
33
  const require_preview_preview_previewOperation = require("./preview/previewOperation.js");
34
34
  require("./preview/index.js");
35
35
  require("./types.js");
@@ -51,7 +51,7 @@ exports.UnsupportedPoolFunctionError = require_preview_parse_errors.UnsupportedP
51
51
  exports.UnsupportedTargetError = require_preview_parse_errors.UnsupportedTargetError;
52
52
  exports.UnsupportedZapperFunctionError = require_onchain_market_zapper_errors.UnsupportedZapperFunctionError;
53
53
  exports.WithdrawCollateralAlignmentError = require_preview_trace_errors.WithdrawCollateralAlignmentError;
54
- exports.buildDelayedPreview = require_preview_preview_buildDelayedPreview.buildDelayedPreview;
54
+ exports.buildDelayedStrategyVerify = require_preview_preview_buildDelayedStrategyVerify.buildDelayedStrategyVerify;
55
55
  exports.checkOperation = require_preview_validate_checkOperation.checkOperation;
56
56
  exports.checkPrerequisites = require_preview_prerequisites_checkPrerequisites.checkPrerequisites;
57
57
  exports.checkSimulation = require_preview_validate_checkSimulation.checkSimulation;
@@ -72,8 +72,8 @@ exports.parseFacadeOperationCalldata = require_preview_parse_parseFacadeOperatio
72
72
  exports.parseOperationCalldata = require_preview_parse_parseOperationCalldata.parseOperationCalldata;
73
73
  exports.parsePoolOperationCalldata = require_preview_parse_parsePoolOperationCalldata.parsePoolOperationCalldata;
74
74
  exports.parseRWAFactoryOperationCalldata = require_preview_parse_parseRWAFactoryOperationCalldata.parseRWAFactoryOperationCalldata;
75
- exports.previewAdjustCreditAccount = require_preview_preview_previewAdjustCreditAccount.previewAdjustCreditAccount;
76
- exports.previewCloseOrRepayCreditAccount = require_preview_preview_previewCloseOrRepayCreditAccount.previewCloseOrRepayCreditAccount;
75
+ exports.previewAdjustStrategyVerify = require_preview_preview_previewAdjustStrategyVerify.previewAdjustStrategyVerify;
76
+ exports.previewExitOrRepayStrategyVerify = require_preview_preview_previewExitOrRepayStrategyVerify.previewExitOrRepayStrategyVerify;
77
77
  exports.previewOperation = require_preview_preview_previewOperation.previewOperation;
78
78
  exports.quotaCountIssue = require_preview_validate_checkOperation.quotaCountIssue;
79
79
  exports.raise = require_onchain_validation_refusal.raise;
@@ -2,12 +2,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_utils_AssetsMap = require("../../onchain/utils/AssetsMap.js");
3
3
  const require_onchain_utils_bigint_math = require("../../onchain/utils/bigint-math.js");
4
4
  const require_onchain_constants_math = require("../../onchain/constants/math.js");
5
- const require_onchain_market_math = require("../../onchain/market/math.js");
6
5
  const require_model_previews = require("../../model/previews.js");
7
6
  require("../../model/index.js");
8
7
  require("../../onchain/index.js");
9
8
  let viem = require("viem");
10
- //#region src/preview/preview/buildDelayedPreview.ts
9
+ //#region src/preview/preview/buildDelayedStrategyVerify.ts
11
10
  /**
12
11
  * Builds the best-effort preview of the account state after the detected
13
12
  * delayed withdrawal is claimed and its intent (if any) is resumed:
@@ -30,7 +29,7 @@ let viem = require("viem");
30
29
  * @param sdk - Market data source for the position metrics of the resulting
31
30
  * state; read synchronously, no network access.
32
31
  */
33
- function buildDelayedPreview(afterInstant, before, detected, convert, receivedToken, sdk) {
32
+ function buildDelayedStrategyVerify(afterInstant, before, detected, convert, receivedToken, sdk) {
34
33
  const { request, intent } = detected;
35
34
  const post = afterInstant.clone();
36
35
  const converter = makeSafeConverter(convert);
@@ -175,41 +174,23 @@ function buildClosePreview(post, converter, receivedToken, sdk) {
175
174
  };
176
175
  }
177
176
  function buildAdjustPreview(post, before, collateralWithdrawn, converter, sdk) {
178
- const totalValue = totalValueInUnderlying(post, converter.convert, require_onchain_constants_math.DUST_THRESHOLD);
179
- const assets = post.balances.toAssets(require_onchain_constants_math.DUST_THRESHOLD);
180
- const quotas = post.quotas.toAssets(0n);
181
- const snap = post.toSnapshot(totalValue);
177
+ const snap = post.toSnapshot(totalValueInUnderlying(post, converter.convert, require_onchain_constants_math.DUST_THRESHOLD));
182
178
  const market = sdk.marketRegister.findByCreditManager(post.creditManager);
183
179
  const oracle = market.priceOracle;
184
180
  return {
185
181
  operation: "AdjustCreditAccount",
186
- creditManager: post.creditManager,
187
- name: sdk.marketRegister.findCreditManager(post.creditManager).name,
182
+ ...require_model_previews.asEstimated(sdk.positions.projection(snap, { availableLiquidityChange: before.totalDebt - post.totalDebt })),
188
183
  creditAccount: post.creditAccount,
189
184
  collateralAdded: [],
190
185
  collateralWithdrawn: collateralWithdrawn.toAssets().map((a) => oracle.toTokenAmount(a.token, a.balance)),
191
- totalValue: market.toUnderlyingAmount(totalValue),
192
- totalDebt: market.toUnderlyingAmount(post.totalDebt),
193
- netValue: market.toUnderlyingAmount(totalValue - post.totalDebt),
194
186
  totalDebtChange: market.toUnderlyingAmount(post.totalDebt - before.totalDebt),
195
- quotas: quotas.map((q) => ({
196
- token: sdk.tokensMeta.mustGetToken(q.token),
197
- ...oracle.toAmount(market.underlying, q.balance)
198
- })),
199
187
  quotasChange: post.quotas.difference(before.quotas).toAssets().map((q) => ({
200
188
  token: sdk.tokensMeta.mustGetToken(q.token),
201
189
  ...oracle.toAmount(market.underlying, q.balance)
202
190
  })),
203
- assets: assets.map((a) => oracle.toTokenAmount(a.token, a.balance)),
204
191
  assetsChange: post.balances.difference(before.balances).toAssets(require_onchain_constants_math.DUST_THRESHOLD).map((a) => oracle.toTokenAmount(a.token, a.balance)),
205
- error: converter.error,
206
- healthFactor: sdk.positions.healthFactor(snap),
207
- safeHealthFactor: sdk.positions.healthFactor(snap, { safePrices: true }),
208
- borrowRate: sdk.positions.borrowRate(snap, { availableLiquidityChange: before.totalDebt - post.totalDebt }),
209
- timeToLiquidation: sdk.positions.timeToLiquidation(snap, { availableLiquidityChange: before.totalDebt - post.totalDebt }),
210
- liquidationPrice: sdk.positions.liquidationPrice(snap),
211
- leverage: require_onchain_market_math.calcPositionLeverage(totalValue, post.totalDebt)
192
+ error: converter.error
212
193
  };
213
194
  }
214
195
  //#endregion
215
- exports.buildDelayedPreview = buildDelayedPreview;
196
+ exports.buildDelayedStrategyVerify = buildDelayedStrategyVerify;
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_preview_preview_buildDelayedPreview = require("./buildDelayedPreview.js");
2
+ const require_preview_preview_buildDelayedStrategyVerify = require("./buildDelayedStrategyVerify.js");
3
3
  const require_preview_preview_CreditAccountState = require("./CreditAccountState.js");
4
4
  const require_preview_preview_detectCloseOrRepay = require("./detectCloseOrRepay.js");
5
5
  const require_preview_preview_detectDelayedClaim = require("./detectDelayedClaim.js");
@@ -7,19 +7,19 @@ const require_preview_preview_detectDelayedOperation = require("./detectDelayedO
7
7
  const require_preview_preview_errors = require("./errors.js");
8
8
  const require_preview_preview_replayInnerOperations = require("./replayInnerOperations.js");
9
9
  const require_preview_preview_replayMulticall = require("./replayMulticall.js");
10
- const require_preview_preview_previewAdjustCreditAccount = require("./previewAdjustCreditAccount.js");
11
- const require_preview_preview_previewCloseOrRepayCreditAccount = require("./previewCloseOrRepayCreditAccount.js");
10
+ const require_preview_preview_previewAdjustStrategyVerify = require("./previewAdjustStrategyVerify.js");
11
+ const require_preview_preview_previewExitOrRepayStrategyVerify = require("./previewExitOrRepayStrategyVerify.js");
12
12
  const require_preview_preview_previewOperation = require("./previewOperation.js");
13
13
  exports.CreditAccountState = require_preview_preview_CreditAccountState.CreditAccountState;
14
14
  exports.UnsupportedOperationError = require_preview_preview_errors.UnsupportedOperationError;
15
- exports.buildDelayedPreview = require_preview_preview_buildDelayedPreview.buildDelayedPreview;
15
+ exports.buildDelayedStrategyVerify = require_preview_preview_buildDelayedStrategyVerify.buildDelayedStrategyVerify;
16
16
  exports.classifyCloseOrRepay = require_preview_preview_detectCloseOrRepay.classifyCloseOrRepay;
17
17
  exports.detectDelayedClaim = require_preview_preview_detectDelayedClaim.detectDelayedClaim;
18
18
  exports.detectDelayedOperation = require_preview_preview_detectDelayedOperation.detectDelayedOperation;
19
19
  exports.isCloseOrRepay = require_preview_preview_detectCloseOrRepay.isCloseOrRepay;
20
20
  exports.makeReplayState = require_preview_preview_replayInnerOperations.makeReplayState;
21
- exports.previewAdjustCreditAccount = require_preview_preview_previewAdjustCreditAccount.previewAdjustCreditAccount;
22
- exports.previewCloseOrRepayCreditAccount = require_preview_preview_previewCloseOrRepayCreditAccount.previewCloseOrRepayCreditAccount;
21
+ exports.previewAdjustStrategyVerify = require_preview_preview_previewAdjustStrategyVerify.previewAdjustStrategyVerify;
22
+ exports.previewExitOrRepayStrategyVerify = require_preview_preview_previewExitOrRepayStrategyVerify.previewExitOrRepayStrategyVerify;
23
23
  exports.previewOperation = require_preview_preview_previewOperation.previewOperation;
24
24
  exports.replayInnerOperations = require_preview_preview_replayInnerOperations.replayInnerOperations;
25
25
  exports.replayMulticall = require_preview_preview_replayMulticall.replayMulticall;