@gearbox-protocol/sdk 14.12.0-next.29 → 14.12.0-next.30

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 (39) hide show
  1. package/dist/cjs/preview/preview/CreditAccountState.js +154 -0
  2. package/dist/cjs/preview/preview/buildDelayedPreview.js +111 -0
  3. package/dist/cjs/preview/preview/detectDelayedOperation.js +71 -0
  4. package/dist/cjs/preview/preview/errors.js +17 -0
  5. package/dist/cjs/preview/preview/index.js +10 -4
  6. package/dist/cjs/preview/preview/previewAdjustCreditAccount.js +16 -39
  7. package/dist/cjs/preview/preview/previewCloseOrRepayCreditAccount.js +11 -37
  8. package/dist/cjs/preview/preview/previewOpenCreditAccount.js +13 -8
  9. package/dist/cjs/preview/preview/previewOperation.js +46 -5
  10. package/dist/cjs/preview/preview/{applyInnerOperations.js → replayInnerOperations.js} +24 -35
  11. package/dist/cjs/preview/preview/{applyQuotaChanges.js → replayMulticall.js} +14 -20
  12. package/dist/cjs/preview/preview/types.js +5 -2
  13. package/dist/esm/preview/preview/CreditAccountState.js +133 -0
  14. package/dist/esm/preview/preview/buildDelayedPreview.js +90 -0
  15. package/dist/esm/preview/preview/detectDelayedOperation.js +51 -0
  16. package/dist/esm/preview/preview/errors.js +16 -0
  17. package/dist/esm/preview/preview/index.js +5 -2
  18. package/dist/esm/preview/preview/previewAdjustCreditAccount.js +19 -48
  19. package/dist/esm/preview/preview/previewCloseOrRepayCreditAccount.js +14 -44
  20. package/dist/esm/preview/preview/previewOpenCreditAccount.js +15 -10
  21. package/dist/esm/preview/preview/previewOperation.js +52 -6
  22. package/dist/esm/preview/preview/{applyInnerOperations.js → replayInnerOperations.js} +20 -34
  23. package/dist/esm/preview/preview/replayMulticall.js +16 -0
  24. package/dist/esm/preview/preview/types.js +3 -1
  25. package/dist/types/preview/preview/CreditAccountState.d.ts +83 -0
  26. package/dist/types/preview/preview/buildDelayedPreview.d.ts +41 -0
  27. package/dist/types/preview/preview/detectDelayedOperation.d.ts +29 -0
  28. package/dist/types/preview/preview/errors.d.ts +15 -0
  29. package/dist/types/preview/preview/index.d.ts +5 -2
  30. package/dist/types/preview/preview/previewAdjustCreditAccount.d.ts +3 -3
  31. package/dist/types/preview/preview/previewCloseOrRepayCreditAccount.d.ts +2 -2
  32. package/dist/types/preview/preview/replayInnerOperations.d.ts +44 -0
  33. package/dist/types/preview/preview/replayMulticall.d.ts +38 -0
  34. package/dist/types/preview/preview/types.d.ts +58 -3
  35. package/dist/types/preview/types.d.ts +17 -6
  36. package/package.json +1 -1
  37. package/dist/esm/preview/preview/applyQuotaChanges.js +0 -19
  38. package/dist/types/preview/preview/applyInnerOperations.d.ts +0 -59
  39. package/dist/types/preview/preview/applyQuotaChanges.d.ts +0 -24
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var CreditAccountState_exports = {};
20
+ __export(CreditAccountState_exports, {
21
+ CreditAccountState: () => CreditAccountState
22
+ });
23
+ module.exports = __toCommonJS(CreditAccountState_exports);
24
+ var import_viem = require("viem");
25
+ var import_sdk = require("../../sdk/index.js");
26
+ class CreditAccountState {
27
+ creditAccount;
28
+ creditManager;
29
+ /**
30
+ * Credit manager underlying
31
+ */
32
+ underlying;
33
+ /**
34
+ * Per-token balances
35
+ */
36
+ balances;
37
+ /**
38
+ * Per-token quotas
39
+ */
40
+ quotas;
41
+ /**
42
+ * Debt principal
43
+ */
44
+ debt;
45
+ /**
46
+ * Total debt: principal + accrued interest + accrued fees.
47
+ * `decreaseDebt` amounts operate on total debt (interest and fees are
48
+ * repaid before principal), so principal alone is not enough to resolve
49
+ * either the underlying balance decrement or the final principal.
50
+ */
51
+ totalDebt;
52
+ constructor(props) {
53
+ this.creditAccount = props.creditAccount;
54
+ this.creditManager = props.creditManager;
55
+ this.underlying = props.underlying;
56
+ this.balances = props.balances ?? new import_sdk.AssetsMap();
57
+ this.quotas = props.quotas ?? new import_sdk.AssetsMap();
58
+ this.debt = props.debt ?? 0n;
59
+ this.totalDebt = props.totalDebt ?? 0n;
60
+ }
61
+ /**
62
+ * The account-opening seed: everything zero/empty. The account doesn't
63
+ * exist yet at preview time, so `creditAccount` is the zero address;
64
+ * opening previews take identity from the parsed operation instead.
65
+ */
66
+ static beforeOpen(creditManager, underlying) {
67
+ return new CreditAccountState({
68
+ creditAccount: import_viem.zeroAddress,
69
+ creditManager,
70
+ underlying
71
+ });
72
+ }
73
+ /**
74
+ * Pre-state of an existing account from its on-chain data, with dust
75
+ * balances and quotas (≤ 1 wei) filtered out.
76
+ */
77
+ static fromCreditAccountData(ca) {
78
+ const balances = new import_sdk.AssetsMap();
79
+ const quotas = new import_sdk.AssetsMap();
80
+ for (const t of ca.tokens) {
81
+ if (t.balance > 1n) {
82
+ balances.upsert(t.token, t.balance);
83
+ }
84
+ if (t.quota > 1n) {
85
+ quotas.upsert(t.token, t.quota);
86
+ }
87
+ }
88
+ return new CreditAccountState({
89
+ creditAccount: ca.creditAccount,
90
+ creditManager: ca.creditManager,
91
+ underlying: ca.underlying,
92
+ balances,
93
+ quotas,
94
+ debt: ca.debt,
95
+ totalDebt: ca.debt + ca.accruedInterest + ca.accruedFees
96
+ });
97
+ }
98
+ clone() {
99
+ return new CreditAccountState({
100
+ creditAccount: this.creditAccount,
101
+ creditManager: this.creditManager,
102
+ underlying: this.underlying,
103
+ balances: this.balances.clone(),
104
+ quotas: this.quotas.clone(),
105
+ debt: this.debt,
106
+ totalDebt: this.totalDebt
107
+ });
108
+ }
109
+ /**
110
+ * Borrows `amount` of underlying: debt, total debt and the underlying
111
+ * balance all increase by it.
112
+ */
113
+ increaseDebt(amount) {
114
+ this.debt += amount;
115
+ this.totalDebt += amount;
116
+ this.balances.inc(this.underlying, amount);
117
+ }
118
+ /**
119
+ * Repays up to `amount` of underlying against the debt, clamped to the
120
+ * total debt (the facade never repays more than is owed). Interest and
121
+ * fees are repaid before principal (CreditLogic.calcDecrease), so
122
+ * principal only decreases once total debt drops below it. The underlying
123
+ * balance decreases by the repaid amount.
124
+ *
125
+ * @returns The actually repaid (post-clamp) amount.
126
+ */
127
+ repay(amount) {
128
+ const repaid = amount > this.totalDebt ? this.totalDebt : amount;
129
+ this.balances.dec(this.underlying, repaid);
130
+ this.totalDebt -= repaid;
131
+ if (this.debt > this.totalDebt) {
132
+ this.debt = this.totalDebt;
133
+ }
134
+ return repaid;
135
+ }
136
+ /**
137
+ * Applies a relative `updateQuota` change to the token's quota:
138
+ * `MIN_INT96` is the facade "disable quota" sentinel and zeroes it, other
139
+ * changes are added with the result clamped at zero (quotas cannot go
140
+ * negative on-chain).
141
+ */
142
+ updateQuota(token, change) {
143
+ if (change === import_sdk.MIN_INT96) {
144
+ this.quotas.upsert(token, 0n);
145
+ return;
146
+ }
147
+ const next = this.quotas.getOrZero(token) + change;
148
+ this.quotas.upsert(token, next > 0n ? next : 0n);
149
+ }
150
+ }
151
+ // Annotate the CommonJS export names for ESM import in node:
152
+ 0 && (module.exports = {
153
+ CreditAccountState
154
+ });
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var buildDelayedPreview_exports = {};
20
+ __export(buildDelayedPreview_exports, {
21
+ buildDelayedPreview: () => buildDelayedPreview
22
+ });
23
+ module.exports = __toCommonJS(buildDelayedPreview_exports);
24
+ var import_viem = require("viem");
25
+ var import_sdk = require("../../sdk/index.js");
26
+ var import_types = require("./types.js");
27
+ function buildDelayedPreview(state, before, detected, convert) {
28
+ const { request, intent } = detected;
29
+ const post = state.clone();
30
+ let error;
31
+ const safeConvert = (token, to, amount) => {
32
+ try {
33
+ return convert(token, to, amount);
34
+ } catch {
35
+ error ??= {
36
+ code: import_types.ERROR_UNPRICEABLE_TOKEN,
37
+ message: `cannot price token ${token}`
38
+ };
39
+ return 0n;
40
+ }
41
+ };
42
+ const claimed = post.balances.getOrZero(request.phantomToken);
43
+ post.balances.upsert(request.phantomToken, 0n);
44
+ post.quotas.upsert(request.phantomToken, 0n);
45
+ post.balances.inc(request.claimToken, claimed);
46
+ if (intent?.type === "CLOSE_ACCOUNT") {
47
+ const totalValue2 = post.balances.sum(
48
+ (token, balance) => balance > 0n ? safeConvert(token, post.underlying, balance) : 0n
49
+ );
50
+ const receivedAmount = totalValue2 > post.totalDebt ? totalValue2 - post.totalDebt : 0n;
51
+ const preview2 = {
52
+ operation: "CloseCreditAccount",
53
+ permanent: true,
54
+ creditManager: post.creditManager,
55
+ creditAccount: post.creditAccount,
56
+ receivedAmount,
57
+ error
58
+ };
59
+ return preview2;
60
+ }
61
+ const collateralWithdrawn = new import_sdk.AssetsMap();
62
+ const repayFromClaim = (amount) => {
63
+ const available = post.balances.getOrZero(request.claimToken);
64
+ const spent = amount > available ? available : amount;
65
+ if (spent <= 0n) {
66
+ return;
67
+ }
68
+ const received = safeConvert(request.claimToken, post.underlying, spent);
69
+ post.balances.dec(request.claimToken, spent);
70
+ post.balances.inc(post.underlying, received);
71
+ post.repay(received);
72
+ };
73
+ if (intent?.type === "DECREASE_LEVERAGE") {
74
+ repayFromClaim(claimed);
75
+ } else if (intent?.type === "WITHDRAW_COLLATERAL") {
76
+ const running = post.balances.getOrZero(intent.withdrawToken);
77
+ const withdrawn = intent.withdrawAmount > running ? running : intent.withdrawAmount;
78
+ if (withdrawn > 0n) {
79
+ post.balances.dec(intent.withdrawToken, withdrawn);
80
+ collateralWithdrawn.upsert(intent.withdrawToken, withdrawn);
81
+ }
82
+ const remainingClaim = (0, import_viem.isAddressEqual)(intent.withdrawToken, request.claimToken) && claimed > withdrawn ? claimed - withdrawn : claimed;
83
+ repayFromClaim(remainingClaim);
84
+ }
85
+ const totalValue = post.balances.sum(
86
+ (token, balance) => balance > import_types.PREVIEW_DUST ? safeConvert(token, post.underlying, balance) : 0n
87
+ );
88
+ const preview = {
89
+ operation: "AdjustCreditAccount",
90
+ creditManager: post.creditManager,
91
+ creditAccount: post.creditAccount,
92
+ // the resume flow adds nothing from the wallet
93
+ collateralAdded: [],
94
+ collateralWithdrawn: collateralWithdrawn.toAssets(),
95
+ totalValue,
96
+ debt: post.debt,
97
+ // relative to the pre-transaction state: where the account will end up
98
+ // compared to now, once the withdrawal is claimed and the intent resumed
99
+ debtChange: post.debt - before.debt,
100
+ quotas: post.quotas.toAssets(0n),
101
+ quotasChange: post.quotas.difference(before.quotas).toAssets(),
102
+ assets: post.balances.toAssets(import_types.PREVIEW_DUST),
103
+ assetsChange: post.balances.difference(before.balances).toAssets(import_types.PREVIEW_DUST),
104
+ error
105
+ };
106
+ return preview;
107
+ }
108
+ // Annotate the CommonJS export names for ESM import in node:
109
+ 0 && (module.exports = {
110
+ buildDelayedPreview
111
+ });
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var detectDelayedOperation_exports = {};
20
+ __export(detectDelayedOperation_exports, {
21
+ detectDelayedOperation: () => detectDelayedOperation
22
+ });
23
+ module.exports = __toCommonJS(detectDelayedOperation_exports);
24
+ var import_viem = require("viem");
25
+ var import_adapters = require("../../plugins/adapters/index.js");
26
+ var import_sdk = require("../../sdk/index.js");
27
+ var import_errors = require("./errors.js");
28
+ function detectDelayedOperation(sdk, multicall) {
29
+ let bracketDeltas = [];
30
+ for (const op of multicall) {
31
+ if (op.operation === "StoreExpectedBalances") {
32
+ bracketDeltas = op.deltas;
33
+ continue;
34
+ }
35
+ if (op.operation === "CompareBalances") {
36
+ bracketDeltas = [];
37
+ continue;
38
+ }
39
+ if (op.operation !== "Execute") {
40
+ continue;
41
+ }
42
+ const adapter = sdk.getContract(op.adapter);
43
+ if (!(adapter instanceof import_adapters.AbstractAdapterContract)) {
44
+ continue;
45
+ }
46
+ const request = adapter.parseDelayedWithdrawalRequest(op.calldata);
47
+ if (!request) {
48
+ continue;
49
+ }
50
+ const mintsPhantom = bracketDeltas.some(
51
+ ({ token, balance }) => balance > 0n && (0, import_viem.isAddressEqual)(token, request.phantomToken)
52
+ );
53
+ if (!mintsPhantom) {
54
+ continue;
55
+ }
56
+ let intent;
57
+ if (request.extraData && request.extraData !== "0x") {
58
+ try {
59
+ intent = (0, import_sdk.decodeDelayedIntent)(request.extraData);
60
+ } catch (e) {
61
+ throw new import_errors.InvalidDelayedIntentError(op.adapter, request.extraData, e);
62
+ }
63
+ }
64
+ return { request, intent };
65
+ }
66
+ return void 0;
67
+ }
68
+ // Annotate the CommonJS export names for ESM import in node:
69
+ 0 && (module.exports = {
70
+ detectDelayedOperation
71
+ });
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var errors_exports = {};
20
20
  __export(errors_exports, {
21
+ InvalidDelayedIntentError: () => InvalidDelayedIntentError,
21
22
  UnsupportedOperationError: () => UnsupportedOperationError
22
23
  });
23
24
  module.exports = __toCommonJS(errors_exports);
@@ -30,7 +31,23 @@ class UnsupportedOperationError extends Error {
30
31
  this.operation = operation;
31
32
  }
32
33
  }
34
+ class InvalidDelayedIntentError extends Error {
35
+ /** Adapter the withdrawal request was addressed to. */
36
+ adapter;
37
+ /** Raw `extraData` that failed to decode. */
38
+ extraData;
39
+ constructor(adapter, extraData, cause) {
40
+ super(
41
+ `cannot decode delayed intent from extraData ${extraData} of withdrawal request to adapter ${adapter}`,
42
+ { cause }
43
+ );
44
+ this.name = "InvalidDelayedIntentError";
45
+ this.adapter = adapter;
46
+ this.extraData = extraData;
47
+ }
48
+ }
33
49
  // Annotate the CommonJS export names for ESM import in node:
34
50
  0 && (module.exports = {
51
+ InvalidDelayedIntentError,
35
52
  UnsupportedOperationError
36
53
  });
@@ -15,22 +15,28 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
15
15
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
16
  var preview_exports = {};
17
17
  module.exports = __toCommonJS(preview_exports);
18
- __reExport(preview_exports, require("./applyInnerOperations.js"), module.exports);
19
- __reExport(preview_exports, require("./applyQuotaChanges.js"), module.exports);
18
+ __reExport(preview_exports, require("./buildDelayedPreview.js"), module.exports);
19
+ __reExport(preview_exports, require("./CreditAccountState.js"), module.exports);
20
20
  __reExport(preview_exports, require("./detectCloseOrRepay.js"), module.exports);
21
+ __reExport(preview_exports, require("./detectDelayedOperation.js"), module.exports);
21
22
  __reExport(preview_exports, require("./errors.js"), module.exports);
22
23
  __reExport(preview_exports, require("./previewAdjustCreditAccount.js"), module.exports);
23
24
  __reExport(preview_exports, require("./previewCloseOrRepayCreditAccount.js"), module.exports);
24
25
  __reExport(preview_exports, require("./previewOperation.js"), module.exports);
26
+ __reExport(preview_exports, require("./replayInnerOperations.js"), module.exports);
27
+ __reExport(preview_exports, require("./replayMulticall.js"), module.exports);
25
28
  __reExport(preview_exports, require("./types.js"), module.exports);
26
29
  // Annotate the CommonJS export names for ESM import in node:
27
30
  0 && (module.exports = {
28
- ...require("./applyInnerOperations.js"),
29
- ...require("./applyQuotaChanges.js"),
31
+ ...require("./buildDelayedPreview.js"),
32
+ ...require("./CreditAccountState.js"),
30
33
  ...require("./detectCloseOrRepay.js"),
34
+ ...require("./detectDelayedOperation.js"),
31
35
  ...require("./errors.js"),
32
36
  ...require("./previewAdjustCreditAccount.js"),
33
37
  ...require("./previewCloseOrRepayCreditAccount.js"),
34
38
  ...require("./previewOperation.js"),
39
+ ...require("./replayInnerOperations.js"),
40
+ ...require("./replayMulticall.js"),
35
41
  ...require("./types.js")
36
42
  });
@@ -22,8 +22,7 @@ __export(previewAdjustCreditAccount_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(previewAdjustCreditAccount_exports);
24
24
  var import_sdk = require("../../sdk/index.js");
25
- var import_applyInnerOperations = require("./applyInnerOperations.js");
26
- var import_applyQuotaChanges = require("./applyQuotaChanges.js");
25
+ var import_replayMulticall = require("./replayMulticall.js");
27
26
  var import_types = require("./types.js");
28
27
  var import_unwrapNativeCollateral = require("./unwrapNativeCollateral.js");
29
28
  async function previewAdjustCreditAccount(input, operation, options) {
@@ -31,43 +30,21 @@ async function previewAdjustCreditAccount(input, operation, options) {
31
30
  const market = sdk.marketRegister.findByCreditManager(
32
31
  operation.creditManager
33
32
  );
34
- let ca = options?.creditAccount;
35
- if (!ca) {
36
- ca = await sdk.accounts.getCreditAccountData(
37
- operation.creditAccount,
38
- options?.blockNumber
39
- );
40
- }
41
- if (!ca) {
42
- throw new Error(`credit account ${operation.creditAccount} not found`);
43
- }
44
- const initialBalances = new import_sdk.AssetsMap();
45
- const initialQuotas = new import_sdk.AssetsMap();
46
- for (const t of ca.tokens) {
47
- if (t.balance > 1n) {
48
- initialBalances.upsert(t.token, t.balance);
49
- }
50
- if (t.quota > 1n) {
51
- initialQuotas.upsert(t.token, t.quota);
52
- }
53
- }
54
- const state = (0, import_applyInnerOperations.makeInnerOperationsState)();
55
- state.balances = initialBalances.clone();
56
- state.debt = ca.debt;
57
- state.totalDebt = ca.debt + ca.accruedInterest + ca.accruedFees;
58
- let error = await (0, import_applyInnerOperations.applyInnerOperations)(sdk, operation.multicall, state);
33
+ const {
34
+ before,
35
+ after,
36
+ error: replayError
37
+ } = await (0, import_replayMulticall.replayMulticall)(sdk, operation, options);
38
+ const account = after.account;
39
+ let error = replayError;
59
40
  const { assets: collateralAdded, error: unwrapError } = (0, import_unwrapNativeCollateral.unwrapNativeCollateral)(
60
- state.collateralAdded.toAssets(),
41
+ after.collateralAdded.toAssets(),
61
42
  value,
62
43
  sdk.addressProvider.getAddress(import_sdk.AP_WETH_TOKEN, import_sdk.NO_VERSION)
63
44
  );
64
45
  error ??= unwrapError;
65
- const { quotas, quotasChange } = (0, import_applyQuotaChanges.applyQuotaChanges)(
66
- initialQuotas,
67
- state.quotaChanges
68
- );
69
- const assets = state.balances.toAssets(1n);
70
- const assetsChange = state.balances.difference(initialBalances).toAssets(1n);
46
+ const assets = account.balances.toAssets(import_types.PREVIEW_DUST);
47
+ const assetsChange = account.balances.difference(before.balances).toAssets(import_types.PREVIEW_DUST);
71
48
  const totalValue = assets.reduce((acc, { token, balance }) => {
72
49
  try {
73
50
  return acc + market.priceOracle.convert(token, market.underlying, balance);
@@ -84,12 +61,12 @@ async function previewAdjustCreditAccount(input, operation, options) {
84
61
  creditManager: operation.creditManager,
85
62
  creditAccount: operation.creditAccount,
86
63
  collateralAdded,
87
- collateralWithdrawn: state.collateralWithdrawn.toAssets(),
64
+ collateralWithdrawn: after.collateralWithdrawn.toAssets(),
88
65
  totalValue,
89
- debt: state.debt,
90
- debtChange: state.debt - ca.debt,
91
- quotas,
92
- quotasChange,
66
+ debt: account.debt,
67
+ debtChange: account.debt - before.debt,
68
+ quotas: account.quotas.toAssets(0n),
69
+ quotasChange: account.quotas.difference(before.quotas).toAssets(),
93
70
  assets,
94
71
  assetsChange,
95
72
  error
@@ -22,23 +22,24 @@ __export(previewCloseOrRepayCreditAccount_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(previewCloseOrRepayCreditAccount_exports);
24
24
  var import_sdk = require("../../sdk/index.js");
25
- var import_applyInnerOperations = require("./applyInnerOperations.js");
26
25
  var import_detectCloseOrRepay = require("./detectCloseOrRepay.js");
26
+ var import_replayMulticall = require("./replayMulticall.js");
27
27
  var import_unwrapNativeCollateral = require("./unwrapNativeCollateral.js");
28
28
  async function previewCloseOrRepayCreditAccount(input, operation, permanent, options) {
29
29
  const { sdk } = input;
30
30
  const market = sdk.marketRegister.findByCreditManager(
31
31
  operation.creditManager
32
32
  );
33
+ const replay = await (0, import_replayMulticall.replayMulticall)(sdk, operation, options);
33
34
  const kind = (0, import_detectCloseOrRepay.classifyCloseOrRepay)(operation.multicall, market.underlying);
34
- return kind === "close" ? previewCloseCreditAccount(input, operation, permanent, options) : previewRepayCreditAccount(input, operation, permanent, options);
35
+ return kind === "close" ? previewCloseCreditAccount(input, operation, permanent, replay) : previewRepayCreditAccount(input, operation, permanent, replay);
35
36
  }
36
- async function previewCloseCreditAccount(input, operation, permanent, options) {
37
+ function previewCloseCreditAccount(input, operation, permanent, replay) {
37
38
  const { sdk } = input;
38
39
  const market = sdk.marketRegister.findByCreditManager(
39
40
  operation.creditManager
40
41
  );
41
- const { state, error } = await replayMulticall(sdk, operation, options);
42
+ const { after, error } = replay;
42
43
  return {
43
44
  operation: "CloseCreditAccount",
44
45
  permanent,
@@ -46,59 +47,32 @@ async function previewCloseCreditAccount(input, operation, permanent, options) {
46
47
  creditAccount: operation.creditAccount,
47
48
  // On a malformed multicall the withdrawn amount depends on best-effort
48
49
  // replayed balances and may be unreliable
49
- receivedAmount: state.collateralWithdrawn.getOrZero(market.underlying),
50
+ receivedAmount: after.collateralWithdrawn.getOrZero(market.underlying),
50
51
  error
51
52
  };
52
53
  }
53
- async function previewRepayCreditAccount(input, operation, permanent, options) {
54
+ function previewRepayCreditAccount(input, operation, permanent, replay) {
54
55
  const { sdk, value = 0n } = input;
55
- const {
56
- ca,
57
- state,
58
- error: replayError
59
- } = await replayMulticall(sdk, operation, options);
56
+ const { before, after, error: replayError } = replay;
60
57
  const { assets: collateralAdded, error: unwrapError } = (0, import_unwrapNativeCollateral.unwrapNativeCollateral)(
61
- state.collateralAdded.toAssets(),
58
+ after.collateralAdded.toAssets(),
62
59
  value,
63
60
  sdk.addressProvider.getAddress(import_sdk.AP_WETH_TOKEN, import_sdk.NO_VERSION)
64
61
  );
65
62
  const error = replayError ?? unwrapError;
66
- const initialTotalDebt = ca.debt + ca.accruedInterest + ca.accruedFees;
67
63
  return {
68
64
  operation: "RepayCreditAccount",
69
65
  permanent,
70
66
  creditManager: operation.creditManager,
71
67
  creditAccount: operation.creditAccount,
72
68
  collateralAdded,
73
- debtRepaid: initialTotalDebt - state.totalDebt,
69
+ debtRepaid: before.totalDebt - after.account.totalDebt,
74
70
  // On a malformed multicall the MAX_UINT256 withdrawal sentinel resolves
75
71
  // against best-effort replayed balances and may be unreliable
76
- collateralWithdrawn: state.collateralWithdrawn.toAssets(),
72
+ collateralWithdrawn: after.collateralWithdrawn.toAssets(),
77
73
  error
78
74
  };
79
75
  }
80
- async function replayMulticall(sdk, operation, options) {
81
- let ca = options?.creditAccount;
82
- if (!ca) {
83
- ca = await sdk.accounts.getCreditAccountData(
84
- operation.creditAccount,
85
- options?.blockNumber
86
- );
87
- }
88
- if (!ca) {
89
- throw new Error(`credit account ${operation.creditAccount} not found`);
90
- }
91
- const state = (0, import_applyInnerOperations.makeInnerOperationsState)();
92
- for (const t of ca.tokens) {
93
- if (t.balance > 1n) {
94
- state.balances.upsert(t.token, t.balance);
95
- }
96
- }
97
- state.debt = ca.debt;
98
- state.totalDebt = ca.debt + ca.accruedInterest + ca.accruedFees;
99
- const error = await (0, import_applyInnerOperations.applyInnerOperations)(sdk, operation.multicall, state);
100
- return { ca, state, error };
101
- }
102
76
  // Annotate the CommonJS export names for ESM import in node:
103
77
  0 && (module.exports = {
104
78
  previewCloseOrRepayCreditAccount
@@ -22,7 +22,8 @@ __export(previewOpenCreditAccount_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(previewOpenCreditAccount_exports);
24
24
  var import_sdk = require("../../sdk/index.js");
25
- var import_applyInnerOperations = require("./applyInnerOperations.js");
25
+ var import_CreditAccountState = require("./CreditAccountState.js");
26
+ var import_replayInnerOperations = require("./replayInnerOperations.js");
26
27
  var import_types = require("./types.js");
27
28
  var import_unwrapNativeCollateral = require("./unwrapNativeCollateral.js");
28
29
  async function previewOpenCreditAccount(input, operation) {
@@ -30,8 +31,11 @@ async function previewOpenCreditAccount(input, operation) {
30
31
  const market = sdk.marketRegister.findByCreditManager(
31
32
  operation.creditManager
32
33
  );
33
- const state = (0, import_applyInnerOperations.makeInnerOperationsState)();
34
- let error = await (0, import_applyInnerOperations.applyInnerOperations)(sdk, operation.multicall, state);
34
+ const state = (0, import_replayInnerOperations.makeReplayState)(
35
+ import_CreditAccountState.CreditAccountState.beforeOpen(operation.creditManager, market.underlying)
36
+ );
37
+ let error = await (0, import_replayInnerOperations.replayInnerOperations)(sdk, operation.multicall, state);
38
+ const account = state.account;
35
39
  let priceError;
36
40
  const collateralValue = state.collateralAdded.sum((token, balance) => {
37
41
  try {
@@ -50,16 +54,17 @@ async function previewOpenCreditAccount(input, operation) {
50
54
  sdk.addressProvider.getAddress(import_sdk.AP_WETH_TOKEN, import_sdk.NO_VERSION)
51
55
  );
52
56
  error ??= unwrapError ?? priceError;
53
- const assets = state.balances.toAssets(1n);
57
+ const assets = account.balances.toAssets(1n);
54
58
  return {
55
59
  operation: operation.operation,
56
60
  creditManager: operation.creditManager,
57
- target: inferTargetAsset(operation.multicall, state.balances),
61
+ target: inferTargetAsset(operation.multicall, account.balances),
58
62
  collateral,
59
63
  collateralValue,
60
- debt: state.debt,
61
- // On opening, initial quotas are zero, so the raw changes are the quotas.
62
- quotas: state.quotaChanges,
64
+ debt: account.debt,
65
+ // On opening, initial quotas are zero, so the folded quotas are the
66
+ // applied changes.
67
+ quotas: account.quotas.toAssets(0n),
63
68
  assets,
64
69
  error
65
70
  };