@gearbox-protocol/sdk 14.12.0-next.1 → 14.12.0-next.2

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 (80) hide show
  1. package/dist/cjs/abi/iZapper.js +62 -24
  2. package/dist/cjs/preview/parse/errors.js +5 -2
  3. package/dist/cjs/preview/parse/parseOperationCalldata.js +30 -1
  4. package/dist/cjs/preview/parse/parsePoolOperationCalldata.js +10 -2
  5. package/dist/cjs/preview/prerequisites/buildPrerequisites.js +34 -0
  6. package/dist/cjs/preview/simulate/errors.js +0 -7
  7. package/dist/cjs/preview/simulate/index.js +0 -3
  8. package/dist/cjs/preview/simulate/simulatePoolOperation.js +154 -29
  9. package/dist/cjs/sdk/MultichainSDK.js +1 -0
  10. package/dist/cjs/sdk/OnchainSDK.js +7 -3
  11. package/dist/cjs/sdk/market/MarketRegister.js +10 -5
  12. package/dist/cjs/sdk/market/ZapperRegister.js +54 -0
  13. package/dist/cjs/sdk/market/zapper/IERC20ZapperContract.js +3 -38
  14. package/dist/cjs/sdk/market/zapper/IETHZapperContract.js +3 -38
  15. package/dist/cjs/sdk/market/zapper/ZapperContract.js +109 -0
  16. package/dist/cjs/sdk/market/zapper/createZapper.js +12 -4
  17. package/dist/cjs/{preview/simulate/constants.js → sdk/market/zapper/errors.js} +15 -6
  18. package/dist/cjs/sdk/market/zapper/index.js +6 -2
  19. package/dist/cjs/sdk/market/zapper/types.js +16 -0
  20. package/dist/cjs/sdk/options.js +41 -17
  21. package/dist/esm/abi/iZapper.js +62 -24
  22. package/dist/esm/preview/parse/errors.js +3 -1
  23. package/dist/esm/preview/parse/parseOperationCalldata.js +32 -2
  24. package/dist/esm/preview/parse/parsePoolOperationCalldata.js +10 -2
  25. package/dist/esm/preview/prerequisites/buildPrerequisites.js +34 -0
  26. package/dist/esm/preview/simulate/errors.js +0 -6
  27. package/dist/esm/preview/simulate/index.js +0 -2
  28. package/dist/esm/preview/simulate/simulatePoolOperation.js +155 -30
  29. package/dist/esm/sdk/MultichainSDK.js +1 -0
  30. package/dist/esm/sdk/OnchainSDK.js +7 -3
  31. package/dist/esm/sdk/market/MarketRegister.js +10 -5
  32. package/dist/esm/sdk/market/ZapperRegister.js +54 -0
  33. package/dist/esm/sdk/market/zapper/IERC20ZapperContract.js +3 -38
  34. package/dist/esm/sdk/market/zapper/IETHZapperContract.js +3 -38
  35. package/dist/esm/sdk/market/zapper/ZapperContract.js +85 -0
  36. package/dist/esm/sdk/market/zapper/createZapper.js +12 -4
  37. package/dist/esm/sdk/market/zapper/errors.js +13 -0
  38. package/dist/esm/sdk/market/zapper/index.js +3 -1
  39. package/dist/esm/sdk/market/zapper/types.js +0 -0
  40. package/dist/esm/sdk/options.js +39 -15
  41. package/dist/types/abi/iERC20Zapper.d.ts +91 -23
  42. package/dist/types/abi/iETHZapper.d.ts +91 -23
  43. package/dist/types/abi/iZapper.d.ts +91 -23
  44. package/dist/types/preview/parse/errors.d.ts +1 -0
  45. package/dist/types/preview/parse/parseOperationCalldata.d.ts +3 -3
  46. package/dist/types/preview/parse/types-pools.d.ts +61 -1
  47. package/dist/types/preview/simulate/errors.d.ts +6 -12
  48. package/dist/types/preview/simulate/index.d.ts +0 -1
  49. package/dist/types/preview/simulate/simulatePoolOperation.d.ts +22 -4
  50. package/dist/types/preview/simulate/types.d.ts +3 -16
  51. package/dist/types/sdk/MultichainSDK.d.ts +5 -0
  52. package/dist/types/sdk/OnchainSDK.d.ts +4 -0
  53. package/dist/types/sdk/market/MarketRegister.d.ts +15 -6
  54. package/dist/types/sdk/market/ZapperRegister.d.ts +25 -4
  55. package/dist/types/sdk/market/zapper/IERC20ZapperContract.d.ts +93 -39
  56. package/dist/types/sdk/market/zapper/IETHZapperContract.d.ts +93 -39
  57. package/dist/types/sdk/market/zapper/ZapperContract.d.ts +35 -0
  58. package/dist/types/sdk/market/zapper/createZapper.d.ts +2 -4
  59. package/dist/types/sdk/market/zapper/errors.d.ts +10 -0
  60. package/dist/types/sdk/market/zapper/index.d.ts +3 -1
  61. package/dist/types/sdk/market/zapper/types.d.ts +64 -0
  62. package/dist/types/sdk/options.d.ts +10 -5
  63. package/dist/types/sdk/pools/types.d.ts +3 -3
  64. package/dist/types/sdk/types/state-human.d.ts +9 -0
  65. package/dist/types/sdk/types/state.d.ts +7 -0
  66. package/package.json +3 -3
  67. package/dist/cjs/preview/simulate/extractERC20Transfers.js +0 -47
  68. package/dist/cjs/preview/simulate/simulatePoolOpMulticall.js +0 -155
  69. package/dist/cjs/preview/simulate/simulatePoolOpV1.js +0 -106
  70. package/dist/cjs/sdk/market/zapper/Zapper.js +0 -47
  71. package/dist/esm/preview/simulate/constants.js +0 -4
  72. package/dist/esm/preview/simulate/extractERC20Transfers.js +0 -23
  73. package/dist/esm/preview/simulate/simulatePoolOpMulticall.js +0 -130
  74. package/dist/esm/preview/simulate/simulatePoolOpV1.js +0 -82
  75. package/dist/esm/sdk/market/zapper/Zapper.js +0 -23
  76. package/dist/types/preview/simulate/constants.d.ts +0 -6
  77. package/dist/types/preview/simulate/extractERC20Transfers.d.ts +0 -11
  78. package/dist/types/preview/simulate/simulatePoolOpMulticall.d.ts +0 -28
  79. package/dist/types/preview/simulate/simulatePoolOpV1.d.ts +0 -14
  80. package/dist/types/sdk/market/zapper/Zapper.d.ts +0 -13
@@ -24,80 +24,118 @@ module.exports = __toCommonJS(iZapper_exports);
24
24
  const iZapperAbi = [
25
25
  {
26
26
  type: "function",
27
+ name: "contractType",
27
28
  inputs: [],
29
+ outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
30
+ stateMutability: "view"
31
+ },
32
+ {
33
+ type: "function",
28
34
  name: "pool",
29
- outputs: [{ name: "", internalType: "address", type: "address" }],
35
+ inputs: [],
36
+ outputs: [{ name: "", type: "address", internalType: "address" }],
30
37
  stateMutability: "view"
31
38
  },
32
39
  {
33
40
  type: "function",
41
+ name: "previewDeposit",
34
42
  inputs: [
35
- { name: "tokenInAmount", internalType: "uint256", type: "uint256" }
43
+ { name: "tokenInAmount", type: "uint256", internalType: "uint256" }
36
44
  ],
37
- name: "previewDeposit",
38
45
  outputs: [
39
- { name: "tokenOutAmount", internalType: "uint256", type: "uint256" }
46
+ { name: "tokenOutAmount", type: "uint256", internalType: "uint256" }
40
47
  ],
41
48
  stateMutability: "view"
42
49
  },
43
50
  {
44
51
  type: "function",
52
+ name: "previewRedeem",
45
53
  inputs: [
46
- { name: "tokenOutAmount", internalType: "uint256", type: "uint256" }
54
+ { name: "tokenOutAmount", type: "uint256", internalType: "uint256" }
47
55
  ],
48
- name: "previewRedeem",
49
56
  outputs: [
50
- { name: "tokenInAmount", internalType: "uint256", type: "uint256" }
57
+ { name: "tokenInAmount", type: "uint256", internalType: "uint256" }
51
58
  ],
52
59
  stateMutability: "view"
53
60
  },
54
61
  {
55
62
  type: "function",
63
+ name: "redeem",
56
64
  inputs: [
57
- { name: "tokenOutAmount", internalType: "uint256", type: "uint256" },
58
- { name: "receiver", internalType: "address", type: "address" }
65
+ { name: "tokenOutAmount", type: "uint256", internalType: "uint256" },
66
+ { name: "receiver", type: "address", internalType: "address" }
59
67
  ],
60
- name: "redeem",
61
68
  outputs: [
62
- { name: "tokenInAmount", internalType: "uint256", type: "uint256" }
69
+ { name: "tokenInAmount", type: "uint256", internalType: "uint256" }
63
70
  ],
64
71
  stateMutability: "nonpayable"
65
72
  },
66
73
  {
67
74
  type: "function",
75
+ name: "redeemWithPermit",
68
76
  inputs: [
69
- { name: "tokenOutAmount", internalType: "uint256", type: "uint256" },
70
- { name: "receiver", internalType: "address", type: "address" },
71
- { name: "deadline", internalType: "uint256", type: "uint256" },
72
- { name: "v", internalType: "uint8", type: "uint8" },
73
- { name: "r", internalType: "bytes32", type: "bytes32" },
74
- { name: "s", internalType: "bytes32", type: "bytes32" }
77
+ { name: "tokenOutAmount", type: "uint256", internalType: "uint256" },
78
+ { name: "receiver", type: "address", internalType: "address" },
79
+ { name: "deadline", type: "uint256", internalType: "uint256" },
80
+ { name: "v", type: "uint8", internalType: "uint8" },
81
+ { name: "r", type: "bytes32", internalType: "bytes32" },
82
+ { name: "s", type: "bytes32", internalType: "bytes32" }
75
83
  ],
76
- name: "redeemWithPermit",
77
84
  outputs: [
78
- { name: "tokenInAmount", internalType: "uint256", type: "uint256" }
85
+ { name: "tokenInAmount", type: "uint256", internalType: "uint256" }
79
86
  ],
80
87
  stateMutability: "nonpayable"
81
88
  },
82
89
  {
83
90
  type: "function",
91
+ name: "redeemWithPermitAllowed",
92
+ inputs: [
93
+ { name: "tokenOutAmount", type: "uint256", internalType: "uint256" },
94
+ { name: "receiver", type: "address", internalType: "address" },
95
+ { name: "nonce", type: "uint256", internalType: "uint256" },
96
+ { name: "expiry", type: "uint256", internalType: "uint256" },
97
+ { name: "v", type: "uint8", internalType: "uint8" },
98
+ { name: "r", type: "bytes32", internalType: "bytes32" },
99
+ { name: "s", type: "bytes32", internalType: "bytes32" }
100
+ ],
101
+ outputs: [
102
+ { name: "tokenInAmount", type: "uint256", internalType: "uint256" }
103
+ ],
104
+ stateMutability: "nonpayable"
105
+ },
106
+ {
107
+ type: "function",
108
+ name: "serialize",
84
109
  inputs: [],
85
- name: "tokenIn",
86
- outputs: [{ name: "", internalType: "address", type: "address" }],
110
+ outputs: [{ name: "serializedData", type: "bytes", internalType: "bytes" }],
87
111
  stateMutability: "view"
88
112
  },
89
113
  {
90
114
  type: "function",
115
+ name: "tokenIn",
91
116
  inputs: [],
92
- name: "tokenOut",
93
- outputs: [{ name: "", internalType: "address", type: "address" }],
117
+ outputs: [{ name: "", type: "address", internalType: "address" }],
94
118
  stateMutability: "view"
95
119
  },
96
120
  {
97
121
  type: "function",
122
+ name: "tokenOut",
98
123
  inputs: [],
124
+ outputs: [{ name: "", type: "address", internalType: "address" }],
125
+ stateMutability: "view"
126
+ },
127
+ {
128
+ type: "function",
99
129
  name: "underlying",
100
- outputs: [{ name: "", internalType: "address", type: "address" }],
130
+ inputs: [],
131
+ outputs: [{ name: "", type: "address", internalType: "address" }],
132
+ stateMutability: "view"
133
+ },
134
+ {
135
+ type: "function",
136
+ name: "version",
137
+ inputs: [],
138
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
101
139
  stateMutability: "view"
102
140
  }
103
141
  ];
@@ -19,9 +19,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var errors_exports = {};
20
20
  __export(errors_exports, {
21
21
  UnsupportedPoolFunctionError: () => UnsupportedPoolFunctionError,
22
- UnsupportedTargetError: () => UnsupportedTargetError
22
+ UnsupportedTargetError: () => UnsupportedTargetError,
23
+ UnsupportedZapperFunctionError: () => import_sdk.UnsupportedZapperFunctionError
23
24
  });
24
25
  module.exports = __toCommonJS(errors_exports);
26
+ var import_sdk = require("../../sdk/index.js");
25
27
  class UnsupportedTargetError extends Error {
26
28
  target;
27
29
  constructor(target) {
@@ -43,5 +45,6 @@ class UnsupportedPoolFunctionError extends Error {
43
45
  // Annotate the CommonJS export names for ESM import in node:
44
46
  0 && (module.exports = {
45
47
  UnsupportedPoolFunctionError,
46
- UnsupportedTargetError
48
+ UnsupportedTargetError,
49
+ UnsupportedZapperFunctionError
47
50
  });
@@ -26,11 +26,40 @@ var import_errors = require("./errors.js");
26
26
  var import_parseFacadeOperationCalldata = require("./parseFacadeOperationCalldata.js");
27
27
  var import_parsePoolOperationCalldata = require("./parsePoolOperationCalldata.js");
28
28
  function parseOperationCalldata(input) {
29
- const { sdk, to, calldata } = input;
29
+ const { sdk, to, calldata, value, sender } = input;
30
30
  const contract = sdk.getContract(to);
31
31
  if (contract instanceof import_sdk.PoolV310Contract) {
32
32
  return (0, import_parsePoolOperationCalldata.parsePoolOperationCalldata)({ sdk, pool: contract, calldata });
33
33
  }
34
+ if (contract instanceof import_sdk.ZapperContract) {
35
+ const parsed = contract.parseOperation(calldata, value);
36
+ if (parsed.operation === "Deposit") {
37
+ const op2 = {
38
+ operation: "Deposit",
39
+ pool: parsed.pool,
40
+ receiver: parsed.receiver,
41
+ assets: parsed.assets,
42
+ underlying: parsed.underlying,
43
+ tokenIn: parsed.token,
44
+ zapper: parsed.zapper,
45
+ referralCode: parsed.referralCode
46
+ };
47
+ return op2;
48
+ }
49
+ const op = {
50
+ operation: "Redeem",
51
+ pool: parsed.pool,
52
+ receiver: parsed.receiver,
53
+ // The zapper burns the caller's pool shares, so the share owner is the
54
+ // transaction sender.
55
+ owner: sender,
56
+ shares: parsed.shares,
57
+ underlying: parsed.underlying,
58
+ tokenOut: parsed.token,
59
+ zapper: parsed.zapper
60
+ };
61
+ return op;
62
+ }
34
63
  if (contract instanceof import_sdk.CreditFacadeV310Contract) {
35
64
  return (0, import_parseFacadeOperationCalldata.parseFacadeOperationCalldata)({
36
65
  sdk,
@@ -37,6 +37,8 @@ function parsePoolOperationCalldata(props) {
37
37
  receiver: rawArgs.receiver,
38
38
  assets: rawArgs.assets,
39
39
  underlying,
40
+ tokenIn: underlying,
41
+ zapper: void 0,
40
42
  referralCode: functionName === "depositWithReferral" ? rawArgs.referralCode : void 0
41
43
  };
42
44
  case "mint":
@@ -47,6 +49,8 @@ function parsePoolOperationCalldata(props) {
47
49
  receiver: rawArgs.receiver,
48
50
  shares: rawArgs.shares,
49
51
  underlying,
52
+ tokenIn: underlying,
53
+ zapper: void 0,
50
54
  referralCode: functionName === "mintWithReferral" ? rawArgs.referralCode : void 0
51
55
  };
52
56
  case "withdraw":
@@ -56,7 +60,9 @@ function parsePoolOperationCalldata(props) {
56
60
  receiver: rawArgs.receiver,
57
61
  owner: rawArgs.owner,
58
62
  assets: rawArgs.assets,
59
- underlying
63
+ underlying,
64
+ tokenOut: underlying,
65
+ zapper: void 0
60
66
  };
61
67
  case "redeem":
62
68
  return {
@@ -65,7 +71,9 @@ function parsePoolOperationCalldata(props) {
65
71
  receiver: rawArgs.receiver,
66
72
  owner: rawArgs.owner,
67
73
  shares: rawArgs.shares,
68
- underlying
74
+ underlying,
75
+ tokenOut: underlying,
76
+ zapper: void 0
69
77
  };
70
78
  default:
71
79
  throw new import_errors.UnsupportedPoolFunctionError(pool.address, parsed.functionName);
@@ -34,6 +34,23 @@ function buildPrerequisites(tx, ctx) {
34
34
  // here we approximate Mint by its shares amount (a lower bound on assets is
35
35
  // not knowable from calldata alone).
36
36
  case "Deposit":
37
+ if (tx.zapper) {
38
+ return [
39
+ new import_AllowancePrerequisite.AllowancePrerequisite({
40
+ token: tx.tokenIn,
41
+ owner: wallet,
42
+ spender: tx.zapper,
43
+ required: tx.assets,
44
+ title: "Token approved to zapper"
45
+ }),
46
+ new import_BalancePrerequisite.BalancePrerequisite({
47
+ token: tx.tokenIn,
48
+ owner: wallet,
49
+ required: tx.assets,
50
+ title: "Sufficient token balance"
51
+ })
52
+ ];
53
+ }
37
54
  return [
38
55
  new import_AllowancePrerequisite.AllowancePrerequisite({
39
56
  token: tx.underlying,
@@ -68,6 +85,23 @@ function buildPrerequisites(tx, ctx) {
68
85
  // Redeem and Withdraw both burn LP shares from `owner`; they only differ in
69
86
  // which side (shares vs assets) the caller specifies.
70
87
  case "Redeem": {
88
+ if (tx.zapper) {
89
+ return [
90
+ new import_BalancePrerequisite.BalancePrerequisite({
91
+ token: tx.pool,
92
+ owner: wallet,
93
+ required: tx.shares,
94
+ title: "Sufficient LP token balance"
95
+ }),
96
+ new import_AllowancePrerequisite.AllowancePrerequisite({
97
+ token: tx.pool,
98
+ owner: wallet,
99
+ spender: tx.zapper,
100
+ required: tx.shares,
101
+ title: "LP token approved to zapper"
102
+ })
103
+ ];
104
+ }
71
105
  const prereqs = [
72
106
  new import_BalancePrerequisite.BalancePrerequisite({
73
107
  token: tx.pool,
@@ -20,7 +20,6 @@ var errors_exports = {};
20
20
  __export(errors_exports, {
21
21
  PreviewSimulationError: () => PreviewSimulationError,
22
22
  asPreviewSimulationError: () => asPreviewSimulationError,
23
- combinePreviewSimulationErrors: () => combinePreviewSimulationErrors,
24
23
  decodeSimulationError: () => decodeSimulationError
25
24
  });
26
25
  module.exports = __toCommonJS(errors_exports);
@@ -49,11 +48,6 @@ function asPreviewSimulationError(reason, source) {
49
48
  { source, detail: decodeSimulationError({ error }) }
50
49
  ]);
51
50
  }
52
- function combinePreviewSimulationErrors(...errors) {
53
- return new PreviewSimulationError(
54
- errors.filter((e) => e).flatMap((e) => e?.failures ?? [])
55
- );
56
- }
57
51
  function decodeSimulationError(revert) {
58
52
  const { error, data } = revert;
59
53
  if (data && data !== "0x") {
@@ -93,6 +87,5 @@ function formatDecodedError(errorName, args) {
93
87
  0 && (module.exports = {
94
88
  PreviewSimulationError,
95
89
  asPreviewSimulationError,
96
- combinePreviewSimulationErrors,
97
90
  decodeSimulationError
98
91
  });
@@ -18,21 +18,18 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var simulate_exports = {};
20
20
  __export(simulate_exports, {
21
- ETH_SIMULATE_V1_NETWORKS: () => import_constants.ETH_SIMULATE_V1_NETWORKS,
22
21
  PreviewSimulationError: () => import_errors.PreviewSimulationError,
23
22
  simulateFacadeOperation: () => import_simulateFacadeOperation.simulateFacadeOperation,
24
23
  simulateOperation: () => import_simulateOperation.simulateOperation,
25
24
  simulatePoolOperation: () => import_simulatePoolOperation.simulatePoolOperation
26
25
  });
27
26
  module.exports = __toCommonJS(simulate_exports);
28
- var import_constants = require("./constants.js");
29
27
  var import_errors = require("./errors.js");
30
28
  var import_simulateFacadeOperation = require("./simulateFacadeOperation.js");
31
29
  var import_simulateOperation = require("./simulateOperation.js");
32
30
  var import_simulatePoolOperation = require("./simulatePoolOperation.js");
33
31
  // Annotate the CommonJS export names for ESM import in node:
34
32
  0 && (module.exports = {
35
- ETH_SIMULATE_V1_NETWORKS,
36
33
  PreviewSimulationError,
37
34
  simulateFacadeOperation,
38
35
  simulateOperation,
@@ -18,45 +18,170 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var simulatePoolOperation_exports = {};
20
20
  __export(simulatePoolOperation_exports, {
21
+ computePoolOpBalanceChanges: () => computePoolOpBalanceChanges,
21
22
  simulatePoolOperation: () => simulatePoolOperation
22
23
  });
23
24
  module.exports = __toCommonJS(simulatePoolOperation_exports);
24
- var import_constants = require("./constants.js");
25
+ var import_generated = require("../../abi/310/generated.js");
26
+ var import_iERC20 = require("../../abi/iERC20.js");
27
+ var import_iZapper = require("../../abi/iZapper.js");
28
+ var import_sdk = require("../../sdk/index.js");
25
29
  var import_errors = require("./errors.js");
26
- var import_simulatePoolOpMulticall = require("./simulatePoolOpMulticall.js");
27
- var import_simulatePoolOpV1 = require("./simulatePoolOpV1.js");
30
+ var import_holders = require("./holders.js");
31
+ function previewRead(operation) {
32
+ switch (operation.operation) {
33
+ case "Deposit":
34
+ return { functionName: "previewDeposit", amount: operation.assets };
35
+ case "Mint":
36
+ return { functionName: "previewMint", amount: operation.shares };
37
+ case "Withdraw":
38
+ return { functionName: "previewWithdraw", amount: operation.assets };
39
+ case "Redeem":
40
+ return { functionName: "previewRedeem", amount: operation.shares };
41
+ }
42
+ }
43
+ function outsideToken(operation) {
44
+ switch (operation.operation) {
45
+ case "Deposit":
46
+ case "Mint":
47
+ return operation.tokenIn;
48
+ case "Withdraw":
49
+ case "Redeem":
50
+ return operation.tokenOut;
51
+ }
52
+ }
53
+ function previewContract(operation) {
54
+ const { functionName, amount } = previewRead(operation);
55
+ if (operation.zapper) {
56
+ return {
57
+ address: operation.zapper,
58
+ abi: import_iZapper.iZapperAbi,
59
+ functionName,
60
+ args: [amount]
61
+ };
62
+ }
63
+ return {
64
+ address: operation.pool,
65
+ abi: import_generated.iPoolV310Abi,
66
+ functionName,
67
+ args: [amount]
68
+ };
69
+ }
28
70
  async function simulatePoolOperation(input, options = {}) {
29
- const { sdk } = input;
30
- const { logger } = options;
31
- const useSimulateV1 = options.useSimulateV1 ?? import_constants.ETH_SIMULATE_V1_NETWORKS.has(sdk.networkType);
32
- logger?.debug(
33
- { wallet: input.wallet, to: input.to },
34
- "simulating pool operation"
35
- );
36
- const [v1, multicall] = await Promise.allSettled([
37
- useSimulateV1 ? (0, import_simulatePoolOpV1.simulatePoolOpV1)(input, options) : void 0,
38
- (0, import_simulatePoolOpMulticall.simulatePoolOpMulticall)(input, options)
39
- ]);
40
- if (v1.status === "fulfilled" && v1.value) {
41
- return { status: "success", ...v1.value };
71
+ const { sdk, operation, wallet } = input;
72
+ const { blockNumber, logger } = options;
73
+ const { pool } = operation;
74
+ try {
75
+ const holders = (0, import_holders.watchedHolders)(operation, wallet);
76
+ const tokens = [outsideToken(operation), pool];
77
+ const balanceCalls = holders.flatMap(
78
+ (holder) => tokens.map((token) => ({ holder, token }))
79
+ );
80
+ const balanceContracts = balanceCalls.map(
81
+ ({ holder, token }) => ({
82
+ address: token,
83
+ abi: import_iERC20.ierc20Abi,
84
+ functionName: "balanceOf",
85
+ args: [holder]
86
+ })
87
+ );
88
+ const preview = previewContract(operation);
89
+ let results;
90
+ try {
91
+ results = await sdk.client.multicall({
92
+ allowFailure: false,
93
+ // `undefined` lets viem read at `latest`; `blockNumber` is only set for
94
+ // testnet forks pinned to a specific block.
95
+ blockNumber,
96
+ contracts: [...balanceContracts, preview]
97
+ });
98
+ } catch (cause) {
99
+ throw new import_errors.PreviewSimulationError([
100
+ {
101
+ source: "multicall",
102
+ detail: (0, import_errors.decodeSimulationError)({
103
+ error: cause instanceof Error ? cause : new Error(String(cause))
104
+ })
105
+ }
106
+ ]);
107
+ }
108
+ const previewAmount = results[balanceContracts.length];
109
+ const balances = new import_sdk.AddressMap();
110
+ for (const [i, { holder, token }] of balanceCalls.entries()) {
111
+ const tokenBalances = balances.get(holder) ?? new import_sdk.AddressMap();
112
+ tokenBalances.upsert(token, results[i]);
113
+ balances.upsert(holder, tokenBalances);
114
+ }
115
+ const before = (token, holder) => balances.get(holder)?.get(token) ?? 0n;
116
+ return {
117
+ status: "success",
118
+ balanceChanges: computePoolOpBalanceChanges(
119
+ operation,
120
+ wallet,
121
+ previewAmount,
122
+ before
123
+ )
124
+ };
125
+ } catch (cause) {
126
+ const error = (0, import_errors.asPreviewSimulationError)(cause, "multicall");
127
+ logger?.error(error, "pool operation simulation failed");
128
+ return { status: "failure", error };
42
129
  }
43
- if (multicall.status === "fulfilled") {
44
- if (v1.status === "rejected") {
45
- logger?.debug(
46
- (0, import_errors.asPreviewSimulationError)(v1.reason, "eth_simulateV1"),
47
- "eth_simulateV1 flow failed; falling back to multicall result"
48
- );
130
+ }
131
+ function balanceLegs(operation, wallet, previewAmount) {
132
+ const { pool, receiver } = operation;
133
+ switch (operation.operation) {
134
+ case "Deposit":
135
+ return [
136
+ { address: wallet, token: operation.tokenIn, delta: -operation.assets },
137
+ { address: receiver, token: pool, delta: previewAmount }
138
+ ];
139
+ case "Mint":
140
+ return [
141
+ { address: wallet, token: operation.tokenIn, delta: -previewAmount },
142
+ { address: receiver, token: pool, delta: operation.shares }
143
+ ];
144
+ case "Withdraw":
145
+ return [
146
+ { address: operation.owner, token: pool, delta: -previewAmount },
147
+ {
148
+ address: receiver,
149
+ token: operation.tokenOut,
150
+ delta: operation.assets
151
+ }
152
+ ];
153
+ case "Redeem":
154
+ return [
155
+ { address: operation.owner, token: pool, delta: -operation.shares },
156
+ { address: receiver, token: operation.tokenOut, delta: previewAmount }
157
+ ];
158
+ }
159
+ }
160
+ function computePoolOpBalanceChanges(operation, wallet, previewAmount, before) {
161
+ const byAddress = new import_sdk.AddressMap();
162
+ for (const { address, token, delta } of balanceLegs(
163
+ operation,
164
+ wallet,
165
+ previewAmount
166
+ )) {
167
+ const beforeBalance = before(token, address);
168
+ const change = {
169
+ token,
170
+ before: beforeBalance,
171
+ after: beforeBalance + delta,
172
+ delta
173
+ };
174
+ const existing = byAddress.get(address);
175
+ if (existing) {
176
+ existing.changes.push(change);
177
+ } else {
178
+ byAddress.upsert(address, { address, changes: [change] });
49
179
  }
50
- return { status: "success", ...multicall.value };
51
180
  }
52
- const error = (0, import_errors.combinePreviewSimulationErrors)(
53
- v1.status === "rejected" ? (0, import_errors.asPreviewSimulationError)(v1.reason, "eth_simulateV1") : void 0,
54
- (0, import_errors.asPreviewSimulationError)(multicall.reason, "multicall")
55
- );
56
- logger?.error(error, "pool operation simulation failed");
57
- return { status: "failure", error };
181
+ return byAddress.values();
58
182
  }
59
183
  // Annotate the CommonJS export names for ESM import in node:
60
184
  0 && (module.exports = {
185
+ computePoolOpBalanceChanges,
61
186
  simulatePoolOperation
62
187
  });
@@ -81,6 +81,7 @@ class MultichainSDK {
81
81
  const perChainOpts = options?.perChain?.[network] ?? {};
82
82
  return sdk.attach({
83
83
  ...perChainOpts,
84
+ loadZappers: perChainOpts.loadZappers ?? options?.loadZappers,
84
85
  redstone: {
85
86
  ...options?.redstone,
86
87
  cache: this.#redstoneCache,
@@ -127,7 +127,8 @@ class OnchainSDK extends import_base.ChainContractsRegister {
127
127
  ignoreMarkets,
128
128
  marketConfigurators: mcs,
129
129
  redstone,
130
- pyth
130
+ pyth,
131
+ loadZappers
131
132
  } = options ?? {};
132
133
  const marketConfigurators = mcs ?? import_utils.TypedObjectUtils.keys(
133
134
  this.client.chain.defaultMarketConfigurators
@@ -196,6 +197,9 @@ class OnchainSDK extends import_base.ChainContractsRegister {
196
197
  blockNumber: this.currentBlock,
197
198
  gas: this.gasLimit
198
199
  });
200
+ if (loadZappers) {
201
+ await this.#marketRegister.loadZappers();
202
+ }
199
203
  }
200
204
  const pluginsList = import_utils.TypedObjectUtils.entries(this.plugins);
201
205
  const pluginResponse = await Promise.allSettled(
@@ -248,7 +252,7 @@ class OnchainSDK extends import_base.ChainContractsRegister {
248
252
  `address provider version: ${this.#addressProvider.version}`
249
253
  );
250
254
  this.#marketRegister = new import_MarketRegister.MarketRegister(this, ignoreMarkets);
251
- this.#marketRegister.hydrate(state.markets);
255
+ this.#marketRegister.hydrate(state);
252
256
  this.#rwa = new import_market.RWARegistry(this);
253
257
  this.#rwa.setState(state.rwa);
254
258
  for (const [name, plugin] of import_utils.TypedObjectUtils.entries(this.plugins)) {
@@ -313,7 +317,7 @@ class OnchainSDK extends import_base.ChainContractsRegister {
313
317
  currentBlock: this.currentBlock,
314
318
  timestamp: this.timestamp,
315
319
  addressProvider: this.addressProvider.state,
316
- markets: this.marketRegister.state,
320
+ ...this.marketRegister.state,
317
321
  rwa: this.#rwa.state,
318
322
  plugins: Object.fromEntries(
319
323
  import_utils.TypedObjectUtils.entries(this.plugins).map(([name, plugin]) => [
@@ -52,10 +52,11 @@ class MarketRegister extends import_ZapperRegister.ZapperRegister {
52
52
  * bypassing on-chain reads.
53
53
  * @param state - Array of market data snapshots.
54
54
  **/
55
- hydrate(state) {
56
- const configurators = new Set(state.map((m) => m.configurator));
55
+ hydrate({ markets, zappers }) {
56
+ const configurators = new Set(markets.map((m) => m.configurator));
57
57
  this.#setMarketFilter([...configurators]);
58
- this.#setMarkets(state);
58
+ this.#setMarkets(markets);
59
+ this.hydrateZappers(zappers);
59
60
  }
60
61
  /**
61
62
  * @internal
@@ -174,7 +175,10 @@ class MarketRegister extends import_ZapperRegister.ZapperRegister {
174
175
  * Serializable snapshot of all loaded markets, suitable for hydration.
175
176
  **/
176
177
  get state() {
177
- return this.markets.map((market) => market.state);
178
+ return {
179
+ markets: this.markets.map((market) => market.state),
180
+ zappers: this.zappersState
181
+ };
178
182
  }
179
183
  /**
180
184
  * Returns a human-readable snapshot of all markets.
@@ -182,7 +186,8 @@ class MarketRegister extends import_ZapperRegister.ZapperRegister {
182
186
  **/
183
187
  stateHuman(raw = true) {
184
188
  return {
185
- markets: this.markets.map((market) => market.stateHuman(raw))
189
+ markets: this.markets.map((market) => market.stateHuman(raw)),
190
+ zappers: this.zappersStateHuman(raw)
186
191
  };
187
192
  }
188
193
  /**