@gearbox-protocol/sdk 16.0.0-next.27 → 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 (69) 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/intents/open-strategy.js +4 -18
  4. package/dist/cjs/onchain/accounts/intents/realize.js +77 -50
  5. package/dist/cjs/onchain/accounts/intents/testing/market.js +1 -0
  6. package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +13 -5
  7. package/dist/cjs/onchain/positions/PositionsService.js +79 -0
  8. package/dist/cjs/preview/index.js +6 -6
  9. package/dist/cjs/preview/preview/{buildDelayedPreview.js → buildDelayedStrategyVerify.js} +6 -25
  10. package/dist/cjs/preview/preview/index.js +6 -6
  11. package/dist/cjs/preview/preview/{previewAdjustCreditAccount.js → previewAdjustStrategyVerify.js} +6 -24
  12. package/dist/cjs/preview/preview/{previewCloseOrRepayCreditAccount.js → previewExitOrRepayStrategyVerify.js} +3 -3
  13. package/dist/cjs/preview/preview/{previewPoolOperation.js → previewLpVerify.js} +3 -3
  14. package/dist/cjs/preview/preview/{previewOpenCreditAccount.js → previewOpenStrategyVerify.js} +6 -26
  15. package/dist/cjs/preview/preview/previewOperation.js +10 -10
  16. package/dist/cjs/preview/validate/checkOperation.js +13 -9
  17. package/dist/esm/dev/AccountOpener.js +1 -1
  18. package/dist/esm/dev/withdrawalUtils.js +1 -1
  19. package/dist/esm/model/index.js +2 -2
  20. package/dist/esm/model/previews.js +23 -1
  21. package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +2 -2
  22. package/dist/esm/onchain/accounts/intents/open-strategy.js +4 -18
  23. package/dist/esm/onchain/accounts/intents/realize.js +77 -50
  24. package/dist/esm/onchain/accounts/intents/testing/market.js +1 -0
  25. package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +13 -5
  26. package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +1 -1
  27. package/dist/esm/onchain/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  28. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  29. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  30. package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  31. package/dist/esm/onchain/base/TokensMeta.js +3 -3
  32. package/dist/esm/onchain/core/createAddressProvider.js +1 -1
  33. package/dist/esm/onchain/market/adapters/contracts/AccountMigratorAdapterContract.js +1 -1
  34. package/dist/esm/onchain/market/adapters/contracts/ERC4626AdapterContract.js +1 -1
  35. package/dist/esm/onchain/market/credit/CreditFacadeV310BaseContract.js +1 -1
  36. package/dist/esm/onchain/market/pool/PoolV310Contract.js +1 -1
  37. package/dist/esm/onchain/market/zapper/IETHZapperContract.js +1 -1
  38. package/dist/esm/onchain/market/zapper/ZapperContract.js +1 -1
  39. package/dist/esm/onchain/positions/PositionsService.js +79 -0
  40. package/dist/esm/onchain/utils/viem/simulateWithPriceUpdates.js +1 -1
  41. package/dist/esm/preview/index.js +4 -4
  42. package/dist/esm/preview/preview/{buildDelayedPreview.js → buildDelayedStrategyVerify.js} +7 -26
  43. package/dist/esm/preview/preview/index.js +4 -4
  44. package/dist/esm/preview/preview/{previewAdjustCreditAccount.js → previewAdjustStrategyVerify.js} +7 -25
  45. package/dist/esm/preview/preview/{previewCloseOrRepayCreditAccount.js → previewExitOrRepayStrategyVerify.js} +3 -3
  46. package/dist/esm/preview/preview/{previewPoolOperation.js → previewLpVerify.js} +3 -3
  47. package/dist/esm/preview/preview/{previewOpenCreditAccount.js → previewOpenStrategyVerify.js} +7 -27
  48. package/dist/esm/preview/preview/previewOperation.js +10 -10
  49. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  50. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  51. package/dist/esm/preview/validate/checkOperation.js +13 -9
  52. package/dist/types/model/index.d.ts +2 -2
  53. package/dist/types/model/previews.d.ts +202 -76
  54. package/dist/types/onchain/accounts/intents/open-strategy.d.ts +1 -7
  55. package/dist/types/onchain/accounts/intents/testing/market.d.ts +1 -0
  56. package/dist/types/onchain/accounts/intents/testing/sdk-mock.d.ts +7 -0
  57. package/dist/types/onchain/positions/PositionsService.d.ts +30 -0
  58. package/dist/types/preview/index.d.ts +5 -5
  59. package/dist/types/preview/preview/{buildDelayedPreview.d.ts → buildDelayedStrategyVerify.d.ts} +4 -4
  60. package/dist/types/preview/preview/index.d.ts +4 -4
  61. package/dist/types/preview/preview/{previewAdjustCreditAccount.d.ts → previewAdjustStrategyVerify.d.ts} +4 -4
  62. package/dist/types/preview/preview/{previewCloseOrRepayCreditAccount.d.ts → previewExitOrRepayStrategyVerify.d.ts} +4 -4
  63. package/dist/types/preview/preview/previewLpVerify.d.ts +11 -0
  64. package/dist/types/preview/preview/previewOpenStrategyVerify.d.ts +12 -0
  65. package/dist/types/preview/validate/checkOperation.d.ts +12 -4
  66. package/dist/types/preview/validate/index.d.ts +2 -2
  67. package/package.json +1 -1
  68. package/dist/types/preview/preview/previewOpenCreditAccount.d.ts +0 -12
  69. package/dist/types/preview/preview/previewPoolOperation.d.ts +0 -11
@@ -1,6 +1,6 @@
1
+ import { iWithdrawalCompressorV313Abi } from "../../../abi/IWithdrawalCompressorV313.js";
1
2
  import { encodeDelayedIntent } from "./intent-codec.js";
2
3
  import { AbstractWithdrawalCompressorContract, iCreditAccountAbi, toClaimableWithdrawal, toPendingWithdrawal, toRequestableWithdrawal } from "./AbstractWithdrawalCompressorContract.js";
3
- import { iWithdrawalCompressorV313Abi } from "../../../abi/IWithdrawalCompressorV313.js";
4
4
  import { toWithdrawalStatus } from "./types.js";
5
5
  //#region src/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.ts
6
6
  const abi = iWithdrawalCompressorV313Abi;
@@ -1,12 +1,12 @@
1
+ import { iExpirableAbi } from "../../abi/iExpirable.js";
2
+ import { iStateSerializerAbi } from "../../abi/iStateSerializer.js";
3
+ import { iVersionAbi } from "../../abi/iVersion.js";
1
4
  import { AddressMap } from "../utils/AddressMap.js";
2
5
  import { AddressSet } from "../utils/AddressSet.js";
3
6
  import { bytes32ToString } from "../utils/bytes32ToString.js";
4
7
  import { getAssetType } from "../chain/chains.js";
5
8
  import { formatBN } from "../utils/formatter.js";
6
9
  import "../utils/index.js";
7
- import { iExpirableAbi } from "../../abi/iExpirable.js";
8
- import { iStateSerializerAbi } from "../../abi/iStateSerializer.js";
9
- import { iVersionAbi } from "../../abi/iVersion.js";
10
10
  import { SdkRWADataNotLoadedError } from "../core/errors.js";
11
11
  import { executeMulticallBatches } from "../utils/viem/executeMulticallBatches.js";
12
12
  //#region src/onchain/base/TokensMeta.ts
@@ -1,8 +1,8 @@
1
+ import { iVersionAbi } from "../../abi/iVersion.js";
1
2
  import { AP_MARKET_COMPRESSOR, AP_PRICE_FEED_COMPRESSOR } from "../constants/address-provider.js";
2
3
  import { isV310 } from "../constants/versions.js";
3
4
  import "../constants/index.js";
4
5
  import { hexEq } from "../utils/hex.js";
5
- import { iVersionAbi } from "../../abi/iVersion.js";
6
6
  import { AddressProviderV310Contract } from "./AddressProviderV310Contract.js";
7
7
  //#region src/onchain/core/createAddressProvider.ts
8
8
  const OVERRIDE_ADDRESSES = { Mainnet: {
@@ -1,5 +1,5 @@
1
- import { AbstractAdapterContract } from "./AbstractAdapter.js";
2
1
  import { accountMigratorAbi } from "../../../../abi/AccountMigrator.js";
2
+ import { AbstractAdapterContract } from "./AbstractAdapter.js";
3
3
  //#region src/onchain/market/adapters/contracts/AccountMigratorAdapterContract.ts
4
4
  const abi = accountMigratorAbi;
5
5
  const protocolAbi = accountMigratorAbi;
@@ -1,6 +1,6 @@
1
+ import { ierc4626AdapterAbi } from "../../../../abi/ierc4626Adapter.js";
1
2
  import { MissingSerializedParamsError } from "../../../base/errors.js";
2
3
  import "../../../base/index.js";
3
- import { ierc4626AdapterAbi } from "../../../../abi/ierc4626Adapter.js";
4
4
  import { iERC4626Abi } from "../abi/targetContractAbi.js";
5
5
  import { fnSigToName, swapFromTransfers } from "../transferHelpers.js";
6
6
  import { AbstractAdapterContract } from "./AbstractAdapter.js";
@@ -1,7 +1,7 @@
1
+ import { iPausableAbi } from "../../../abi/iPausable.js";
1
2
  import { iCreditFacadeMulticallV310Abi, iCreditFacadeV310Abi } from "../../../abi/310/generated.js";
2
3
  import { BaseContract } from "../../base/BaseContract.js";
3
4
  import "../../base/index.js";
4
- import { iPausableAbi } from "../../../abi/iPausable.js";
5
5
  //#region src/onchain/market/credit/CreditFacadeV310BaseContract.ts
6
6
  const abi = [
7
7
  ...iCreditFacadeV310Abi,
@@ -1,3 +1,4 @@
1
+ import { iPausableAbi } from "../../../abi/iPausable.js";
1
2
  import { iPoolV310Abi } from "../../../abi/310/generated.js";
2
3
  import { AddressMap } from "../../utils/AddressMap.js";
3
4
  import { RAY } from "../../constants/math.js";
@@ -7,7 +8,6 @@ import "../../utils/index.js";
7
8
  import { SdkRWADataNotLoadedError } from "../../core/errors.js";
8
9
  import { BaseContract } from "../../base/BaseContract.js";
9
10
  import "../../base/index.js";
10
- import { iPausableAbi } from "../../../abi/iPausable.js";
11
11
  //#region src/onchain/market/pool/PoolV310Contract.ts
12
12
  const abi = [...iPoolV310Abi, ...iPausableAbi];
13
13
  var PoolV310Contract = class extends BaseContract {
@@ -1,5 +1,5 @@
1
- import { ZapperContract } from "./ZapperContract.js";
2
1
  import { iethZapperAbi } from "../../../abi/iETHZapper.js";
2
+ import { ZapperContract } from "./ZapperContract.js";
3
3
  //#region src/onchain/market/zapper/IETHZapperContract.ts
4
4
  const abi = iethZapperAbi;
5
5
  var IETHZapperContract = class extends ZapperContract {
@@ -1,6 +1,6 @@
1
+ import { iZapperAbi } from "../../../abi/iZapper.js";
1
2
  import { BaseContract } from "../../base/BaseContract.js";
2
3
  import "../../base/index.js";
3
- import { iZapperAbi } from "../../../abi/iZapper.js";
4
4
  import { UnsupportedZapperFunctionError } from "./errors.js";
5
5
  //#region src/onchain/market/zapper/ZapperContract.ts
6
6
  /**
@@ -163,6 +163,85 @@ var PositionsService = class extends SDKConstruct {
163
163
  });
164
164
  }
165
165
  /**
166
+ * Every derived number of an account state at once — the whole
167
+ * {@link AccountMetrics} half of a projection.
168
+ *
169
+ * This is what both halves of the SDK fill their answers from: `prepare`, for
170
+ * a state it walked an intent into, and `preview`, for one it replayed out of
171
+ * calldata. One snapshot in, one set of metrics out, so the two descriptions
172
+ * of the same operation cannot disagree because one of them grew its own
173
+ * formula.
174
+ *
175
+ * Identical to the four methods above field for field, and cheaper than
176
+ * calling them one by one: the market data is collected once, and the health
177
+ * factor and borrow rate the time to liquidation decays at are the very ones
178
+ * reported beside it.
179
+ **/
180
+ metrics(snapshot, options) {
181
+ const data = this.#marketData(snapshot);
182
+ const factor = (safePrices) => calcHealthFactor({
183
+ snapshot,
184
+ underlying: data.underlying,
185
+ decimals: data.decimals,
186
+ prices: data.prices,
187
+ reservePrices: data.reservePrices,
188
+ safePrices,
189
+ liquidationThresholds: data.liquidationThresholds,
190
+ activeQuotas: data.activeQuotas
191
+ });
192
+ const healthFactor = factor(false);
193
+ const borrowRate = calcBorrowRate({
194
+ snapshot,
195
+ baseInterestRate: this.#baseInterestRate(snapshot, data, options),
196
+ feeInterest: data.feeInterest,
197
+ quotaRates: data.quotaRates,
198
+ resolveToken: (address) => this.sdk.tokensMeta.mustGetToken(address)
199
+ });
200
+ return {
201
+ healthFactor,
202
+ safeHealthFactor: factor(true),
203
+ borrowRate,
204
+ timeToLiquidation: calcTimeToLiquidationMs(healthFactor, BigInt(borrowRate.totalOnDebt)),
205
+ liquidationPrice: calcLiquidationPrice({
206
+ snapshot,
207
+ underlying: data.underlying,
208
+ decimals: data.decimals,
209
+ liquidationThresholds: data.liquidationThresholds
210
+ }),
211
+ leverage: calcPositionLeverage(snapshot.totalValue, snapshot.totalDebt)
212
+ };
213
+ }
214
+ /**
215
+ * A projected account state as both halves of the SDK report it: the holdings
216
+ * priced and named, and the metrics of {@link PositionsService.metrics}.
217
+ *
218
+ * The snapshot is taken at its word — what it lists is what comes back, so a
219
+ * caller that drops dust before the walk reports an account without it, and
220
+ * one that keeps wei reports them. That is the whole of the policy left to
221
+ * the caller; everything downstream of the balances is decided here.
222
+ *
223
+ * @param options - The operation's effect on the pool, for the rate the
224
+ * metrics are quoted at, see {@link ProjectedPoolOptions}.
225
+ **/
226
+ projection(snapshot, options) {
227
+ const { creditManager, totalValue, totalDebt } = snapshot;
228
+ const market = this.sdk.marketRegister.findByCreditManager(creditManager);
229
+ const { priceOracle } = market;
230
+ return {
231
+ creditManager,
232
+ name: this.sdk.marketRegister.findCreditManager(creditManager).name,
233
+ totalValue: market.toUnderlyingAmount(totalValue),
234
+ totalDebt: market.toUnderlyingAmount(totalDebt),
235
+ netValue: market.toUnderlyingAmount(totalValue - totalDebt),
236
+ assets: snapshot.assets.map((a) => priceOracle.toTokenAmount(a.token, a.balance)),
237
+ quotas: snapshot.quotas.map((q) => ({
238
+ token: this.sdk.tokensMeta.mustGetToken(q.token),
239
+ ...priceOracle.toAmount(market.underlying, q.balance)
240
+ })),
241
+ ...this.metrics(snapshot, options)
242
+ };
243
+ }
244
+ /**
166
245
  * Builds one strategy position from an account snapshot.
167
246
  *
168
247
  * @param withdrawals - Delayed withdrawals of the account, keyed by the
@@ -1,6 +1,6 @@
1
1
  import { errorAbis } from "../../../abi/errors.js";
2
- import { generateCastTraceCall } from "./cast.js";
3
2
  import { iUpdatablePriceFeedAbi } from "../../../abi/iUpdatablePriceFeed.js";
3
+ import { generateCastTraceCall } from "./cast.js";
4
4
  import { simulateMulticall } from "./simulateMulticall.js";
5
5
  import { BaseError, CallExecutionError, ContractFunctionRevertedError, decodeFunctionData, decodeFunctionResult, encodeFunctionData, parseAbi } from "viem";
6
6
  import { getAction, parseAccount } from "viem/utils";
@@ -19,7 +19,7 @@ import { BalancePrerequisite } from "./prerequisites/BalancePrerequisite.js";
19
19
  import { RWAOpenRequirementsPrerequisite } from "./prerequisites/RWAOpenRequirementsPrerequisite.js";
20
20
  import { checkPrerequisites } from "./prerequisites/checkPrerequisites.js";
21
21
  import "./prerequisites/index.js";
22
- import { buildDelayedPreview } from "./preview/buildDelayedPreview.js";
22
+ import { buildDelayedStrategyVerify } from "./preview/buildDelayedStrategyVerify.js";
23
23
  import { CreditAccountState } from "./preview/CreditAccountState.js";
24
24
  import { classifyCloseOrRepay, isCloseOrRepay } from "./preview/detectCloseOrRepay.js";
25
25
  import { detectDelayedClaim, resolveDelayedClaimIntent } from "./preview/detectDelayedClaim.js";
@@ -27,12 +27,12 @@ import { detectDelayedOperation } from "./preview/detectDelayedOperation.js";
27
27
  import { UnsupportedOperationError } from "./preview/errors.js";
28
28
  import { makeReplayState, replayInnerOperations } from "./preview/replayInnerOperations.js";
29
29
  import { replayMulticall } from "./preview/replayMulticall.js";
30
- import { previewAdjustCreditAccount } from "./preview/previewAdjustCreditAccount.js";
31
- import { previewCloseOrRepayCreditAccount } from "./preview/previewCloseOrRepayCreditAccount.js";
30
+ import { previewAdjustStrategyVerify } from "./preview/previewAdjustStrategyVerify.js";
31
+ import { previewExitOrRepayStrategyVerify } from "./preview/previewExitOrRepayStrategyVerify.js";
32
32
  import { previewOperation } from "./preview/previewOperation.js";
33
33
  import "./preview/index.js";
34
34
  import "./types.js";
35
35
  import { checkOperation, collateralIssue, marketIssues, quotaCountIssue } from "./validate/checkOperation.js";
36
36
  import { checkSimulation } from "./validate/checkSimulation.js";
37
37
  import "./validate/index.js";
38
- export { AllowancePrerequisite, BalancePrerequisite, CreditAccountState, IntentPreviewError, Prerequisite, RWAOpenRequirementsPrerequisite, TransferAlignmentError, UnexpectedFacadeEventOrderError, UnknownAdapterError, UnknownFacadeCallError, UnsupportedOperationError, UnsupportedPoolFunctionError, UnsupportedTargetError, UnsupportedZapperFunctionError, WithdrawCollateralAlignmentError, buildDelayedPreview, checkOperation, checkPrerequisites, checkSimulation, classifyCloseOrRepay, classifyInnerOperations, collateralIssue, detectDelayedClaim, detectDelayedOperation, extractAdapterCallTraces, extractTransfers, findFacadeCalls, isCloseOrRepay, isPoolOperation, isRWAOperation, makeReplayState, marketIssues, parseFacadeOperationCalldata, parseOperationCalldata, parsePoolOperationCalldata, parseRWAFactoryOperationCalldata, previewAdjustCreditAccount, previewCloseOrRepayCreditAccount, previewOperation, quotaCountIssue, raise, refuse, replayInnerOperations, replayMulticall, resolveDelayedClaimIntent };
38
+ export { AllowancePrerequisite, BalancePrerequisite, CreditAccountState, IntentPreviewError, Prerequisite, RWAOpenRequirementsPrerequisite, TransferAlignmentError, UnexpectedFacadeEventOrderError, UnknownAdapterError, UnknownFacadeCallError, UnsupportedOperationError, UnsupportedPoolFunctionError, UnsupportedTargetError, UnsupportedZapperFunctionError, WithdrawCollateralAlignmentError, buildDelayedStrategyVerify, checkOperation, checkPrerequisites, checkSimulation, classifyCloseOrRepay, classifyInnerOperations, collateralIssue, detectDelayedClaim, detectDelayedOperation, extractAdapterCallTraces, extractTransfers, findFacadeCalls, isCloseOrRepay, isPoolOperation, isRWAOperation, makeReplayState, marketIssues, parseFacadeOperationCalldata, parseOperationCalldata, parsePoolOperationCalldata, parseRWAFactoryOperationCalldata, previewAdjustStrategyVerify, previewExitOrRepayStrategyVerify, previewOperation, quotaCountIssue, raise, refuse, replayInnerOperations, replayMulticall, resolveDelayedClaimIntent };
@@ -1,12 +1,11 @@
1
1
  import { AssetsMap } from "../../onchain/utils/AssetsMap.js";
2
2
  import { BigIntMath } from "../../onchain/utils/bigint-math.js";
3
3
  import { DUST_THRESHOLD } from "../../onchain/constants/math.js";
4
- import { calcPositionLeverage } from "../../onchain/market/math.js";
5
- import { ERROR_UNPRICEABLE_TOKEN } from "../../model/previews.js";
4
+ import { ERROR_UNPRICEABLE_TOKEN, asEstimated } from "../../model/previews.js";
6
5
  import "../../model/index.js";
7
6
  import "../../onchain/index.js";
8
7
  import { isAddressEqual } from "viem";
9
- //#region src/preview/preview/buildDelayedPreview.ts
8
+ //#region src/preview/preview/buildDelayedStrategyVerify.ts
10
9
  /**
11
10
  * Builds the best-effort preview of the account state after the detected
12
11
  * delayed withdrawal is claimed and its intent (if any) is resumed:
@@ -29,7 +28,7 @@ import { isAddressEqual } from "viem";
29
28
  * @param sdk - Market data source for the position metrics of the resulting
30
29
  * state; read synchronously, no network access.
31
30
  */
32
- function buildDelayedPreview(afterInstant, before, detected, convert, receivedToken, sdk) {
31
+ function buildDelayedStrategyVerify(afterInstant, before, detected, convert, receivedToken, sdk) {
33
32
  const { request, intent } = detected;
34
33
  const post = afterInstant.clone();
35
34
  const converter = makeSafeConverter(convert);
@@ -174,41 +173,23 @@ function buildClosePreview(post, converter, receivedToken, sdk) {
174
173
  };
175
174
  }
176
175
  function buildAdjustPreview(post, before, collateralWithdrawn, converter, sdk) {
177
- const totalValue = totalValueInUnderlying(post, converter.convert, DUST_THRESHOLD);
178
- const assets = post.balances.toAssets(DUST_THRESHOLD);
179
- const quotas = post.quotas.toAssets(0n);
180
- const snap = post.toSnapshot(totalValue);
176
+ const snap = post.toSnapshot(totalValueInUnderlying(post, converter.convert, DUST_THRESHOLD));
181
177
  const market = sdk.marketRegister.findByCreditManager(post.creditManager);
182
178
  const oracle = market.priceOracle;
183
179
  return {
184
180
  operation: "AdjustCreditAccount",
185
- creditManager: post.creditManager,
186
- name: sdk.marketRegister.findCreditManager(post.creditManager).name,
181
+ ...asEstimated(sdk.positions.projection(snap, { availableLiquidityChange: before.totalDebt - post.totalDebt })),
187
182
  creditAccount: post.creditAccount,
188
183
  collateralAdded: [],
189
184
  collateralWithdrawn: collateralWithdrawn.toAssets().map((a) => oracle.toTokenAmount(a.token, a.balance)),
190
- totalValue: market.toUnderlyingAmount(totalValue),
191
- totalDebt: market.toUnderlyingAmount(post.totalDebt),
192
- netValue: market.toUnderlyingAmount(totalValue - post.totalDebt),
193
185
  totalDebtChange: market.toUnderlyingAmount(post.totalDebt - before.totalDebt),
194
- quotas: quotas.map((q) => ({
195
- token: sdk.tokensMeta.mustGetToken(q.token),
196
- ...oracle.toAmount(market.underlying, q.balance)
197
- })),
198
186
  quotasChange: post.quotas.difference(before.quotas).toAssets().map((q) => ({
199
187
  token: sdk.tokensMeta.mustGetToken(q.token),
200
188
  ...oracle.toAmount(market.underlying, q.balance)
201
189
  })),
202
- assets: assets.map((a) => oracle.toTokenAmount(a.token, a.balance)),
203
190
  assetsChange: post.balances.difference(before.balances).toAssets(DUST_THRESHOLD).map((a) => oracle.toTokenAmount(a.token, a.balance)),
204
- error: converter.error,
205
- healthFactor: sdk.positions.healthFactor(snap),
206
- safeHealthFactor: sdk.positions.healthFactor(snap, { safePrices: true }),
207
- borrowRate: sdk.positions.borrowRate(snap, { availableLiquidityChange: before.totalDebt - post.totalDebt }),
208
- timeToLiquidation: sdk.positions.timeToLiquidation(snap, { availableLiquidityChange: before.totalDebt - post.totalDebt }),
209
- liquidationPrice: sdk.positions.liquidationPrice(snap),
210
- leverage: calcPositionLeverage(totalValue, post.totalDebt)
191
+ error: converter.error
211
192
  };
212
193
  }
213
194
  //#endregion
214
- export { buildDelayedPreview };
195
+ export { buildDelayedStrategyVerify };
@@ -1,4 +1,4 @@
1
- import { buildDelayedPreview } from "./buildDelayedPreview.js";
1
+ import { buildDelayedStrategyVerify } from "./buildDelayedStrategyVerify.js";
2
2
  import { CreditAccountState } from "./CreditAccountState.js";
3
3
  import { classifyCloseOrRepay, isCloseOrRepay } from "./detectCloseOrRepay.js";
4
4
  import { detectDelayedClaim, resolveDelayedClaimIntent } from "./detectDelayedClaim.js";
@@ -6,7 +6,7 @@ import { detectDelayedOperation } from "./detectDelayedOperation.js";
6
6
  import { UnsupportedOperationError } from "./errors.js";
7
7
  import { makeReplayState, replayInnerOperations } from "./replayInnerOperations.js";
8
8
  import { replayMulticall } from "./replayMulticall.js";
9
- import { previewAdjustCreditAccount } from "./previewAdjustCreditAccount.js";
10
- import { previewCloseOrRepayCreditAccount } from "./previewCloseOrRepayCreditAccount.js";
9
+ import { previewAdjustStrategyVerify } from "./previewAdjustStrategyVerify.js";
10
+ import { previewExitOrRepayStrategyVerify } from "./previewExitOrRepayStrategyVerify.js";
11
11
  import { previewOperation } from "./previewOperation.js";
12
- export { CreditAccountState, UnsupportedOperationError, buildDelayedPreview, classifyCloseOrRepay, detectDelayedClaim, detectDelayedOperation, isCloseOrRepay, makeReplayState, previewAdjustCreditAccount, previewCloseOrRepayCreditAccount, previewOperation, replayInnerOperations, replayMulticall, resolveDelayedClaimIntent };
12
+ export { CreditAccountState, UnsupportedOperationError, buildDelayedStrategyVerify, classifyCloseOrRepay, detectDelayedClaim, detectDelayedOperation, isCloseOrRepay, makeReplayState, previewAdjustStrategyVerify, previewExitOrRepayStrategyVerify, previewOperation, replayInnerOperations, replayMulticall, resolveDelayedClaimIntent };
@@ -1,12 +1,11 @@
1
1
  import { AP_WETH_TOKEN } from "../../onchain/constants/address-provider.js";
2
2
  import { DUST_THRESHOLD } from "../../onchain/constants/math.js";
3
- import { calcPositionLeverage } from "../../onchain/market/math.js";
4
- import { ERROR_UNPRICEABLE_TOKEN } from "../../model/previews.js";
3
+ import { ERROR_UNPRICEABLE_TOKEN, asEstimated } from "../../model/previews.js";
5
4
  import "../../model/index.js";
6
5
  import "../../onchain/index.js";
7
6
  import { replayMulticall } from "./replayMulticall.js";
8
7
  import { unwrapNativeCollateral } from "./unwrapNativeCollateral.js";
9
- //#region src/preview/preview/previewAdjustCreditAccount.ts
8
+ //#region src/preview/preview/previewAdjustStrategyVerify.ts
10
9
  /**
11
10
  * Previews a `multicall`/`botMulticall` operation on an existing credit
12
11
  * account: threads the multicall through {@link replayMulticall} over the
@@ -14,7 +13,7 @@ import { unwrapNativeCollateral } from "./unwrapNativeCollateral.js";
14
13
  * minimal guaranteed post-state alongside the changes relative to the
15
14
  * pre-state.
16
15
  */
17
- async function previewAdjustCreditAccount(input, operation, options) {
16
+ async function previewAdjustStrategyVerify(input, operation, options) {
18
17
  const { sdk, value = 0n } = input;
19
18
  const market = sdk.marketRegister.findByCreditManager(operation.creditManager);
20
19
  const oracle = market.priceOracle;
@@ -23,10 +22,8 @@ async function previewAdjustCreditAccount(input, operation, options) {
23
22
  let error = replayError;
24
23
  const { assets: collateralAdded, error: unwrapError } = unwrapNativeCollateral(after.collateralAdded.toAssets(), value, sdk.addressProvider.getAddress(AP_WETH_TOKEN, 0));
25
24
  error ??= unwrapError;
26
- const assets = account.balances.toAssets(DUST_THRESHOLD);
27
- const quotas = account.quotas.toAssets(0n);
28
25
  const assetsChange = account.balances.difference(before.balances).toAssets(DUST_THRESHOLD);
29
- const totalValue = assets.reduce((acc, { token, balance }) => {
26
+ const totalValue = account.balances.toAssets(DUST_THRESHOLD).reduce((acc, { token, balance }) => {
30
27
  try {
31
28
  return acc + oracle.convert(token, market.underlying, balance);
32
29
  } catch {
@@ -40,33 +37,18 @@ async function previewAdjustCreditAccount(input, operation, options) {
40
37
  const snap = account.toSnapshot(totalValue);
41
38
  return {
42
39
  operation: "AdjustCreditAccount",
43
- creditManager: operation.creditManager,
44
- name: sdk.marketRegister.findCreditManager(operation.creditManager).name,
40
+ ...asEstimated(sdk.positions.projection(snap, { availableLiquidityChange: before.totalDebt - account.totalDebt })),
45
41
  creditAccount: operation.creditAccount,
46
42
  collateralAdded: collateralAdded.map((a) => oracle.toTokenAmount(a.token, a.balance)),
47
43
  collateralWithdrawn: after.collateralWithdrawn.toAssets().map((a) => oracle.toTokenAmount(a.token, a.balance)),
48
- totalValue: market.toUnderlyingAmount(totalValue),
49
- totalDebt: market.toUnderlyingAmount(account.totalDebt),
50
- netValue: market.toUnderlyingAmount(totalValue - account.totalDebt),
51
44
  totalDebtChange: market.toUnderlyingAmount(account.totalDebt - before.totalDebt),
52
- quotas: quotas.map((q) => ({
53
- token: sdk.tokensMeta.mustGetToken(q.token),
54
- ...oracle.toAmount(market.underlying, q.balance)
55
- })),
56
45
  quotasChange: account.quotas.difference(before.quotas).toAssets().map((q) => ({
57
46
  token: sdk.tokensMeta.mustGetToken(q.token),
58
47
  ...oracle.toAmount(market.underlying, q.balance)
59
48
  })),
60
- assets: assets.map((a) => oracle.toTokenAmount(a.token, a.balance)),
61
49
  assetsChange: assetsChange.map((a) => oracle.toTokenAmount(a.token, a.balance)),
62
- error,
63
- healthFactor: sdk.positions.healthFactor(snap),
64
- safeHealthFactor: sdk.positions.healthFactor(snap, { safePrices: true }),
65
- borrowRate: sdk.positions.borrowRate(snap, { availableLiquidityChange: before.totalDebt - account.totalDebt }),
66
- timeToLiquidation: sdk.positions.timeToLiquidation(snap, { availableLiquidityChange: before.totalDebt - account.totalDebt }),
67
- liquidationPrice: sdk.positions.liquidationPrice(snap),
68
- leverage: calcPositionLeverage(totalValue, account.totalDebt)
50
+ error
69
51
  };
70
52
  }
71
53
  //#endregion
72
- export { previewAdjustCreditAccount };
54
+ export { previewAdjustStrategyVerify };
@@ -4,8 +4,8 @@ import "../../onchain/index.js";
4
4
  import { classifyCloseOrRepay } from "./detectCloseOrRepay.js";
5
5
  import { replayMulticall } from "./replayMulticall.js";
6
6
  import { unwrapNativeCollateral } from "./unwrapNativeCollateral.js";
7
- //#region src/preview/preview/previewCloseOrRepayCreditAccount.ts
8
- async function previewCloseOrRepayCreditAccount(input, operation, permanent, options) {
7
+ //#region src/preview/preview/previewExitOrRepayStrategyVerify.ts
8
+ async function previewExitOrRepayStrategyVerify(input, operation, permanent, options) {
9
9
  const { sdk } = input;
10
10
  const market = sdk.marketRegister.findByCreditManager(operation.creditManager);
11
11
  const exitTokens = [market.underlying];
@@ -62,4 +62,4 @@ function previewRepayCreditAccount(input, operation, permanent, replay) {
62
62
  };
63
63
  }
64
64
  //#endregion
65
- export { previewCloseOrRepayCreditAccount };
65
+ export { previewExitOrRepayStrategyVerify };
@@ -1,7 +1,7 @@
1
1
  import { simulatePoolOperation } from "../simulate/simulatePoolOperation.js";
2
2
  import "../simulate/index.js";
3
- //#region src/preview/preview/previewPoolOperation.ts
4
- async function previewPoolOperation(input, operation, options) {
3
+ //#region src/preview/preview/previewLpVerify.ts
4
+ async function previewLpVerify(input, operation, options) {
5
5
  const { sdk, to, calldata } = input;
6
6
  const { tokenIn, tokenOut } = operation;
7
7
  const market = sdk.marketRegister.findByPool(operation.pool);
@@ -21,4 +21,4 @@ async function previewPoolOperation(input, operation, options) {
21
21
  };
22
22
  }
23
23
  //#endregion
24
- export { previewPoolOperation };
24
+ export { previewLpVerify };
@@ -1,14 +1,12 @@
1
1
  import { AP_WETH_TOKEN } from "../../onchain/constants/address-provider.js";
2
- import { DUST_THRESHOLD } from "../../onchain/constants/math.js";
3
- import { calcPositionLeverage } from "../../onchain/market/math.js";
4
- import { ERROR_UNPRICEABLE_TOKEN } from "../../model/previews.js";
2
+ import { ERROR_UNPRICEABLE_TOKEN, asEstimated } from "../../model/previews.js";
5
3
  import "../../model/index.js";
6
4
  import "../../onchain/index.js";
7
5
  import { CreditAccountState } from "./CreditAccountState.js";
8
6
  import { makeReplayState, replayInnerOperations } from "./replayInnerOperations.js";
9
7
  import { unwrapNativeCollateral } from "./unwrapNativeCollateral.js";
10
- //#region src/preview/preview/previewOpenCreditAccount.ts
11
- async function previewOpenCreditAccount(input, operation) {
8
+ //#region src/preview/preview/previewOpenStrategyVerify.ts
9
+ async function previewOpenStrategyVerify(input, operation) {
12
10
  const { sdk, value = 0n } = input;
13
11
  const market = sdk.marketRegister.findByCreditManager(operation.creditManager);
14
12
  const oracle = market.priceOracle;
@@ -29,32 +27,14 @@ async function previewOpenCreditAccount(input, operation) {
29
27
  });
30
28
  const { assets: collateral, error: unwrapError } = unwrapNativeCollateral(state.collateralAdded.toAssets(), value, sdk.addressProvider.getAddress(AP_WETH_TOKEN, 0));
31
29
  error ??= unwrapError ?? priceError;
32
- const assets = account.balances.toAssets(DUST_THRESHOLD);
33
- const quotas = account.quotas.toAssets(0n);
34
- const totalValue = netValue + account.totalDebt;
35
- const snap = account.toSnapshot(totalValue);
30
+ const snap = account.toSnapshot(netValue + account.totalDebt);
36
31
  const targetAsset = inferTargetAsset(operation.multicall, account.balances);
37
32
  return {
38
33
  operation: operation.operation,
39
- creditManager: operation.creditManager,
40
- name: sdk.marketRegister.findCreditManager(operation.creditManager).name,
34
+ ...asEstimated(sdk.positions.projection(snap, { availableLiquidityChange: -account.totalDebt })),
41
35
  targetCollateral: targetAsset ? oracle.toTokenAmount(targetAsset.token, targetAsset.balance) : void 0,
42
36
  collateralAdded: collateral.map((a) => oracle.toTokenAmount(a.token, a.balance)),
43
- netValue: market.toUnderlyingAmount(netValue),
44
- totalValue: market.toUnderlyingAmount(totalValue),
45
- totalDebt: market.toUnderlyingAmount(account.totalDebt),
46
- quotas: quotas.map((q) => ({
47
- token: sdk.tokensMeta.mustGetToken(q.token),
48
- ...oracle.toAmount(market.underlying, q.balance)
49
- })),
50
- assets: assets.map((a) => oracle.toTokenAmount(a.token, a.balance)),
51
- error,
52
- healthFactor: sdk.positions.healthFactor(snap),
53
- safeHealthFactor: sdk.positions.healthFactor(snap, { safePrices: true }),
54
- borrowRate: sdk.positions.borrowRate(snap, { availableLiquidityChange: -account.totalDebt }),
55
- timeToLiquidation: sdk.positions.timeToLiquidation(snap, { availableLiquidityChange: -account.totalDebt }),
56
- liquidationPrice: sdk.positions.liquidationPrice(snap),
57
- leverage: calcPositionLeverage(totalValue, account.totalDebt)
37
+ error
58
38
  };
59
39
  }
60
40
  /**
@@ -72,4 +52,4 @@ function inferTargetAsset(multicall, balances) {
72
52
  }
73
53
  }
74
54
  //#endregion
75
- export { previewOpenCreditAccount };
55
+ export { previewOpenStrategyVerify };
@@ -1,16 +1,16 @@
1
1
  import { parseOperationCalldata } from "../parse/parseOperationCalldata.js";
2
2
  import { isPoolOperation } from "../parse/types.js";
3
3
  import "../parse/index.js";
4
- import { buildDelayedPreview } from "./buildDelayedPreview.js";
4
+ import { buildDelayedStrategyVerify } from "./buildDelayedStrategyVerify.js";
5
5
  import { isCloseOrRepay } from "./detectCloseOrRepay.js";
6
6
  import { resolveDelayedClaimIntent } from "./detectDelayedClaim.js";
7
7
  import { detectDelayedOperation } from "./detectDelayedOperation.js";
8
8
  import { UnsupportedOperationError } from "./errors.js";
9
9
  import { replayMulticall } from "./replayMulticall.js";
10
- import { previewAdjustCreditAccount } from "./previewAdjustCreditAccount.js";
11
- import { previewCloseOrRepayCreditAccount } from "./previewCloseOrRepayCreditAccount.js";
12
- import { previewOpenCreditAccount } from "./previewOpenCreditAccount.js";
13
- import { previewPoolOperation } from "./previewPoolOperation.js";
10
+ import { previewAdjustStrategyVerify } from "./previewAdjustStrategyVerify.js";
11
+ import { previewExitOrRepayStrategyVerify } from "./previewExitOrRepayStrategyVerify.js";
12
+ import { previewLpVerify } from "./previewLpVerify.js";
13
+ import { previewOpenStrategyVerify } from "./previewOpenStrategyVerify.js";
14
14
  //#region src/preview/preview/previewOperation.ts
15
15
  /**
16
16
  * Previews a raw operation calldata: decodes it into a typed operation and
@@ -18,11 +18,11 @@ import { previewPoolOperation } from "./previewPoolOperation.js";
18
18
  */
19
19
  async function previewOperation(input, options) {
20
20
  const operation = parseOperationCalldata(input);
21
- if (isPoolOperation(operation)) return previewPoolOperation(input, operation, options);
22
- if (operation.operation === "OpenCreditAccount" || operation.operation === "RWAOpenCreditAccount") return previewOpenCreditAccount(input, operation);
21
+ if (isPoolOperation(operation)) return previewLpVerify(input, operation, options);
22
+ if (operation.operation === "OpenCreditAccount" || operation.operation === "RWAOpenCreditAccount") return previewOpenStrategyVerify(input, operation);
23
23
  if (operation.operation === "CloseCreditAccount") {
24
24
  const resolved = await resolveCreditAccount(input, operation, options);
25
- const preview = await previewCloseOrRepayCreditAccount(input, operation, true, resolved);
25
+ const preview = await previewExitOrRepayStrategyVerify(input, operation, true, resolved);
26
26
  preview.intent = await resolveDelayedClaimIntent(input.sdk, operation.multicall, options?.blockNumber);
27
27
  return preview;
28
28
  }
@@ -52,7 +52,7 @@ async function resolveCreditAccount(input, operation, options) {
52
52
  */
53
53
  async function previewMulticallOperation(input, operation, options) {
54
54
  const { sdk } = input;
55
- const instantPreview = isCloseOrRepay(operation.multicall) ? await previewCloseOrRepayCreditAccount(input, operation, false, options) : await previewAdjustCreditAccount(input, operation, options);
55
+ const instantPreview = isCloseOrRepay(operation.multicall) ? await previewExitOrRepayStrategyVerify(input, operation, false, options) : await previewAdjustStrategyVerify(input, operation, options);
56
56
  const delayed = detectDelayedOperation(sdk, operation.multicall);
57
57
  if (!delayed) {
58
58
  instantPreview.intent = await resolveDelayedClaimIntent(sdk, operation.multicall, options?.blockNumber);
@@ -70,7 +70,7 @@ async function previewMulticallOperation(input, operation, options) {
70
70
  name: sdk.marketRegister.findCreditManager(operation.creditManager).name,
71
71
  intent: delayed.intent,
72
72
  instantPreview,
73
- delayedPreview: buildDelayedPreview(after.account, before, delayed, convert, receivedToken, sdk)
73
+ delayedPreview: buildDelayedStrategyVerify(after.account, before, delayed, convert, receivedToken, sdk)
74
74
  };
75
75
  }
76
76
  //#endregion
@@ -1,5 +1,5 @@
1
- import { iPoolV310Abi } from "../../abi/310/generated.js";
2
1
  import { iZapperAbi } from "../../abi/iZapper.js";
2
+ import { iPoolV310Abi } from "../../abi/310/generated.js";
3
3
  import { asPreviewSimulationError } from "./errors.js";
4
4
  //#region src/preview/simulate/simulatePoolOperation.ts
5
5
  function previewRead(operation) {
@@ -1,5 +1,5 @@
1
- import { iCreditFacadeV310Abi } from "../../abi/310/generated.js";
2
1
  import { ierc20Abi } from "../../abi/iERC20.js";
2
+ import { iCreditFacadeV310Abi } from "../../abi/310/generated.js";
3
3
  import { AddressMap } from "../../onchain/utils/AddressMap.js";
4
4
  import "../../onchain/index.js";
5
5
  import { UnexpectedFacadeEventOrderError } from "./errors.js";
@@ -71,7 +71,11 @@ function creditIssues(sdk, preview, options) {
71
71
  maxDebt: suite.creditFacade.maxDebt,
72
72
  underlying,
73
73
  allowZero: !isOpening
74
- }) || borrowIssue(suite, preview, underlying) || forbiddenIssue(suite, preview) || quotaCountIssue(suite, preview) || quotaIssue(market, preview, underlying) || collateralIssue(preview, options) || fundingIssue(options, preview.collateralAdded);
74
+ }) || borrowIssue(suite, preview, underlying) || forbiddenIssue(suite, preview) || quotaCountIssue(suite, preview) || quotaIssue(market, preview, underlying) || collateralIssue({
75
+ totalDebt: preview.totalDebt,
76
+ healthFactor: preview.estHealthFactor,
77
+ safeHealthFactor: preview.estSafeHealthFactor
78
+ }, options) || fundingIssue(options, preview.collateralAdded);
75
79
  }
76
80
  /**
77
81
  * A bar that reads nothing but the projected account, so a parsed transaction
@@ -82,9 +86,9 @@ function creditIssues(sdk, preview, options) {
82
86
  * need an operation's *delta* between them, and the caller acts on the first
83
87
  * issue reported.
84
88
  */
85
- function quotaCountIssue(suite, projection) {
89
+ function quotaCountIssue(suite, account) {
86
90
  return checkQuotaCount({
87
- count: projection.quotas.filter((q) => q.value > 0n).length,
91
+ count: account.quotas.filter((q) => q.value > 0n).length,
88
92
  max: suite.creditManager.maxEnabledTokens
89
93
  });
90
94
  }
@@ -118,16 +122,16 @@ function borrowIssue(suite, preview, underlying) {
118
122
  *
119
123
  * {@inheritDoc quotaCountIssue}
120
124
  */
121
- function collateralIssue(projection, options) {
125
+ function collateralIssue(account, options) {
122
126
  const { minHealthFactor, minSafeHealthFactor, currentHealthFactor } = options;
123
- if (projection.totalDebt.value === 0n) return null;
127
+ if (account.totalDebt.value === 0n) return null;
124
128
  return (minHealthFactor === void 0 ? null : checkCollateralised({
125
- healthFactor: projection.healthFactor,
129
+ healthFactor: account.healthFactor,
126
130
  required: minHealthFactor,
127
131
  safePrices: false,
128
132
  improvesFrom: currentHealthFactor
129
- })) || (minSafeHealthFactor === void 0 || projection.safeHealthFactor === void 0 ? null : checkCollateralised({
130
- healthFactor: projection.safeHealthFactor,
133
+ })) || (minSafeHealthFactor === void 0 ? null : checkCollateralised({
134
+ healthFactor: account.safeHealthFactor,
131
135
  required: minSafeHealthFactor,
132
136
  safePrices: true
133
137
  }));
@@ -147,7 +151,7 @@ function fundingIssue(options, puts) {
147
151
  return null;
148
152
  }
149
153
  function forbiddenIssue(suite, preview) {
150
- const obtained = preview.operation === "AdjustCreditAccount" ? preview.assetsChange : preview.assets;
154
+ const obtained = preview.operation === "AdjustCreditAccount" ? preview.assetsChange : preview.estAssets;
151
155
  const forbidden = suite.forbiddenTokens;
152
156
  for (const asset of obtained) {
153
157
  if (asset.value <= 0n) continue;