@gearbox-protocol/sdk 14.11.0-next.3 → 14.11.0-next.5

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 (105) hide show
  1. package/dist/cjs/common-utils/utils/index.js +2 -0
  2. package/dist/cjs/{history/trace-utils.js → common-utils/utils/trace.js} +62 -5
  3. package/dist/cjs/history/assembleOperations.js +6 -6
  4. package/dist/cjs/history/classifyMulticallOperations.js +31 -25
  5. package/dist/cjs/history/index.js +0 -2
  6. package/dist/cjs/history/parseCreditAccountTransaction.js +5 -6
  7. package/dist/cjs/history/toLegacyOperation.js +5 -1
  8. package/dist/cjs/plugins/adapters/contracts/AbstractAdapter.js +25 -37
  9. package/dist/cjs/plugins/adapters/contracts/AccountMigratorAdapterContract.js +9 -0
  10. package/dist/cjs/{history/internal-types.js → plugins/adapters/transfers.js} +2 -2
  11. package/dist/cjs/preview/index.js +3 -1
  12. package/dist/cjs/preview/parse/classifyInnerOperations.js +5 -43
  13. package/dist/cjs/preview/parse/parseFacadeOperationCalldata.js +1 -4
  14. package/dist/cjs/{history/inner-operations.js → preview/parse/types-adapters.js} +2 -2
  15. package/dist/cjs/preview/parse/types-facades.js +16 -0
  16. package/dist/cjs/preview/parse/types-pools.js +16 -0
  17. package/dist/cjs/preview/parse/types.js +8 -1
  18. package/dist/cjs/preview/prerequisites/index.js +2 -0
  19. package/dist/cjs/preview/prerequisites/prepareAction.js +48 -0
  20. package/dist/cjs/{history → preview/trace}/errors.js +0 -26
  21. package/dist/cjs/preview/trace/extractAdapterCallTraces.js +58 -0
  22. package/dist/cjs/{history → preview/trace}/extractTransfers.js +10 -13
  23. package/dist/cjs/{history → preview/trace}/findFacadeCalls.js +3 -3
  24. package/dist/cjs/preview/trace/index.js +30 -0
  25. package/dist/cjs/preview/trace/types.js +16 -0
  26. package/dist/esm/common-utils/utils/index.js +1 -0
  27. package/dist/esm/common-utils/utils/trace.js +93 -0
  28. package/dist/esm/history/assembleOperations.js +8 -6
  29. package/dist/esm/history/classifyMulticallOperations.js +29 -23
  30. package/dist/esm/history/index.js +0 -1
  31. package/dist/esm/history/parseCreditAccountTransaction.js +3 -4
  32. package/dist/esm/history/toLegacyOperation.js +5 -1
  33. package/dist/esm/plugins/adapters/contracts/AbstractAdapter.js +28 -38
  34. package/dist/esm/plugins/adapters/contracts/AccountMigratorAdapterContract.js +9 -0
  35. package/dist/esm/preview/index.js +1 -0
  36. package/dist/esm/preview/parse/classifyInnerOperations.js +6 -46
  37. package/dist/esm/preview/parse/parseFacadeOperationCalldata.js +2 -9
  38. package/dist/esm/preview/parse/types-facades.js +0 -0
  39. package/dist/esm/preview/parse/types-pools.js +0 -0
  40. package/dist/esm/preview/parse/types.js +3 -0
  41. package/dist/esm/preview/prerequisites/index.js +1 -0
  42. package/dist/esm/preview/prerequisites/prepareAction.js +23 -0
  43. package/dist/esm/{history → preview/trace}/errors.js +0 -24
  44. package/dist/esm/preview/trace/extractAdapterCallTraces.js +40 -0
  45. package/dist/esm/{history → preview/trace}/extractTransfers.js +10 -13
  46. package/dist/esm/{history → preview/trace}/findFacadeCalls.js +4 -2
  47. package/dist/esm/preview/trace/index.js +5 -0
  48. package/dist/esm/preview/trace/types.js +0 -0
  49. package/dist/types/common-utils/utils/index.d.ts +1 -0
  50. package/dist/types/common-utils/utils/trace.d.ts +73 -0
  51. package/dist/types/history/assembleOperations.d.ts +11 -6
  52. package/dist/types/history/classifyMulticallOperations.d.ts +21 -9
  53. package/dist/types/history/index.d.ts +0 -1
  54. package/dist/types/history/mapOperations.d.ts +7 -9
  55. package/dist/types/history/types.d.ts +22 -65
  56. package/dist/types/plugins/adapters/contracts/AbstractAdapter.d.ts +16 -17
  57. package/dist/types/plugins/adapters/contracts/AccountMigratorAdapterContract.d.ts +10 -1
  58. package/dist/types/plugins/adapters/contracts/ConvexV1BaseRewardPoolAdapterContract.d.ts +1 -1
  59. package/dist/types/plugins/adapters/contracts/ConvexV1BoosterAdapterContract.d.ts +1 -1
  60. package/dist/types/plugins/adapters/contracts/Curve2AssetsAdapterContract.d.ts +1 -1
  61. package/dist/types/plugins/adapters/contracts/Curve3AssetsAdapterContract.d.ts +1 -1
  62. package/dist/types/plugins/adapters/contracts/Curve4AssetsAdapterContract.d.ts +1 -1
  63. package/dist/types/plugins/adapters/contracts/CurveV1AdapterDeposit.d.ts +1 -1
  64. package/dist/types/plugins/adapters/contracts/CurveV1AdapterStETHContract.d.ts +1 -1
  65. package/dist/types/plugins/adapters/contracts/CurveV1StableNGAdapterContract.d.ts +1 -1
  66. package/dist/types/plugins/adapters/contracts/DaiUsdsAdapterContract.d.ts +1 -1
  67. package/dist/types/plugins/adapters/contracts/ERC4626AdapterContract.d.ts +1 -1
  68. package/dist/types/plugins/adapters/contracts/ERC4626ReferralAdapterContract.d.ts +1 -1
  69. package/dist/types/plugins/adapters/contracts/LidoV1AdapterContract.d.ts +1 -1
  70. package/dist/types/plugins/adapters/contracts/MellowDVVAdapterContract.d.ts +1 -1
  71. package/dist/types/plugins/adapters/contracts/MellowERC4626VaultAdapterContract.d.ts +1 -1
  72. package/dist/types/plugins/adapters/contracts/UniswapV2AdapterContract.d.ts +1 -1
  73. package/dist/types/plugins/adapters/contracts/UniswapV4AdapterContract.d.ts +1 -1
  74. package/dist/types/plugins/adapters/contracts/WstETHV1AdapterContract.d.ts +1 -1
  75. package/dist/types/plugins/adapters/transferHelpers.d.ts +1 -1
  76. package/dist/types/plugins/adapters/transfers.d.ts +17 -0
  77. package/dist/types/plugins/adapters/types.d.ts +8 -46
  78. package/dist/types/preview/index.d.ts +1 -0
  79. package/dist/types/preview/parse/classifyInnerOperations.d.ts +8 -8
  80. package/dist/types/preview/parse/parseFacadeOperationCalldata.d.ts +4 -3
  81. package/dist/types/preview/parse/types-adapters.d.ts +69 -0
  82. package/dist/types/preview/parse/types-facades.d.ts +124 -0
  83. package/dist/types/preview/parse/types-pools.d.ts +42 -0
  84. package/dist/types/preview/parse/types.d.ts +12 -46
  85. package/dist/types/preview/prerequisites/index.d.ts +1 -0
  86. package/dist/types/preview/prerequisites/prepareAction.d.ts +52 -0
  87. package/dist/types/preview/simulate/extractERC20Transfers.d.ts +1 -1
  88. package/dist/types/preview/simulate/simulateFacadeOperation.d.ts +1 -1
  89. package/dist/types/preview/simulate/types.d.ts +1 -1
  90. package/dist/types/{history → preview/trace}/errors.d.ts +0 -10
  91. package/dist/types/preview/trace/extractAdapterCallTraces.d.ts +23 -0
  92. package/dist/types/{history → preview/trace}/extractTransfers.d.ts +14 -5
  93. package/dist/types/{history → preview/trace}/findFacadeCalls.d.ts +3 -2
  94. package/dist/types/preview/trace/index.d.ts +5 -0
  95. package/dist/types/preview/trace/types.d.ts +21 -0
  96. package/package.json +1 -1
  97. package/dist/cjs/history/extractProtocolCalls.js +0 -53
  98. package/dist/esm/history/extractProtocolCalls.js +0 -32
  99. package/dist/esm/history/trace-utils.js +0 -36
  100. package/dist/types/history/extractProtocolCalls.d.ts +0 -8
  101. package/dist/types/history/inner-operations.d.ts +0 -57
  102. package/dist/types/history/internal-types.d.ts +0 -47
  103. package/dist/types/history/trace-utils.d.ts +0 -12
  104. /package/dist/esm/{history/inner-operations.js → plugins/adapters/transfers.js} +0 -0
  105. /package/dist/esm/{history/internal-types.js → preview/parse/types-adapters.js} +0 -0
@@ -3,13 +3,16 @@ import {
3
3
  decodeFunctionData,
4
4
  zeroAddress
5
5
  } from "viem";
6
+ import {
7
+ resolveProtocolCall
8
+ } from "../../../common-utils/utils/trace.js";
6
9
  import {
7
10
  BaseContract,
8
11
  functionArgsToRecord,
9
12
  getFunctionSignature,
10
13
  MissingSerializedParamsError
11
14
  } from "../../../sdk/index.js";
12
- import { swapFromTransfers, toNetTransfers } from "../transferHelpers.js";
15
+ import { swapFromTransfers } from "../transferHelpers.js";
13
16
  class AbstractAdapterContract extends BaseContract {
14
17
  #targetContract;
15
18
  #creditManager;
@@ -50,45 +53,33 @@ class AbstractAdapterContract extends BaseContract {
50
53
  };
51
54
  }
52
55
  /**
53
- * Builds an {@link AdapterOperation} from a parsed call and ordered transfer entries.
56
+ * Decodes the protocol-level call (target contract + function name + args)
57
+ * performed by this adapter, recovered from its adapter-level call trace.
54
58
  *
55
- * Returns `PartialBy<AdapterOperation, "targetContract">` because the adapter
56
- * may not have `targetContract` (adapters created without SDK do not have serializedParams)
59
+ * Both the `targetContract` and the protocol calldata are taken from the
60
+ * execution trace.
57
61
  *
58
- * @param protocolCalldata Raw calldata of the actual CALL to targetContract, extracted from trace
59
- * @param strict When true, throws if protocol ABI is missing or decode fails
60
- */
61
- parseAdapterOperation(parsed, transfers, creditAccount, protocolCalldata, strict) {
62
- const netTransfers = toNetTransfers(transfers, creditAccount);
63
- const protocol = this.parseProtocolCall(protocolCalldata, strict);
64
- return {
65
- operation: "Execute",
66
- adapter: this.address,
67
- protocol: this.#targetContract,
68
- adapterType: this.adapterType,
69
- version: this.version,
70
- label: parsed.label,
71
- adapterFunctionName: parsed.functionName,
72
- adapterArgs: parsed.rawArgs,
73
- ...protocol,
74
- transfers,
75
- legacy: this.classifyLegacyOperation(parsed, netTransfers)
76
- };
77
- }
78
- /**
79
- * Decodes protocol-level function name and args from the raw calldata
80
- * sent to targetContract.
62
+ * Returns `undefined` (in non-strict mode) when no external protocol call can
63
+ * be recovered, in strict mode throws instead.
64
+ *
65
+ * @param trace Adapter-level call trace (a direct child of the facade trace)
66
+ * @param strict When true, throws instead of returning `undefined`
81
67
  */
82
- parseProtocolCall(calldata, strict) {
68
+ parseProtocolCall(trace, strict) {
69
+ const resolved = resolveProtocolCall(trace);
70
+ if (!resolved) {
71
+ if (strict) {
72
+ throw new Error("no external protocol call found in adapter trace");
73
+ }
74
+ return void 0;
75
+ }
76
+ const { contract, calldata } = resolved;
83
77
  const selector = calldata.slice(0, 10);
84
78
  if (this.protocolAbi.length === 0) {
85
79
  if (strict) {
86
80
  throw new Error(`Protocol ABI is missing for selector ${selector}`);
87
81
  }
88
- return {
89
- protocolFunctionName: `unknown function ${selector}`,
90
- protocolArgs: {}
91
- };
82
+ return void 0;
92
83
  }
93
84
  try {
94
85
  const decoded = decodeFunctionData({
@@ -96,12 +87,12 @@ class AbstractAdapterContract extends BaseContract {
96
87
  data: calldata
97
88
  });
98
89
  const functionName = getFunctionSignature(this.protocolAbi, calldata);
99
- const protocolArgs = functionArgsToRecord(
90
+ const functionArgs = functionArgsToRecord(
100
91
  this.protocolAbi,
101
92
  decoded.functionName,
102
93
  decoded.args
103
94
  );
104
- return { protocolFunctionName: functionName, protocolArgs };
95
+ return { contract, functionName, functionArgs };
105
96
  } catch (e) {
106
97
  if (strict) {
107
98
  throw new Error(
@@ -109,10 +100,7 @@ class AbstractAdapterContract extends BaseContract {
109
100
  { cause: e }
110
101
  );
111
102
  }
112
- return {
113
- protocolFunctionName: `unknown function ${selector}`,
114
- protocolArgs: {}
115
- };
103
+ return void 0;
116
104
  }
117
105
  }
118
106
  /**
@@ -126,6 +114,8 @@ class AbstractAdapterContract extends BaseContract {
126
114
  * Override in protocol-specific subclasses for richer classification.
127
115
  *
128
116
  * @see https://github.com/Gearbox-protocol/charts_server/blob/master/core/account_operation.go#L238-L264
117
+ *
118
+ * @deprecated Eventually will be gone, exists to produce output that legacy UI can display
129
119
  */
130
120
  classifyLegacyOperation(_parsed, transfers) {
131
121
  const swap = swapFromTransfers(transfers);
@@ -12,6 +12,15 @@ class AccountMigratorAdapterContract extends AbstractAdapterContract {
12
12
  `classifyLegacyOperation is not supported for legacy adapter: ${this.contractType}`
13
13
  );
14
14
  }
15
+ /**
16
+ * The account-migrator adapter's `execute` targets the migrator bot, not an
17
+ * external protocol, so there is no protocol-level call to recover. Returning
18
+ * `undefined` keeps the `protocol` field aligned with its external-protocol
19
+ * semantics (see {@link TraceAdapterExt}).
20
+ */
21
+ parseProtocolCall(_trace, _strict) {
22
+ return void 0;
23
+ }
15
24
  }
16
25
  export {
17
26
  AccountMigratorAdapterContract
@@ -1,3 +1,4 @@
1
1
  export * from "./parse/index.js";
2
2
  export * from "./prerequisites/index.js";
3
3
  export * from "./simulate/index.js";
4
+ export * from "./trace/index.js";
@@ -1,56 +1,25 @@
1
- import { zeroAddress } from "viem";
2
- import {
3
- AbstractAdapterContract
4
- } from "../../plugins/adapters/index.js";
1
+ import { AbstractAdapterContract } from "../../plugins/adapters/index.js";
5
2
  function classifyInnerOperations(calls, props) {
6
3
  const { sdk, underlying } = props;
7
4
  const result = [];
8
5
  for (const call of calls) {
9
6
  const contract = sdk.getContract(call.target);
10
- if (contract instanceof AbstractAdapterContract) {
7
+ if (contract instanceof AbstractAdapterContract || contract === void 0) {
11
8
  result.push({
12
9
  operation: "Execute",
13
10
  adapter: call.target,
14
- protocol: contract.targetContract,
15
11
  adapterType: call.contractType,
16
12
  version: call.version,
17
13
  label: call.label,
18
14
  adapterFunctionName: call.functionName,
19
- adapterArgs: call.rawArgs,
20
- // TODO: mirror the adapter call into the protocol fields for now. The
21
- // real protocol-level call (adapter -> target contract) only exists in
22
- // the execution call trace, which is not available from raw calldata.
23
- // Recovering the actual protocol function/args requires a call trace.
24
- protocolFunctionName: call.functionName,
25
- protocolArgs: call.rawArgs,
26
- transfers: [],
27
- legacy: mockLegacyOperation()
15
+ adapterArgs: call.rawArgs
28
16
  });
29
17
  continue;
30
18
  }
31
- if (contract !== void 0) {
32
- const op = classifyFacadeInnerCall(call, underlying);
33
- if (op) result.push(op);
34
- continue;
19
+ const op = classifyFacadeInnerCall(call, underlying);
20
+ if (op) {
21
+ result.push(op);
35
22
  }
36
- result.push({
37
- operation: "Execute",
38
- adapter: call.target,
39
- protocol: call.target,
40
- adapterType: call.contractType,
41
- version: call.version,
42
- label: call.label,
43
- adapterFunctionName: call.functionName,
44
- adapterArgs: call.rawArgs,
45
- // TODO: mirror the adapter call into the protocol fields for now. The
46
- // real protocol-level call (adapter -> target contract) only exists in
47
- // the execution call trace, which is not available from raw calldata.
48
- // Recovering the actual protocol function/args requires a call trace.
49
- protocolFunctionName: call.functionName,
50
- protocolArgs: call.rawArgs,
51
- transfers: [],
52
- legacy: mockLegacyOperation()
53
- });
54
23
  }
55
24
  return result;
56
25
  }
@@ -94,15 +63,6 @@ function classifyFacadeInnerCall(call, underlying) {
94
63
  return null;
95
64
  }
96
65
  }
97
- function mockLegacyOperation() {
98
- return {
99
- operation: "Swap",
100
- from: zeroAddress,
101
- fromAmount: "0",
102
- to: zeroAddress,
103
- toAmount: "0"
104
- };
105
- }
106
66
  export {
107
67
  classifyInnerOperations
108
68
  };
@@ -1,8 +1,4 @@
1
- import {
2
- isAddressEqual,
3
- zeroAddress,
4
- zeroHash
5
- } from "viem";
1
+ import { isAddressEqual, zeroAddress } from "viem";
6
2
  import { classifyInnerOperations } from "./classifyInnerOperations.js";
7
3
  function parseFacadeOperationCalldata(props) {
8
4
  const { sdk, facade, calldata } = props;
@@ -17,10 +13,7 @@ function parseFacadeOperationCalldata(props) {
17
13
  }
18
14
  const metadata = {
19
15
  creditManager: suite.creditManager.address,
20
- creditFacade: facade.address,
21
- blockNumber: Number(sdk.currentBlock),
22
- txHash: zeroHash,
23
- timestamp: 0
16
+ creditFacade: facade.address
24
17
  };
25
18
  const innerCalls = rawArgs.calls ?? [];
26
19
  const multicall = classifyInnerOperations(innerCalls, {
File without changes
File without changes
@@ -1,3 +1,6 @@
1
+ export * from "./types-adapters.js";
2
+ export * from "./types-facades.js";
3
+ export * from "./types-pools.js";
1
4
  function isPoolOperation(tx) {
2
5
  return tx.operation === "Deposit" || tx.operation === "Redeem";
3
6
  }
@@ -2,5 +2,6 @@ export * from "./AllowancePrerequisite.js";
2
2
  export * from "./BalancePrerequisite.js";
3
3
  export * from "./buildPrerequisites.js";
4
4
  export * from "./Prerequisite.js";
5
+ export * from "./prepareAction.js";
5
6
  export * from "./runPrerequisites.js";
6
7
  export * from "./types.js";
@@ -0,0 +1,23 @@
1
+ import { encodeFunctionData, erc20Abi } from "viem";
2
+ function preparePrerequisiteAction(result) {
3
+ if (result.kind === "allowance" && result.satisfied === false) {
4
+ const { token, spender, required } = result.detail;
5
+ return {
6
+ kind: "allowance",
7
+ to: token,
8
+ data: encodeFunctionData({
9
+ abi: erc20Abi,
10
+ functionName: "approve",
11
+ args: [spender, required]
12
+ })
13
+ };
14
+ }
15
+ return null;
16
+ }
17
+ function isActionablePrerequisite(result) {
18
+ return preparePrerequisiteAction(result) !== null;
19
+ }
20
+ export {
21
+ isActionablePrerequisite,
22
+ preparePrerequisiteAction
23
+ };
@@ -22,28 +22,6 @@ class WithdrawCollateralAlignmentError extends Error {
22
22
  this.name = "WithdrawCollateralAlignmentError";
23
23
  }
24
24
  }
25
- class ProtocolCallNotFoundError extends Error {
26
- targetContract;
27
- executeIndex;
28
- constructor(targetContract, executeIndex) {
29
- super(
30
- `protocol call to ${targetContract} not found in trace for Execute #${executeIndex}`
31
- );
32
- this.name = "ProtocolCallNotFoundError";
33
- this.targetContract = targetContract;
34
- this.executeIndex = executeIndex;
35
- }
36
- }
37
- class AdapterTraceAlignmentError extends Error {
38
- constructor(expected, actual) {
39
- super(`found ${actual} adapter traces for ${expected} execute events`);
40
- this.expected = expected;
41
- this.actual = actual;
42
- this.name = "AdapterTracesAlignmentError";
43
- }
44
- expected;
45
- actual;
46
- }
47
25
  class UnexpectedFacadeEventOrderError extends Error {
48
26
  constructor(e) {
49
27
  super(
@@ -63,8 +41,6 @@ class UnknownFacadeCallError extends Error {
63
41
  }
64
42
  }
65
43
  export {
66
- AdapterTraceAlignmentError,
67
- ProtocolCallNotFoundError,
68
44
  TransferAlignmentError,
69
45
  UnexpectedFacadeEventOrderError,
70
46
  UnknownAdapterError,
@@ -0,0 +1,40 @@
1
+ import {
2
+ decodeAbiParameters,
3
+ isAddressEqual,
4
+ toFunctionSelector
5
+ } from "viem";
6
+ import {
7
+ resolveProtocolCall
8
+ } from "../../common-utils/utils/trace.js";
9
+ const WITHDRAW_PHANTOM_TOKEN_SELECTOR = toFunctionSelector(
10
+ "withdrawPhantomToken(address,uint256)"
11
+ );
12
+ const GET_PHANTOM_TOKEN_INFO_SELECTOR = toFunctionSelector(
13
+ "getPhantomTokenInfo()"
14
+ );
15
+ function isSynthesizedPhantomWithdrawal(siblings, index) {
16
+ const node = siblings[index];
17
+ if (node.type !== "CALL" || node.input.slice(0, 10).toLowerCase() !== WITHDRAW_PHANTOM_TOKEN_SELECTOR) {
18
+ return false;
19
+ }
20
+ const [token] = decodeAbiParameters(
21
+ [{ type: "address" }, { type: "uint256" }],
22
+ `0x${node.input.slice(10)}`
23
+ );
24
+ for (let i = 0; i < index; i++) {
25
+ const sib = siblings[i];
26
+ if (sib.type === "STATICCALL" && sib.input.slice(0, 10).toLowerCase() === GET_PHANTOM_TOKEN_INFO_SELECTOR && isAddressEqual(sib.to, token)) {
27
+ return true;
28
+ }
29
+ }
30
+ return false;
31
+ }
32
+ function extractAdapterCallTraces(facadeTrace) {
33
+ const subtraces = facadeTrace.calls ?? [];
34
+ return subtraces.filter(
35
+ (sub, index) => resolveProtocolCall(sub) !== void 0 && !isSynthesizedPhantomWithdrawal(subtraces, index)
36
+ );
37
+ }
38
+ export {
39
+ extractAdapterCallTraces
40
+ };
@@ -3,14 +3,14 @@ import {
3
3
  isAddressEqual,
4
4
  parseEventLogs
5
5
  } from "viem";
6
- import { iCreditFacadeV310Abi } from "../abi/310/generated.js";
7
- import { ierc20Abi } from "../abi/iERC20.js";
8
- import { AddressMap } from "../sdk/index.js";
6
+ import { iCreditFacadeV310Abi } from "../../abi/310/generated.js";
7
+ import { ierc20Abi } from "../../abi/iERC20.js";
8
+ import { AddressMap } from "../../sdk/index.js";
9
9
  import { UnexpectedFacadeEventOrderError } from "./errors.js";
10
10
  function extractTransfers(logs, creditAccount, pool, creditFacade) {
11
11
  const ranges = buildOperationRanges(logs, creditFacade, creditAccount);
12
12
  let currentEntries = [];
13
- const executeResults = [];
13
+ const executeTransfers = [];
14
14
  const directTransfers = [];
15
15
  const phantomTokens = new AddressMap();
16
16
  const withdrawCollateralEvents = [];
@@ -19,20 +19,17 @@ function extractTransfers(logs, creditAccount, pool, creditFacade) {
19
19
  const facadeEvent = tryDecodeFacadeEvent(log, creditFacade);
20
20
  if (facadeEvent) {
21
21
  if (isExecute(facadeEvent, creditAccount)) {
22
- executeResults.push({
23
- transfers: currentEntries,
24
- targetContract: facadeEvent.args.targetContract
25
- });
22
+ executeTransfers.push(currentEntries);
26
23
  } else if (isLiquidation(facadeEvent, creditAccount)) {
27
24
  liquidationRemainingFunds = facadeEvent.args.remainingFunds;
28
25
  } else if (isWithdrawPhantomToken(facadeEvent, creditAccount)) {
29
- const phantomExec = executeResults.pop();
30
- if (!phantomExec) {
26
+ const phantomTransfers = executeTransfers.pop();
27
+ if (!phantomTransfers) {
31
28
  throw new Error(
32
29
  `WithdrawPhantomToken without preceding Execute at logIndex ${facadeEvent.logIndex}`
33
30
  );
34
31
  }
35
- const rawDeposit = phantomExec.transfers.find(
32
+ const rawDeposit = phantomTransfers.find(
36
33
  (t) => isAddressEqual(t.to, creditAccount)
37
34
  );
38
35
  if (!rawDeposit) {
@@ -67,11 +64,11 @@ function extractTransfers(logs, creditAccount, pool, creditFacade) {
67
64
  currentEntries.push({ token, amount: value, from, to });
68
65
  }
69
66
  if (isAddressEqual(to, creditAccount) && !isInRange(log.logIndex, ranges)) {
70
- directTransfers.push({ token, from, amount: value });
67
+ directTransfers.push({ token, amount: value, from, to });
71
68
  }
72
69
  }
73
70
  return {
74
- executeResults,
71
+ executeTransfers,
75
72
  directTransfers,
76
73
  liquidationRemainingFunds,
77
74
  phantomTokens,
@@ -2,9 +2,11 @@ import {
2
2
  decodeFunctionResult,
3
3
  isAddressEqual
4
4
  } from "viem";
5
- import { iCreditFacadeV310Abi } from "../abi/310/generated.js";
5
+ import { iCreditFacadeV310Abi } from "../../abi/310/generated.js";
6
+ import {
7
+ collectTraces
8
+ } from "../../common-utils/utils/trace.js";
6
9
  import { UnknownFacadeCallError } from "./errors.js";
7
- import { collectTraces } from "./trace-utils.js";
8
10
  const FACADE_CALL_TYPES = {
9
11
  multicall: "MultiCall",
10
12
  botMulticall: "BotMulticall",
@@ -0,0 +1,5 @@
1
+ export * from "./errors.js";
2
+ export * from "./extractAdapterCallTraces.js";
3
+ export * from "./extractTransfers.js";
4
+ export * from "./findFacadeCalls.js";
5
+ export * from "./types.js";
File without changes
@@ -5,4 +5,5 @@ export * from "./constants.js";
5
5
  export * from "./creditAccount/index.js";
6
6
  export * from "./price-math.js";
7
7
  export * from "./strategies/index.js";
8
+ export * from "./trace.js";
8
9
  export * from "./validation/index.js";
@@ -0,0 +1,73 @@
1
+ import { type Address, type Hex } from "viem";
2
+ /**
3
+ * A single frame from Ethereum's `debug_traceTransaction` callTracer output.
4
+ * Recursive: each frame may contain nested sub-calls.
5
+ */
6
+ export interface CallTrace {
7
+ from: Address;
8
+ to: Address;
9
+ input: Hex;
10
+ output: Hex;
11
+ value: Hex;
12
+ /** "CALL", "DELEGATECALL", "STATICCALL", "CREATE", etc. */
13
+ type: string;
14
+ /** Present when the call reverted (e.g. "execution reverted"). */
15
+ error?: string;
16
+ /** ABI-encoded revert data, if available. */
17
+ revertReason?: Hex;
18
+ calls?: CallTrace[];
19
+ }
20
+ /**
21
+ * Selector of `CreditManagerV3.execute(bytes)` (`0x09c5eabe`).
22
+ *
23
+ * This is the authoritative marker of an adapter performing an external
24
+ * protocol call: the adapter calls the credit manager's `execute(bytes)`, which
25
+ * forwards the calldata to the credit account, which in turn CALLs the target
26
+ * (protocol) contract. Adapter approvals use a different selector
27
+ * (`execute(address,bytes)` on the credit account), so matching on this
28
+ * selector isolates the real protocol call.
29
+ */
30
+ export declare const EXECUTE_BYTES_SELECTOR: "0x09c5eabe";
31
+ /**
32
+ * Finds the shallowest non-reverted `CreditManager.execute(bytes)` call in a
33
+ * trace subtree (breadth-first), or `undefined` if none exists.
34
+ *
35
+ * "Shallowest" matters for account migration: a migrate adapter nests the
36
+ * entire target `openCreditAccount` multicall - including that account's own
37
+ * `execute(bytes)` calls - inside its subtree. The shallowest match is the
38
+ * adapter's own protocol call, not a nested one.
39
+ */
40
+ export declare function findExecuteBytes(node: CallTrace): CallTrace | undefined;
41
+ /**
42
+ * Finds the first non-reverted CALL in a subtree whose `input` exactly matches
43
+ * `input` (case-insensitive). Used to locate the leaf CALL to the target
44
+ * contract: `execute(bytes)` forwards the calldata unchanged through the credit
45
+ * account proxy DELEGATECALL down to the final CALL to the protocol contract.
46
+ */
47
+ export declare function findCallWithInput(node: CallTrace, input: Hex): CallTrace | undefined;
48
+ /**
49
+ * Resolves the external protocol call performed by an adapter-level call trace.
50
+ *
51
+ * Locates the shallowest `CreditManager.execute(bytes)`, decodes the forwarded
52
+ * calldata, then finds the leaf CALL whose input matches that calldata to
53
+ * recover the target (protocol) contract address. Returns `undefined` when the
54
+ * subtree does not actually reach an external protocol CALL (e.g. the
55
+ * facade-internal `depositPhantomToken` / `withdrawPhantomToken` accounting
56
+ * calls, which forward calldata but make no external CALL).
57
+ *
58
+ * @param node - direct child node of the upper-level facade call trace
59
+ */
60
+ export declare function resolveProtocolCall(node: CallTrace): {
61
+ contract: Address;
62
+ calldata: Hex;
63
+ } | undefined;
64
+ /**
65
+ * Finds the first non-reverted CALL to `target` anywhere in a trace subtree.
66
+ */
67
+ export declare function findCallTo(node: CallTrace, target: Address): CallTrace | undefined;
68
+ /**
69
+ * DFS walk of the call trace tree, collecting non-reverted CALL entries
70
+ * to the given address.
71
+ * Does not recurse into children of matched nodes
72
+ */
73
+ export declare function collectTraces(node: CallTrace, target: Address): CallTrace[];
@@ -1,11 +1,16 @@
1
1
  import type { Address } from "viem";
2
+ import type { TokenTransfer } from "../preview/parse/index.js";
3
+ import { type FacadeParsedCall, type WithdrawCollateralEventInfo } from "../preview/trace/index.js";
2
4
  import type { AddressMap, ChainContractsRegister } from "../sdk/index.js";
3
- import type { WithdrawCollateralEventInfo } from "./extractTransfers.js";
4
- import type { ExecuteResult, FacadeParsedCall } from "./internal-types.js";
5
- import type { FacadeOperationMetadata, OuterFacadeOperation } from "./types.js";
5
+ import type { HistoryFacadeMetadata, OuterFacadeOperation } from "./types.js";
6
6
  export interface AssembleOperationsInput {
7
7
  facadeCalls: FacadeParsedCall[];
8
- executeResults: ExecuteResult[];
8
+ /**
9
+ * ERC-20 transfers grouped per facade `Execute` event, one inner array per
10
+ * Execute event across the whole transaction, in emission order. Sliced per
11
+ * facade call and consumed one inner array per adapter/unknown inner call.
12
+ */
13
+ executeTransfers: TokenTransfer[][];
9
14
  register: ChainContractsRegister;
10
15
  underlying: Address;
11
16
  liquidationRemainingFunds?: bigint;
@@ -17,8 +22,8 @@ export interface AssembleOperationsInput {
17
22
  * Combines parsed facade calls with per-Execute transfer data into
18
23
  * fully classified {@link OuterFacadeOperation} entries.
19
24
  *
20
- * The flat `executeResults` array (one entry per Execute event across
25
+ * The flat `executeTransfers` array (one inner array per Execute event across
21
26
  * the entire transaction) is sliced per facade call based on how many
22
27
  * adapter/unknown inner calls each one contains.
23
28
  */
24
- export declare function assembleOperations(input: AssembleOperationsInput): Omit<OuterFacadeOperation, keyof FacadeOperationMetadata>[];
29
+ export declare function assembleOperations(input: AssembleOperationsInput): Omit<OuterFacadeOperation, keyof HistoryFacadeMetadata>[];
@@ -1,12 +1,23 @@
1
- import { type Address, type Hex } from "viem";
1
+ import { type Address } from "viem";
2
+ import type { CallTrace } from "../common-utils/utils/trace.js";
3
+ import type { TokenTransfer } from "../preview/parse/index.js";
4
+ import { type WithdrawCollateralEventInfo } from "../preview/trace/index.js";
2
5
  import type { AddressMap, ChainContractsRegister, ParsedCallV2 } from "../sdk/index.js";
3
- import type { WithdrawCollateralEventInfo } from "./extractTransfers.js";
4
- import type { InnerOperation } from "./inner-operations.js";
5
- import type { ExecuteResult } from "./internal-types.js";
6
+ import type { InnerOperation } from "./types.js";
6
7
  export interface ClassifyMulticallOperationsInput {
7
8
  innerCalls: ParsedCallV2[];
8
- executeResults: ExecuteResult[];
9
- protocolCalldatas: Hex[];
9
+ /**
10
+ * ERC-20 transfers grouped per facade `Execute` event for this facade call,
11
+ * one inner array per Execute event, in order. One inner array is consumed
12
+ * per adapter/unknown inner call.
13
+ */
14
+ executeTransfers: TokenTransfer[][];
15
+ /**
16
+ * Adapter-level call traces (one per Execute event, in order) used to recover
17
+ * the protocol-level call for adapter inner calls. See
18
+ * `extractAdapterCallTraces`.
19
+ */
20
+ adapterTraces: CallTrace[];
10
21
  register: ChainContractsRegister;
11
22
  creditAccount: Address;
12
23
  underlying: Address;
@@ -17,9 +28,10 @@ export interface ClassifyMulticallOperationsInput {
17
28
  /**
18
29
  * Classifies each multicall inner call into a {@link InnerOperation}:
19
30
  *
20
- * - **Adapter calls** (target registered as an adapter): delegates to
21
- * `adapter.parseAdapterOperation()` and consumes the next entry from
22
- * `executeTransfers` (one Execute event per adapter call).
31
+ * - **Adapter calls** (target registered as an adapter): decodes the
32
+ * protocol-level call via `adapter.parseProtocolCall()`, classifies the
33
+ * legacy operation via `adapter.classifyLegacyOperation()`, and consumes the
34
+ * next entry from `executeTransfers` (one Execute event per adapter call).
23
35
  *
24
36
  * - **Facade self-calls** (`increaseDebt`, `updateQuota`, etc.): mapped
25
37
  * directly from `functionName` / `rawArgs`. No transfer consumed.
@@ -1,4 +1,3 @@
1
- export * from "./inner-operations.js";
2
1
  export * from "./mapOperations.js";
3
2
  export { parseCreditAccountTransaction } from "./parseCreditAccountTransaction.js";
4
3
  export * from "./populateContractsRegister.js";
@@ -1,18 +1,16 @@
1
- import type { AdapterOperation } from "../plugins/adapters/index.js";
2
- import type { AddCollateralOp, DecreaseDebtOp, IncreaseDebtOp, UpdateQuotaOp, WithdrawCollateralOp } from "./inner-operations.js";
3
- import type { CloseCreditAccountOperation, CreditAccountOperation, DirectTokenTransferOperation, FacadeOperationMetadata, LiquidateCreditAccountOperation, MulticallOperation, OpenCreditAccountOperation, PartialLiquidationOperation } from "./types.js";
1
+ import type { AdapterOperation, AddCollateralOp, CloseCreditAccountOperation, CreditAccountOperation, DecreaseDebtOp, DirectTokenTransferOperation, HistoryFacadeMetadata, IncreaseDebtOp, LiquidateCreditAccountOperation, MulticallOperation, OpenCreditAccountOperation, PartialLiquidationOperation, UpdateQuotaOp, WithdrawCollateralOp } from "./types.js";
4
2
  /**
5
3
  * Visitor that maps each operation node in a {@link CreditAccountOperation}
6
4
  * tree to a new representation.
7
5
  *
8
6
  */
9
7
  export interface OperationVisitor<TInner, TOuter> {
10
- Execute(op: AdapterOperation, ctx: FacadeOperationMetadata): TInner;
11
- IncreaseBorrowedAmount(op: IncreaseDebtOp, ctx: FacadeOperationMetadata): TInner;
12
- DecreaseBorrowedAmount(op: DecreaseDebtOp, ctx: FacadeOperationMetadata): TInner;
13
- AddCollateral(op: AddCollateralOp, ctx: FacadeOperationMetadata): TInner;
14
- WithdrawCollateral(op: WithdrawCollateralOp, ctx: FacadeOperationMetadata): TInner;
15
- UpdateQuota(op: UpdateQuotaOp, ctx: FacadeOperationMetadata): TInner;
8
+ Execute(op: AdapterOperation, ctx: HistoryFacadeMetadata): TInner;
9
+ IncreaseBorrowedAmount(op: IncreaseDebtOp, ctx: HistoryFacadeMetadata): TInner;
10
+ DecreaseBorrowedAmount(op: DecreaseDebtOp, ctx: HistoryFacadeMetadata): TInner;
11
+ AddCollateral(op: AddCollateralOp, ctx: HistoryFacadeMetadata): TInner;
12
+ WithdrawCollateral(op: WithdrawCollateralOp, ctx: HistoryFacadeMetadata): TInner;
13
+ UpdateQuota(op: UpdateQuotaOp, ctx: HistoryFacadeMetadata): TInner;
16
14
  DirectTokenTransfer(op: DirectTokenTransferOperation): TOuter;
17
15
  MultiCall(op: MulticallOperation, multicall: TInner[]): TOuter;
18
16
  OpenCreditAccount(op: OpenCreditAccountOperation, multicall: TInner[]): TOuter;