@continuumdao/ctm-mpc-defi 0.2.0 → 0.2.1
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.
- package/README.md +20 -78
- package/dist/agent/catalog.cjs +511 -4
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +140 -20
- package/dist/agent/catalog.js +501 -6
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/aave-v4/SKILL.md +43 -0
- package/dist/agent/skills/curve-dao/SKILL.md +12 -0
- package/dist/agent/skills/ethena/SKILL.md +10 -0
- package/dist/agent/skills/euler-v2/SKILL.md +10 -0
- package/dist/agent/skills/lido/SKILL.md +22 -0
- package/dist/agent/skills/maple-syrup/SKILL.md +10 -0
- package/dist/agent/skills/sky/SKILL.md +10 -0
- package/dist/agent/skills/uniswap-v4/SKILL.md +22 -0
- package/dist/chains/evm/index.cjs +27 -226
- package/dist/chains/evm/index.cjs.map +1 -1
- package/dist/chains/evm/index.d.ts +14 -26
- package/dist/chains/evm/index.js +21 -211
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/chains/near/index.d.ts +1 -1
- package/dist/chains/solana/index.d.ts +1 -1
- package/dist/core/index.cjs +8 -110
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +5 -39
- package/dist/core/index.js +6 -100
- package/dist/core/index.js.map +1 -1
- package/dist/{envelope-CcE5Cz_q.d.ts → envelope-CpBUh9eP.d.ts} +1 -1
- package/dist/index.cjs +238 -1868
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -11
- package/dist/index.js +227 -1839
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aave-v4/index.cjs +385 -662
- package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/aave-v4/index.d.ts +1 -2
- package/dist/protocols/evm/aave-v4/index.js +385 -662
- package/dist/protocols/evm/aave-v4/index.js.map +1 -1
- package/dist/protocols/evm/curve-dao/index.cjs +24 -124
- package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/curve-dao/index.d.ts +3 -4
- package/dist/protocols/evm/curve-dao/index.js +15 -115
- package/dist/protocols/evm/curve-dao/index.js.map +1 -1
- package/dist/protocols/evm/ethena/index.cjs +290 -402
- package/dist/protocols/evm/ethena/index.cjs.map +1 -1
- package/dist/protocols/evm/ethena/index.d.ts +1 -2
- package/dist/protocols/evm/ethena/index.js +291 -403
- package/dist/protocols/evm/ethena/index.js.map +1 -1
- package/dist/protocols/evm/euler-v2/index.cjs +485 -1163
- package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
- package/dist/protocols/evm/euler-v2/index.d.ts +1 -2
- package/dist/protocols/evm/euler-v2/index.js +486 -1164
- package/dist/protocols/evm/euler-v2/index.js.map +1 -1
- package/dist/protocols/evm/lido/index.cjs +241 -236
- package/dist/protocols/evm/lido/index.cjs.map +1 -1
- package/dist/protocols/evm/lido/index.d.ts +1 -2
- package/dist/protocols/evm/lido/index.js +242 -237
- package/dist/protocols/evm/lido/index.js.map +1 -1
- package/dist/protocols/evm/maple/index.cjs +310 -398
- package/dist/protocols/evm/maple/index.cjs.map +1 -1
- package/dist/protocols/evm/maple/index.d.ts +1 -2
- package/dist/protocols/evm/maple/index.js +311 -399
- package/dist/protocols/evm/maple/index.js.map +1 -1
- package/dist/protocols/evm/sky/index.cjs +238 -233
- package/dist/protocols/evm/sky/index.cjs.map +1 -1
- package/dist/protocols/evm/sky/index.d.ts +1 -2
- package/dist/protocols/evm/sky/index.js +236 -231
- package/dist/protocols/evm/sky/index.js.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs +423 -658
- package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.d.ts +3 -4
- package/dist/protocols/evm/uniswap-v4/index.js +422 -657
- package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
- package/dist/{registry-oMKlO_5z.d.ts → registry-Bv5o37_w.d.ts} +1 -1
- package/dist/{types-Ce2qNHai.d.cts → types-BfjWdw1j.d.ts} +3 -1
- package/dist/{types-5u863Fd9.d.ts → types-DUeNJLr9.d.ts} +1 -1
- package/package.json +7 -6
- package/dist/agent/catalog.d.cts +0 -939
- package/dist/chains/evm/index.d.cts +0 -64
- package/dist/chains/near/index.d.cts +0 -37
- package/dist/chains/solana/index.d.cts +0 -40
- package/dist/core/index.d.cts +0 -43
- package/dist/envelope-DYDPnrHZ.d.cts +0 -35
- package/dist/index.d.cts +0 -16
- package/dist/keygen-CfNp8yKJ.d.cts +0 -9
- package/dist/keygen-DsINazx8.d.ts +0 -9
- package/dist/nodeRead-BnmSaMGO.d.cts +0 -8
- package/dist/nodeRead-BnmSaMGO.d.ts +0 -8
- package/dist/protocols/evm/aave-v4/index.d.cts +0 -500
- package/dist/protocols/evm/curve-dao/index.d.cts +0 -147
- package/dist/protocols/evm/ethena/index.d.cts +0 -161
- package/dist/protocols/evm/euler-v2/index.d.cts +0 -317
- package/dist/protocols/evm/lido/index.d.cts +0 -120
- package/dist/protocols/evm/maple/index.d.cts +0 -109
- package/dist/protocols/evm/sky/index.d.cts +0 -218
- package/dist/protocols/evm/uniswap-v4/index.d.cts +0 -324
- package/dist/registry-BwZoE668.d.cts +0 -8
- package/dist/txParams-BC7ogvdR.d.cts +0 -19
- package/dist/txParams-BC7ogvdR.d.ts +0 -19
- package/dist/types-B8idm_gu.d.cts +0 -34
- package/dist/types-Ce2qNHai.d.ts +0 -57
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var viem = require('viem');
|
|
4
|
+
var continuumNodeSdk = require('@continuumdao/continuum-node-sdk');
|
|
4
5
|
|
|
5
6
|
// src/core/registry.ts
|
|
6
7
|
var modules = [];
|
|
@@ -87,98 +88,238 @@ function eulerSameAssetApproveAmountWithBuffer(args) {
|
|
|
87
88
|
return args.totalPullWei + extra + 1n;
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
// src/core/
|
|
91
|
-
function
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
// src/core/purpose.ts
|
|
92
|
+
function mergePurposeText(purposeText, purposeSuffix) {
|
|
93
|
+
const t = purposeText.trim();
|
|
94
|
+
const suffix = (purposeSuffix ?? "").trim();
|
|
95
|
+
if (!suffix) return t;
|
|
96
|
+
return t ? `${t}
|
|
97
|
+
|
|
98
|
+
${suffix}` : suffix;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
// src/
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
// src/core/envelope.ts
|
|
102
|
+
function finalizeMultisign(input) {
|
|
103
|
+
const { keyGen, destinationChainID, legs } = input;
|
|
104
|
+
if (legs.length === 0) {
|
|
105
|
+
throw new Error("finalizeMultisign requires at least one leg");
|
|
106
|
+
}
|
|
107
|
+
const ph = (keyGen.pubkeyhex ?? "").trim();
|
|
108
|
+
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
109
|
+
const keyList = keyGen.keylist ?? [];
|
|
110
|
+
const clientId = continuumNodeSdk.getClientIdFromKeyGenResult(keyGen);
|
|
111
|
+
const first = legs[0];
|
|
112
|
+
const messageHashes = legs.map((l) => l.msgHash);
|
|
113
|
+
const messageRawBatch = legs.map((l) => l.msgRaw);
|
|
114
|
+
const batchMeta = legs.map((l) => ({
|
|
115
|
+
destinationAddress: l.destinationAddress,
|
|
116
|
+
signatureText: l.signatureText,
|
|
117
|
+
...l.audit
|
|
118
|
+
}));
|
|
119
|
+
const proposalTxParams = legs.map((l) => l.proposalTxParams).filter((p) => p != null && typeof p === "object");
|
|
120
|
+
const extraPayload = {
|
|
121
|
+
batchMeta,
|
|
122
|
+
...input.extraJSON ?? {}
|
|
123
|
+
};
|
|
124
|
+
const extraJSON = JSON.stringify(extraPayload);
|
|
125
|
+
const bodyForSign = {
|
|
126
|
+
keyList,
|
|
127
|
+
pubKey: ph,
|
|
128
|
+
msgHash: messageHashes[0],
|
|
129
|
+
msgRaw: first.msgRaw,
|
|
130
|
+
destinationChainID,
|
|
131
|
+
destinationAddress: input.destinationAddress ?? first.destinationAddress,
|
|
132
|
+
extraJSON,
|
|
133
|
+
signatureText: first.signatureText,
|
|
134
|
+
purpose: mergePurposeText(input.purposeText, input.purposeSuffix),
|
|
135
|
+
...first.feeSnapshot
|
|
136
|
+
};
|
|
137
|
+
if (legs.length > 1) {
|
|
138
|
+
bodyForSign.messageHashes = messageHashes;
|
|
139
|
+
bodyForSign.messageRawBatch = messageRawBatch;
|
|
140
|
+
}
|
|
141
|
+
if (proposalTxParams.length > 0) {
|
|
142
|
+
bodyForSign.proposalTxParams = proposalTxParams;
|
|
143
|
+
}
|
|
144
|
+
const valueWei = first.valueWei;
|
|
145
|
+
if (valueWei != null && valueWei > 0n) {
|
|
146
|
+
bodyForSign.value = valueWei.toString();
|
|
147
|
+
}
|
|
148
|
+
if (clientId) bodyForSign.clientId = clientId;
|
|
149
|
+
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
150
|
+
}
|
|
151
|
+
function routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimit) {
|
|
152
|
+
if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {
|
|
153
|
+
return continuumNodeSdk.gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit);
|
|
104
154
|
}
|
|
105
|
-
|
|
106
|
-
return cfg > estimatedGas ? cfg : estimatedGas;
|
|
155
|
+
return (estimatedGas * 12n + 9n) / 10n;
|
|
107
156
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
157
|
+
|
|
158
|
+
// src/chains/evm/buildBatch.ts
|
|
159
|
+
async function buildEvmMultisignBatch(args) {
|
|
160
|
+
const { context, steps } = args;
|
|
161
|
+
const {
|
|
162
|
+
chainId,
|
|
163
|
+
rpcUrl,
|
|
164
|
+
executorAddress,
|
|
165
|
+
chainDetail,
|
|
166
|
+
useCustomGas,
|
|
167
|
+
customGasChainDetails,
|
|
168
|
+
keyGen,
|
|
169
|
+
purposeText
|
|
170
|
+
} = context;
|
|
171
|
+
if (steps.length === 0) throw new Error("buildEvmMultisignBatch requires at least one step");
|
|
172
|
+
const ch = viem.defineChain({
|
|
173
|
+
id: chainId,
|
|
174
|
+
name: "Destination",
|
|
116
175
|
nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
|
|
117
|
-
rpcUrls: { default: { http: [
|
|
176
|
+
rpcUrls: { default: { http: [rpcUrl] } }
|
|
118
177
|
});
|
|
119
|
-
const publicClient = viem.createPublicClient({
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
});
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
178
|
+
const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpcUrl) });
|
|
179
|
+
const feeParams = await continuumNodeSdk.fetchChainFeeParams(rpcUrl, chainId);
|
|
180
|
+
const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559;
|
|
181
|
+
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
182
|
+
const gasLimitConfig = useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : void 0;
|
|
183
|
+
const chainGasLimitRouter = chainDetail?.gasLimit != null && Number.isFinite(Number(chainDetail.gasLimit)) && Number(chainDetail.gasLimit) > 0 ? Number(chainDetail.gasLimit) : void 0;
|
|
184
|
+
const gasFeeMultiplier = useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : void 0;
|
|
185
|
+
const executor = viem.getAddress(executorAddress);
|
|
186
|
+
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
187
|
+
const legs = [];
|
|
188
|
+
for (let i = 0; i < steps.length; i++) {
|
|
189
|
+
const step = steps[i];
|
|
190
|
+
const currentNonce = baseNonce + i;
|
|
191
|
+
let estimatedGas;
|
|
192
|
+
if (args.estimateGasForStep) {
|
|
193
|
+
estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor });
|
|
194
|
+
} else {
|
|
195
|
+
try {
|
|
196
|
+
estimatedGas = await publicClient.estimateGas({
|
|
197
|
+
to: step.to,
|
|
198
|
+
data: step.data,
|
|
199
|
+
value: step.value,
|
|
200
|
+
account: executor
|
|
201
|
+
});
|
|
202
|
+
} catch {
|
|
203
|
+
estimatedGas = step.fallbackGas ?? 100000n;
|
|
204
|
+
}
|
|
133
205
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
206
|
+
let gasLimitI;
|
|
207
|
+
if (args.resolveGasLimit) {
|
|
208
|
+
gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient });
|
|
209
|
+
} else if (step.routerSwap) {
|
|
210
|
+
gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter);
|
|
211
|
+
} else {
|
|
212
|
+
gasLimitI = useCustomGas ? continuumNodeSdk.gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
140
213
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
214
|
+
let proposalTxParams;
|
|
215
|
+
let feeSnapshot;
|
|
216
|
+
let serialized;
|
|
217
|
+
if (legacy) {
|
|
218
|
+
let gasPriceWei = await publicClient.getGasPrice();
|
|
219
|
+
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
220
|
+
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
221
|
+
}
|
|
222
|
+
if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {
|
|
223
|
+
const configured = viem.parseGwei(continuumNodeSdk.gweiToDecimalString(Number(chainDetail.gasPrice)));
|
|
224
|
+
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
225
|
+
}
|
|
226
|
+
serialized = viem.serializeTransaction({
|
|
227
|
+
type: "legacy",
|
|
228
|
+
to: step.to,
|
|
229
|
+
data: step.data,
|
|
230
|
+
value: step.value,
|
|
231
|
+
gas: gasLimitI,
|
|
232
|
+
gasPrice: gasPriceWei,
|
|
233
|
+
nonce: currentNonce,
|
|
234
|
+
chainId
|
|
235
|
+
});
|
|
236
|
+
proposalTxParams = {
|
|
237
|
+
nonce: currentNonce,
|
|
238
|
+
gasLimit: gasLimitI.toString(),
|
|
239
|
+
txType: "legacy",
|
|
240
|
+
gasPrice: gasPriceWei.toString()
|
|
241
|
+
};
|
|
242
|
+
feeSnapshot = continuumNodeSdk.proposalTxParamsToFeeSnapshot(proposalTxParams);
|
|
243
|
+
} else {
|
|
244
|
+
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
245
|
+
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
246
|
+
const configuredBase = useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0;
|
|
247
|
+
const configuredPriority = useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0;
|
|
248
|
+
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
249
|
+
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
250
|
+
const baseFeeMultiplierPct = useCustomGas && chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(chainDetail.baseFeeMultiplier)) : 100;
|
|
251
|
+
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
252
|
+
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
253
|
+
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(continuumNodeSdk.gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
254
|
+
let maxFeePerGas = viem.parseGwei(continuumNodeSdk.gweiToDecimalString(maxFeePerGasGwei));
|
|
255
|
+
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
256
|
+
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
257
|
+
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
258
|
+
}
|
|
259
|
+
({ maxFeePerGas, maxPriorityFeePerGas } = continuumNodeSdk.alignEip1559FeesWithLatestBase(
|
|
260
|
+
maxFeePerGas,
|
|
261
|
+
maxPriorityFeePerGas,
|
|
262
|
+
latestBaseFeeWei
|
|
263
|
+
));
|
|
264
|
+
serialized = viem.serializeTransaction({
|
|
265
|
+
type: "eip1559",
|
|
266
|
+
to: step.to,
|
|
267
|
+
data: step.data,
|
|
268
|
+
value: step.value,
|
|
269
|
+
gas: gasLimitI,
|
|
270
|
+
maxFeePerGas,
|
|
271
|
+
maxPriorityFeePerGas,
|
|
272
|
+
nonce: currentNonce,
|
|
273
|
+
chainId
|
|
274
|
+
});
|
|
275
|
+
proposalTxParams = {
|
|
276
|
+
nonce: currentNonce,
|
|
277
|
+
gasLimit: gasLimitI.toString(),
|
|
278
|
+
txType: "eip1559",
|
|
279
|
+
maxFeePerGas: maxFeePerGas.toString(),
|
|
280
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
281
|
+
};
|
|
282
|
+
feeSnapshot = i === 0 ? continuumNodeSdk.proposalTxParamsToFeeSnapshot(proposalTxParams) : {};
|
|
283
|
+
}
|
|
284
|
+
const h = viem.keccak256(serialized);
|
|
285
|
+
const msgHash = h.startsWith("0x") ? h.slice(2) : h;
|
|
286
|
+
const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI });
|
|
287
|
+
legs.push({
|
|
288
|
+
msgHash,
|
|
289
|
+
msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,
|
|
290
|
+
destinationAddress: step.to,
|
|
291
|
+
signatureText: typeof batchMetaExtra.signatureText === "string" ? batchMetaExtra.signatureText : JSON.stringify(batchMetaExtra.signatureText ?? {}),
|
|
292
|
+
audit: batchMetaExtra,
|
|
293
|
+
feeSnapshot: i === 0 ? feeSnapshot : {},
|
|
294
|
+
proposalTxParams,
|
|
295
|
+
valueWei: i === 0 ? step.value : void 0
|
|
296
|
+
});
|
|
297
|
+
if (i === 0 && args.firstMsgRawNo0x != null) {
|
|
298
|
+
legs[0].msgRaw = args.firstMsgRawNo0x;
|
|
155
299
|
}
|
|
156
300
|
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
let maxF = maxFeePerGas;
|
|
161
|
-
if (baseWei > 0n && maxF < baseWei + maxP) {
|
|
162
|
-
maxF = baseWei + maxP + viem.parseGwei("0.001");
|
|
301
|
+
const extraJSON = {};
|
|
302
|
+
if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {
|
|
303
|
+
extraJSON.customGasChainDetails = customGasChainDetails;
|
|
163
304
|
}
|
|
164
|
-
|
|
165
|
-
|
|
305
|
+
const result = finalizeMultisign({
|
|
306
|
+
keyGen,
|
|
307
|
+
purposeText,
|
|
308
|
+
purposeSuffix: args.purposeSuffix,
|
|
309
|
+
destinationChainID: String(chainId),
|
|
310
|
+
destinationAddress: args.destinationAddress ?? steps[0].to,
|
|
311
|
+
legs,
|
|
312
|
+
extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0
|
|
313
|
+
});
|
|
314
|
+
const pv = args.payableValueWei;
|
|
315
|
+
if (pv != null && pv > 0n) {
|
|
316
|
+
result.bodyForSign.value = pv.toString();
|
|
166
317
|
}
|
|
167
|
-
return
|
|
168
|
-
}
|
|
169
|
-
function alignEip1559FeesWithLatestBase(maxFeePerGas, maxPriorityFeePerGas, latestBlockBaseFeeWei) {
|
|
170
|
-
return finalizeEip1559Fees(maxFeePerGas, maxPriorityFeePerGas, null, latestBlockBaseFeeWei);
|
|
318
|
+
return result;
|
|
171
319
|
}
|
|
172
320
|
|
|
173
321
|
// src/protocols/evm/euler-v2/vaultWithdrawMultisign.ts
|
|
174
322
|
var EULER_V2_VAULT_WITHDRAW_FALLBACK_GAS = 900000n;
|
|
175
|
-
function gweiToDecimalString(n) {
|
|
176
|
-
if (!Number.isFinite(n)) return "0";
|
|
177
|
-
if (n === 0) return "0";
|
|
178
|
-
const s = String(n);
|
|
179
|
-
if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
|
|
180
|
-
return s;
|
|
181
|
-
}
|
|
182
323
|
var erc20DecimalsAbi = viem.parseAbi(["function decimals() view returns (uint8)"]);
|
|
183
324
|
var erc4626AssetAbi = viem.parseAbi(["function asset() view returns (address)"]);
|
|
184
325
|
var erc4626MaxWithdrawAbi = viem.parseAbi(["function maxWithdraw(address owner) view returns (uint256)"]);
|
|
@@ -349,157 +490,7 @@ async function fetchEulerLendEarnVaultEffectiveMaxWithdrawWei(args) {
|
|
|
349
490
|
txSender
|
|
350
491
|
});
|
|
351
492
|
}
|
|
352
|
-
async function eulerMultisignBodyOneStep(args) {
|
|
353
|
-
const ch = viem.defineChain({
|
|
354
|
-
id: args.chainId,
|
|
355
|
-
name: "Destination",
|
|
356
|
-
nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
|
|
357
|
-
rpcUrls: { default: { http: [args.rpcUrl] } }
|
|
358
|
-
});
|
|
359
|
-
const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(args.rpcUrl) });
|
|
360
|
-
const feeParams = await fetchChainFeeParams(args.rpcUrl, args.chainId);
|
|
361
|
-
const legacy = Boolean(args.chainDetail?.legacy) || !feeParams.isEip1559;
|
|
362
|
-
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
363
|
-
const useCustomGas = args.useCustomGas;
|
|
364
|
-
const gasLimitConfig = useCustomGas && args.chainDetail?.gasLimit != null ? Number(args.chainDetail.gasLimit) : void 0;
|
|
365
|
-
const gasFeeMultiplier = useCustomGas && args.chainDetail?.gasMultiplier != null ? Number(args.chainDetail.gasMultiplier) : void 0;
|
|
366
|
-
const baseNonce = await publicClient.getTransactionCount({ address: args.executorAddress, blockTag: "pending" });
|
|
367
|
-
let estimatedGas;
|
|
368
|
-
try {
|
|
369
|
-
estimatedGas = await publicClient.estimateGas({
|
|
370
|
-
to: args.to,
|
|
371
|
-
data: args.data,
|
|
372
|
-
value: args.value,
|
|
373
|
-
account: args.executorAddress
|
|
374
|
-
});
|
|
375
|
-
} catch {
|
|
376
|
-
estimatedGas = args.estimateGasFallback;
|
|
377
|
-
}
|
|
378
|
-
const gasLimitI = useCustomGas ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
379
|
-
const batchMeta0 = args.buildBatchMeta({ gasLimit: gasLimitI });
|
|
380
|
-
let firstTxFeePayload = {};
|
|
381
|
-
let firstDataNo0x = "";
|
|
382
|
-
const messageHashes = [];
|
|
383
|
-
const messageRawBatch = [];
|
|
384
|
-
const proposalTxParamsBatch = [];
|
|
385
|
-
const vTo = args.to;
|
|
386
|
-
const vData = args.data;
|
|
387
|
-
const vValue = args.value;
|
|
388
|
-
if (legacy) {
|
|
389
|
-
let gasPriceWei = await publicClient.getGasPrice();
|
|
390
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
391
|
-
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
392
|
-
}
|
|
393
|
-
if (useCustomGas && args.chainDetail?.gasPrice != null && args.chainDetail.gasPrice > 0) {
|
|
394
|
-
const configured = viem.parseGwei(gweiToDecimalString(Number(args.chainDetail.gasPrice)));
|
|
395
|
-
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
396
|
-
}
|
|
397
|
-
const ser = viem.serializeTransaction({
|
|
398
|
-
type: "legacy",
|
|
399
|
-
to: vTo,
|
|
400
|
-
data: vData,
|
|
401
|
-
value: vValue,
|
|
402
|
-
gas: gasLimitI,
|
|
403
|
-
gasPrice: gasPriceWei,
|
|
404
|
-
nonce: baseNonce,
|
|
405
|
-
chainId: args.chainId
|
|
406
|
-
});
|
|
407
|
-
const h = viem.keccak256(ser);
|
|
408
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
409
|
-
messageRawBatch.push(ser);
|
|
410
|
-
proposalTxParamsBatch.push({
|
|
411
|
-
nonce: baseNonce,
|
|
412
|
-
gasLimit: gasLimitI.toString(),
|
|
413
|
-
txType: "legacy",
|
|
414
|
-
gasPrice: gasPriceWei.toString()
|
|
415
|
-
});
|
|
416
|
-
firstTxFeePayload = { txNonce: baseNonce, txGasLimit: gasLimitI.toString(), txGasPrice: gasPriceWei.toString() };
|
|
417
|
-
firstDataNo0x = vData.startsWith("0x") ? vData.slice(2) : vData;
|
|
418
|
-
} else {
|
|
419
|
-
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
420
|
-
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
421
|
-
const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
422
|
-
const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
423
|
-
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
424
|
-
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
425
|
-
const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
426
|
-
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
427
|
-
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
428
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
429
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString(maxFeePerGasGwei));
|
|
430
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
431
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
432
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
433
|
-
}
|
|
434
|
-
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
435
|
-
maxFeePerGas,
|
|
436
|
-
maxPriorityFeePerGas,
|
|
437
|
-
latestBaseFeeWei
|
|
438
|
-
));
|
|
439
|
-
const ser = viem.serializeTransaction({
|
|
440
|
-
type: "eip1559",
|
|
441
|
-
to: vTo,
|
|
442
|
-
data: vData,
|
|
443
|
-
value: vValue,
|
|
444
|
-
gas: gasLimitI,
|
|
445
|
-
maxFeePerGas,
|
|
446
|
-
maxPriorityFeePerGas,
|
|
447
|
-
nonce: baseNonce,
|
|
448
|
-
chainId: args.chainId
|
|
449
|
-
});
|
|
450
|
-
const h = viem.keccak256(ser);
|
|
451
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
452
|
-
messageRawBatch.push(ser);
|
|
453
|
-
proposalTxParamsBatch.push({
|
|
454
|
-
nonce: baseNonce,
|
|
455
|
-
gasLimit: gasLimitI.toString(),
|
|
456
|
-
txType: "eip1559",
|
|
457
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
458
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
459
|
-
});
|
|
460
|
-
firstTxFeePayload = {
|
|
461
|
-
txNonce: baseNonce,
|
|
462
|
-
txGasLimit: gasLimitI.toString(),
|
|
463
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
464
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
465
|
-
};
|
|
466
|
-
firstDataNo0x = vData.startsWith("0x") ? vData.slice(2) : vData;
|
|
467
|
-
}
|
|
468
|
-
const extraPayload = { batchMeta: [batchMeta0] };
|
|
469
|
-
if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
|
|
470
|
-
extraPayload.customGasChainDetails = args.customGasChainDetails;
|
|
471
|
-
}
|
|
472
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
473
|
-
const firstSigText = batchMeta0.signatureText;
|
|
474
|
-
const bodyForSign = {
|
|
475
|
-
keyList: args.keyList,
|
|
476
|
-
pubKey: args.ph,
|
|
477
|
-
msgHash: messageHashes[0],
|
|
478
|
-
msgRaw: firstDataNo0x,
|
|
479
|
-
messageHashes,
|
|
480
|
-
messageRawBatch,
|
|
481
|
-
destinationChainID: String(args.chainId),
|
|
482
|
-
destinationAddress: vTo,
|
|
483
|
-
extraJSON,
|
|
484
|
-
signatureText: firstSigText,
|
|
485
|
-
purpose: (() => {
|
|
486
|
-
const t = args.purposeText.trim();
|
|
487
|
-
return (t ? `${t}
|
|
488
|
-
|
|
489
|
-
` : "") + args.purposeSuffix;
|
|
490
|
-
})(),
|
|
491
|
-
...firstTxFeePayload,
|
|
492
|
-
proposalTxParams: proposalTxParamsBatch
|
|
493
|
-
};
|
|
494
|
-
if (vValue > 0n) bodyForSign.value = vValue.toString();
|
|
495
|
-
if (args.clientId) bodyForSign.clientId = args.clientId;
|
|
496
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
497
|
-
}
|
|
498
493
|
async function buildEvmMultisignBodyEulerV2VaultWithdraw(args) {
|
|
499
|
-
const ph = (args.keyGen.pubkeyhex ?? "").trim();
|
|
500
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
501
|
-
const keyList = args.keyGen.keylist ?? [];
|
|
502
|
-
const clientId = firstClientIdFromKeyGen(args.keyGen);
|
|
503
494
|
const evault = viem.getAddress(args.evault);
|
|
504
495
|
const receiver = viem.getAddress(args.owner);
|
|
505
496
|
const shareOwner = viem.getAddress(args.vaultShareOwner ?? args.owner);
|
|
@@ -524,24 +515,32 @@ async function buildEvmMultisignBodyEulerV2VaultWithdraw(args) {
|
|
|
524
515
|
});
|
|
525
516
|
const vaultLabel = (args.vaultMarketLabel ?? "").trim() || "Euler vault";
|
|
526
517
|
const purposeSuffix = `Euler v2: 1-tx \u2014 eVault.withdraw (${args.amountHuman} underlying) from isolated vault "${vaultLabel}" (ERC-4626).`;
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
518
|
+
const evmSteps = [
|
|
519
|
+
{
|
|
520
|
+
to: evault,
|
|
521
|
+
data: withdrawData,
|
|
522
|
+
value: 0n,
|
|
523
|
+
fallbackGas: EULER_V2_VAULT_WITHDRAW_FALLBACK_GAS
|
|
524
|
+
}
|
|
525
|
+
];
|
|
526
|
+
const firstDataNo0x = withdrawData.startsWith("0x") ? withdrawData.slice(2) : withdrawData;
|
|
527
|
+
return buildEvmMultisignBatch({
|
|
528
|
+
context: {
|
|
529
|
+
chainCategory: "evm",
|
|
530
|
+
keyGen: args.keyGen,
|
|
531
|
+
purposeText: args.purposeText,
|
|
532
|
+
chainId: args.chainId,
|
|
533
|
+
rpcUrl: args.rpcUrl,
|
|
534
|
+
executorAddress: executor,
|
|
535
|
+
chainDetail: args.chainDetail,
|
|
536
|
+
useCustomGas: args.useCustomGas,
|
|
537
|
+
customGasChainDetails: args.customGasChainDetails
|
|
538
|
+
},
|
|
539
|
+
steps: evmSteps,
|
|
537
540
|
purposeSuffix,
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
value: 0n,
|
|
542
|
-
estimateGasFallback: EULER_V2_VAULT_WITHDRAW_FALLBACK_GAS,
|
|
543
|
-
buildBatchMeta: (ctx) => ({
|
|
544
|
-
destinationAddress: evault,
|
|
541
|
+
firstMsgRawNo0x: firstDataNo0x,
|
|
542
|
+
destinationAddress: evault,
|
|
543
|
+
buildBatchMeta: ({ gasLimit }) => ({
|
|
545
544
|
signatureText: JSON.stringify({
|
|
546
545
|
kind: "EulerV2",
|
|
547
546
|
name: "EVault.withdraw",
|
|
@@ -558,7 +557,7 @@ async function buildEvmMultisignBodyEulerV2VaultWithdraw(args) {
|
|
|
558
557
|
amountHuman: args.amountHuman,
|
|
559
558
|
evault,
|
|
560
559
|
owner: shareOwner,
|
|
561
|
-
gasBuildWithdraw: { baseGasUnits:
|
|
560
|
+
gasBuildWithdraw: { baseGasUnits: gasLimit.toString() }
|
|
562
561
|
}
|
|
563
562
|
})
|
|
564
563
|
});
|
|
@@ -699,16 +698,6 @@ var EULER_V2_ISOLATED_VAULT_DEPOSIT_FALLBACK_GAS = 950000n;
|
|
|
699
698
|
var EULER_VAULT_DEPOSIT_ESTIMATE_FALLBACK = EULER_V2_ISOLATED_VAULT_DEPOSIT_FALLBACK_GAS;
|
|
700
699
|
var EULER_ERC20_APPROVE_FALLBACK = 100000n;
|
|
701
700
|
var EULER_WETH_DEPOSIT_FALLBACK = 120000n;
|
|
702
|
-
function gweiToDecimalString2(n) {
|
|
703
|
-
if (!Number.isFinite(n)) return "0";
|
|
704
|
-
if (n === 0) return "0";
|
|
705
|
-
const s = String(n);
|
|
706
|
-
if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
|
|
707
|
-
return s;
|
|
708
|
-
}
|
|
709
|
-
function txToViemStep(tx) {
|
|
710
|
-
return { to: viem.getAddress(tx.to), data: tx.data, value: tx.value };
|
|
711
|
-
}
|
|
712
701
|
var wethDepositAbi = viem.parseAbi(["function deposit() payable"]);
|
|
713
702
|
var erc20AllowanceAbi = viem.parseAbi([
|
|
714
703
|
"function allowance(address owner, address spender) view returns (uint256)",
|
|
@@ -719,10 +708,6 @@ var erc4626DepositAbi = viem.parseAbi([
|
|
|
719
708
|
"function deposit(uint256 assets, address receiver) returns (uint256 shares)"
|
|
720
709
|
]);
|
|
721
710
|
async function buildEvmMultisignBodyEulerV2IsolatedLendDepositBatch(args) {
|
|
722
|
-
const ph = (args.keyGen.pubkeyhex ?? "").trim();
|
|
723
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
724
|
-
const keyList = args.keyGen.keylist ?? [];
|
|
725
|
-
const clientId = firstClientIdFromKeyGen(args.keyGen);
|
|
726
711
|
const asset = viem.getAddress(args.underlying);
|
|
727
712
|
const evault = viem.getAddress(args.evault);
|
|
728
713
|
const weth = viem.getAddress(args.nativeWrapped);
|
|
@@ -801,154 +786,79 @@ async function buildEvmMultisignBodyEulerV2IsolatedLendDepositBatch(args) {
|
|
|
801
786
|
args: [amountWei, receiver]
|
|
802
787
|
});
|
|
803
788
|
steps.push({ kind: "vault_deposit", to: evault, data: depositData, value: 0n });
|
|
804
|
-
const feeParams = await fetchChainFeeParams(args.rpcUrl, args.chainId);
|
|
805
|
-
const legacy = Boolean(args.chainDetail?.legacy) || !feeParams.isEip1559;
|
|
806
|
-
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
807
|
-
const useCustomGas = args.useCustomGas;
|
|
808
|
-
const gasLimitConfig = useCustomGas && args.chainDetail?.gasLimit != null ? Number(args.chainDetail.gasLimit) : void 0;
|
|
809
|
-
const gasFeeMultiplier = useCustomGas && args.chainDetail?.gasMultiplier != null ? Number(args.chainDetail.gasMultiplier) : void 0;
|
|
810
|
-
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
811
|
-
const messageHashes = [];
|
|
812
|
-
const messageRawBatch = [];
|
|
813
|
-
const proposalTxParamsBatch = [];
|
|
814
|
-
const batchMeta = [];
|
|
815
|
-
let firstTxFeePayload = {};
|
|
816
|
-
let firstDataNo0x = "";
|
|
817
789
|
const vaultLabel = (args.vaultMarketLabel ?? "").trim() || "Euler vault";
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
});
|
|
830
|
-
} catch {
|
|
831
|
-
if (s.kind === "weth_deposit") estimatedGas = EULER_WETH_DEPOSIT_FALLBACK;
|
|
832
|
-
else if (s.kind === "approve") estimatedGas = EULER_ERC20_APPROVE_FALLBACK;
|
|
833
|
-
else estimatedGas = EULER_VAULT_DEPOSIT_ESTIMATE_FALLBACK;
|
|
790
|
+
const evmSteps = steps.map((s) => ({
|
|
791
|
+
to: s.to,
|
|
792
|
+
data: s.data,
|
|
793
|
+
value: s.value,
|
|
794
|
+
fallbackGas: s.kind === "weth_deposit" ? EULER_WETH_DEPOSIT_FALLBACK : s.kind === "approve" ? EULER_ERC20_APPROVE_FALLBACK : EULER_VAULT_DEPOSIT_ESTIMATE_FALLBACK
|
|
795
|
+
}));
|
|
796
|
+
const n = steps.length;
|
|
797
|
+
const hasWrap = args.isNativeIn;
|
|
798
|
+
const purposeSuffix = (() => {
|
|
799
|
+
if (hasWrap) {
|
|
800
|
+
return `Euler v2: ${n}-tx batch \u2014 wrap native to WETH (if needed), approve eVault for the exact amount, then ERC-4626 deposit into isolated vault "${vaultLabel}".`;
|
|
834
801
|
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString2(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
879
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString2(maxFeePerGasGwei));
|
|
880
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
881
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
882
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
802
|
+
if (n === 1) {
|
|
803
|
+
return `Euler v2: 1-tx \u2014 eVault.deposit (allowance already sufficient) into "${vaultLabel}".`;
|
|
804
|
+
}
|
|
805
|
+
return `Euler v2: ${n}-tx batch \u2014 approve eVault for the exact amount, then ERC-4626 deposit into "${vaultLabel}".`;
|
|
806
|
+
})();
|
|
807
|
+
const firstDataNo0x = evmSteps[0].data.startsWith("0x") ? evmSteps[0].data.slice(2) : evmSteps[0].data;
|
|
808
|
+
return buildEvmMultisignBatch({
|
|
809
|
+
context: {
|
|
810
|
+
chainCategory: "evm",
|
|
811
|
+
keyGen: args.keyGen,
|
|
812
|
+
purposeText: args.purposeText,
|
|
813
|
+
chainId: args.chainId,
|
|
814
|
+
rpcUrl: args.rpcUrl,
|
|
815
|
+
executorAddress: executor,
|
|
816
|
+
chainDetail: args.chainDetail,
|
|
817
|
+
useCustomGas: args.useCustomGas,
|
|
818
|
+
customGasChainDetails: args.customGasChainDetails
|
|
819
|
+
},
|
|
820
|
+
steps: evmSteps,
|
|
821
|
+
purposeSuffix,
|
|
822
|
+
firstMsgRawNo0x: firstDataNo0x,
|
|
823
|
+
destinationAddress: steps[0].to,
|
|
824
|
+
buildBatchMeta: ({ index, gasLimit }) => {
|
|
825
|
+
const s = steps[index];
|
|
826
|
+
if (s.kind === "weth_deposit") {
|
|
827
|
+
return {
|
|
828
|
+
signatureText: JSON.stringify({
|
|
829
|
+
kind: "EulerV2",
|
|
830
|
+
name: "WETH.deposit",
|
|
831
|
+
function: "deposit()",
|
|
832
|
+
valueWei: amountWei.toString(),
|
|
833
|
+
vaultMarket: vaultLabel,
|
|
834
|
+
note: "Wrap native for Euler v2 isolated vault deposit (same batch)."
|
|
835
|
+
}),
|
|
836
|
+
evm: { type: "euler_v2_weth_deposit", version: 1, chainId: String(args.chainId) },
|
|
837
|
+
eulerV2: {
|
|
838
|
+
step: "weth_deposit",
|
|
839
|
+
vaultMarket: vaultLabel,
|
|
840
|
+
amountHuman: args.amountHuman,
|
|
841
|
+
evault,
|
|
842
|
+
underlying: asset
|
|
843
|
+
}
|
|
844
|
+
};
|
|
883
845
|
}
|
|
884
|
-
(
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
nonce: currentNonce,
|
|
898
|
-
chainId: args.chainId
|
|
899
|
-
});
|
|
900
|
-
const h = viem.keccak256(ser);
|
|
901
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
902
|
-
messageRawBatch.push(ser);
|
|
903
|
-
proposalTxParamsBatch.push({
|
|
904
|
-
nonce: currentNonce,
|
|
905
|
-
gasLimit: gasLimitI.toString(),
|
|
906
|
-
txType: "eip1559",
|
|
907
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
908
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
909
|
-
});
|
|
910
|
-
if (i === 0) {
|
|
911
|
-
firstTxFeePayload = {
|
|
912
|
-
txNonce: currentNonce,
|
|
913
|
-
txGasLimit: gasLimitI.toString(),
|
|
914
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
915
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
846
|
+
if (s.kind === "approve") {
|
|
847
|
+
return {
|
|
848
|
+
signatureText: JSON.stringify({
|
|
849
|
+
kind: "EulerV2",
|
|
850
|
+
name: "ERC20.approve",
|
|
851
|
+
to: "Euler eVault",
|
|
852
|
+
function: "approve(address spender, uint256 amount)",
|
|
853
|
+
evault,
|
|
854
|
+
amountHuman: args.amountHuman,
|
|
855
|
+
note: "Allowance for this deposit amount only (not unlimited)."
|
|
856
|
+
}),
|
|
857
|
+
evm: { type: "euler_v2_erc20_approve", version: 1, chainId: String(args.chainId) },
|
|
858
|
+
eulerV2: { vaultMarket: vaultLabel, amountHuman: args.amountHuman, evault, underlying: asset }
|
|
916
859
|
};
|
|
917
|
-
firstDataNo0x = v.data.startsWith("0x") ? v.data.slice(2) : v.data;
|
|
918
860
|
}
|
|
919
|
-
|
|
920
|
-
if (s.kind === "weth_deposit") {
|
|
921
|
-
batchMeta.push({
|
|
922
|
-
destinationAddress: weth,
|
|
923
|
-
signatureText: JSON.stringify({
|
|
924
|
-
kind: "EulerV2",
|
|
925
|
-
name: "WETH.deposit",
|
|
926
|
-
function: "deposit()",
|
|
927
|
-
valueWei: amountWei.toString(),
|
|
928
|
-
vaultMarket: vaultLabel,
|
|
929
|
-
note: "Wrap native for Euler v2 isolated vault deposit (same batch)."
|
|
930
|
-
}),
|
|
931
|
-
evm: { type: "euler_v2_weth_deposit", version: 1, chainId: String(args.chainId) },
|
|
932
|
-
eulerV2: { step: "weth_deposit", vaultMarket: vaultLabel, amountHuman: args.amountHuman, evault, underlying: asset }
|
|
933
|
-
});
|
|
934
|
-
} else if (s.kind === "approve") {
|
|
935
|
-
batchMeta.push({
|
|
936
|
-
destinationAddress: s.to,
|
|
937
|
-
signatureText: JSON.stringify({
|
|
938
|
-
kind: "EulerV2",
|
|
939
|
-
name: "ERC20.approve",
|
|
940
|
-
to: "Euler eVault",
|
|
941
|
-
function: "approve(address spender, uint256 amount)",
|
|
942
|
-
evault,
|
|
943
|
-
amountHuman: args.amountHuman,
|
|
944
|
-
note: "Allowance for this deposit amount only (not unlimited)."
|
|
945
|
-
}),
|
|
946
|
-
evm: { type: "euler_v2_erc20_approve", version: 1, chainId: String(args.chainId) },
|
|
947
|
-
eulerV2: { vaultMarket: vaultLabel, amountHuman: args.amountHuman, evault, underlying: asset }
|
|
948
|
-
});
|
|
949
|
-
} else {
|
|
950
|
-
batchMeta.push({
|
|
951
|
-
destinationAddress: evault,
|
|
861
|
+
return {
|
|
952
862
|
signatureText: JSON.stringify({
|
|
953
863
|
kind: "EulerV2",
|
|
954
864
|
name: "EVault.deposit",
|
|
@@ -966,54 +876,11 @@ async function buildEvmMultisignBodyEulerV2IsolatedLendDepositBatch(args) {
|
|
|
966
876
|
evault,
|
|
967
877
|
underlying: asset,
|
|
968
878
|
receiver,
|
|
969
|
-
gasBuildDeposit: { baseGasUnits:
|
|
879
|
+
gasBuildDeposit: { baseGasUnits: gasLimit.toString() }
|
|
970
880
|
}
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
const extraPayload = { batchMeta };
|
|
975
|
-
if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
|
|
976
|
-
extraPayload.customGasChainDetails = args.customGasChainDetails;
|
|
977
|
-
}
|
|
978
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
979
|
-
const firstSigText = batchMeta[0].signatureText;
|
|
980
|
-
const n = steps.length;
|
|
981
|
-
const hasWrap = args.isNativeIn;
|
|
982
|
-
const purposeSuffix = (() => {
|
|
983
|
-
if (hasWrap) {
|
|
984
|
-
return `Euler v2: ${n}-tx batch \u2014 wrap native to WETH (if needed), approve eVault for the exact amount, then ERC-4626 deposit into isolated vault "${vaultLabel}".`;
|
|
985
|
-
}
|
|
986
|
-
if (n === 1) {
|
|
987
|
-
return `Euler v2: 1-tx \u2014 eVault.deposit (allowance already sufficient) into "${vaultLabel}".`;
|
|
881
|
+
};
|
|
988
882
|
}
|
|
989
|
-
|
|
990
|
-
})();
|
|
991
|
-
const firstValue = steps[0].value;
|
|
992
|
-
const bodyForSign = {
|
|
993
|
-
keyList,
|
|
994
|
-
pubKey: ph,
|
|
995
|
-
msgHash: messageHashes[0],
|
|
996
|
-
msgRaw: firstDataNo0x,
|
|
997
|
-
messageHashes,
|
|
998
|
-
messageRawBatch,
|
|
999
|
-
destinationChainID: String(args.chainId),
|
|
1000
|
-
destinationAddress: steps[0].to,
|
|
1001
|
-
extraJSON,
|
|
1002
|
-
signatureText: firstSigText,
|
|
1003
|
-
purpose: (() => {
|
|
1004
|
-
const t = args.purposeText.trim();
|
|
1005
|
-
return (t ? `${t}
|
|
1006
|
-
|
|
1007
|
-
` : "") + purposeSuffix;
|
|
1008
|
-
})(),
|
|
1009
|
-
...firstTxFeePayload,
|
|
1010
|
-
proposalTxParams: proposalTxParamsBatch
|
|
1011
|
-
};
|
|
1012
|
-
if (firstValue > 0n) {
|
|
1013
|
-
bodyForSign.value = firstValue.toString();
|
|
1014
|
-
}
|
|
1015
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
1016
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
883
|
+
});
|
|
1017
884
|
}
|
|
1018
885
|
var EULER_BORROW_BATCH_FALLBACK_GAS = 2500000n;
|
|
1019
886
|
var EULER_BORROW_BATCH_FALLBACK_GAS_PER_ROUND = 350000n;
|
|
@@ -1032,21 +899,7 @@ var evaultBorrowAbi = viem.parseAbi(["function borrow(uint256 amount, address re
|
|
|
1032
899
|
var evcAbi = viem.parseAbi([
|
|
1033
900
|
"function batch((address targetContract, address onBehalfOfAccount, uint256 value, bytes data)[])"
|
|
1034
901
|
]);
|
|
1035
|
-
function gweiToDecimalString3(n) {
|
|
1036
|
-
if (!Number.isFinite(n)) return "0";
|
|
1037
|
-
if (n === 0) return "0";
|
|
1038
|
-
const s = String(n);
|
|
1039
|
-
if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
|
|
1040
|
-
return s;
|
|
1041
|
-
}
|
|
1042
|
-
function txToViemStep2(tx) {
|
|
1043
|
-
return { to: viem.getAddress(tx.to), data: tx.data, value: tx.value };
|
|
1044
|
-
}
|
|
1045
902
|
async function buildEvmMultisignBodyEulerV2IsolatedBorrowBatch(args) {
|
|
1046
|
-
const ph = (args.keyGen.pubkeyhex ?? "").trim();
|
|
1047
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
1048
|
-
const keyList = args.keyGen.keylist ?? [];
|
|
1049
|
-
const clientId = firstClientIdFromKeyGen(args.keyGen);
|
|
1050
903
|
const evc = viem.getAddress(args.evc);
|
|
1051
904
|
const borrowVault = viem.getAddress(args.borrowVault);
|
|
1052
905
|
const collateralVault = viem.getAddress(args.collateralVault);
|
|
@@ -1195,156 +1048,73 @@ async function buildEvmMultisignBodyEulerV2IsolatedBorrowBatch(args) {
|
|
|
1195
1048
|
});
|
|
1196
1049
|
steps.push({ kind: "evc_batch", to: evc, data: batchData, value: 0n });
|
|
1197
1050
|
const borrowRoundsExtraGas = EULER_BORROW_BATCH_FALLBACK_GAS_PER_ROUND * BigInt(Math.max(0, loops.length - 1 + (args.redepositBorrowedToCollateral ? loops.length : 0)));
|
|
1198
|
-
const feeParams = await fetchChainFeeParams(args.rpcUrl, args.chainId);
|
|
1199
|
-
const legacy = Boolean(args.chainDetail?.legacy) || !feeParams.isEip1559;
|
|
1200
|
-
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
1201
|
-
const useCustomGas = args.useCustomGas;
|
|
1202
|
-
const gasLimitConfig = useCustomGas && args.chainDetail?.gasLimit != null ? Number(args.chainDetail.gasLimit) : void 0;
|
|
1203
|
-
const gasFeeMultiplier = useCustomGas && args.chainDetail?.gasMultiplier != null ? Number(args.chainDetail.gasMultiplier) : void 0;
|
|
1204
|
-
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
1205
|
-
const messageHashes = [];
|
|
1206
|
-
const messageRawBatch = [];
|
|
1207
|
-
const proposalTxParamsBatch = [];
|
|
1208
|
-
const batchMeta = [];
|
|
1209
|
-
let firstTxFeePayload = {};
|
|
1210
|
-
let firstDataNo0x = "";
|
|
1211
1051
|
const vaultLabel = (args.vaultMarketLabel ?? "").trim() || "Euler vault";
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
})
|
|
1224
|
-
} catch {
|
|
1225
|
-
if (s.kind === "weth_deposit") estimatedGas = EULER_WETH_DEPOSIT_FALLBACK2;
|
|
1226
|
-
else if (s.kind === "approve") estimatedGas = EULER_ERC20_APPROVE_FALLBACK2;
|
|
1227
|
-
else estimatedGas = EULER_BORROW_BATCH_FALLBACK_GAS + borrowRoundsExtraGas;
|
|
1052
|
+
const evmSteps = steps.map((s) => ({
|
|
1053
|
+
to: s.to,
|
|
1054
|
+
data: s.data,
|
|
1055
|
+
value: s.value,
|
|
1056
|
+
fallbackGas: s.kind === "weth_deposit" ? EULER_WETH_DEPOSIT_FALLBACK2 : s.kind === "approve" ? EULER_ERC20_APPROVE_FALLBACK2 : EULER_BORROW_BATCH_FALLBACK_GAS + borrowRoundsExtraGas
|
|
1057
|
+
}));
|
|
1058
|
+
const n = steps.length;
|
|
1059
|
+
const hasWrap = args.isNativeCollateralIn;
|
|
1060
|
+
const purposeSuffix = (() => {
|
|
1061
|
+
const tail = args.redepositBorrowedToCollateral ? `deposit collateral, enableCollateral, enableController, then ${loops.length}\xD7 borrow+redeposit on "${vaultLabel}" (same-asset target LTV loop).` : `deposit collateral, enableCollateral, enableController, borrow from "${vaultLabel}".`;
|
|
1062
|
+
if (hasWrap) {
|
|
1063
|
+
return `Euler v2: ${n}-tx batch \u2014 wrap native collateral (if needed), approve collateral eVault (buffered for all deposits), then EVC batch: ${tail}`;
|
|
1228
1064
|
}
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1065
|
+
return `Euler v2: ${n}-tx batch \u2014 approve collateral (if needed) with buffer for all deposits, then EVC batch: ${tail}`;
|
|
1066
|
+
})();
|
|
1067
|
+
const firstDataNo0x = evmSteps[0].data.startsWith("0x") ? evmSteps[0].data.slice(2) : evmSteps[0].data;
|
|
1068
|
+
return buildEvmMultisignBatch({
|
|
1069
|
+
context: {
|
|
1070
|
+
chainCategory: "evm",
|
|
1071
|
+
keyGen: args.keyGen,
|
|
1072
|
+
purposeText: args.purposeText,
|
|
1073
|
+
chainId: args.chainId,
|
|
1074
|
+
rpcUrl: args.rpcUrl,
|
|
1075
|
+
executorAddress: executor,
|
|
1076
|
+
chainDetail: args.chainDetail,
|
|
1077
|
+
useCustomGas: args.useCustomGas,
|
|
1078
|
+
customGasChainDetails: args.customGasChainDetails
|
|
1079
|
+
},
|
|
1080
|
+
steps: evmSteps,
|
|
1081
|
+
purposeSuffix,
|
|
1082
|
+
firstMsgRawNo0x: firstDataNo0x,
|
|
1083
|
+
destinationAddress: steps[0].to,
|
|
1084
|
+
buildBatchMeta: ({ index }) => {
|
|
1085
|
+
const s = steps[index];
|
|
1086
|
+
if (s.kind === "weth_deposit") {
|
|
1087
|
+
return {
|
|
1088
|
+
signatureText: JSON.stringify({
|
|
1089
|
+
kind: "EulerV2",
|
|
1090
|
+
name: "WETH.deposit",
|
|
1091
|
+
function: "deposit()",
|
|
1092
|
+
valueWei: collateralWei.toString(),
|
|
1093
|
+
vaultMarket: vaultLabel,
|
|
1094
|
+
note: "Wrap native for Euler v2 isolated borrow collateral (same batch as borrow flow)."
|
|
1095
|
+
}),
|
|
1096
|
+
evm: { type: "euler_v2_weth_deposit", version: 1, chainId: String(args.chainId) },
|
|
1097
|
+
eulerV2: { step: "weth_deposit", vaultMarket: vaultLabel, flow: "borrow" }
|
|
1098
|
+
};
|
|
1234
1099
|
}
|
|
1235
|
-
if (
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
const h = viem.keccak256(ser);
|
|
1250
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
1251
|
-
messageRawBatch.push(ser);
|
|
1252
|
-
proposalTxParamsBatch.push({
|
|
1253
|
-
nonce: currentNonce,
|
|
1254
|
-
gasLimit: gasLimitI.toString(),
|
|
1255
|
-
txType: "legacy",
|
|
1256
|
-
gasPrice: gasPriceWei.toString()
|
|
1257
|
-
});
|
|
1258
|
-
if (i === 0) {
|
|
1259
|
-
firstTxFeePayload = { txNonce: currentNonce, txGasLimit: gasLimitI.toString(), txGasPrice: gasPriceWei.toString() };
|
|
1260
|
-
firstDataNo0x = v.data.startsWith("0x") ? v.data.slice(2) : v.data;
|
|
1261
|
-
}
|
|
1262
|
-
} else {
|
|
1263
|
-
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
1264
|
-
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
1265
|
-
const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
1266
|
-
const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
1267
|
-
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
1268
|
-
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
1269
|
-
const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
1270
|
-
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
1271
|
-
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
1272
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString3(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
1273
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString3(maxFeePerGasGwei));
|
|
1274
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1275
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1276
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1277
|
-
}
|
|
1278
|
-
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
1279
|
-
maxFeePerGas,
|
|
1280
|
-
maxPriorityFeePerGas,
|
|
1281
|
-
latestBaseFeeWei
|
|
1282
|
-
));
|
|
1283
|
-
const ser = viem.serializeTransaction({
|
|
1284
|
-
type: "eip1559",
|
|
1285
|
-
to: v.to,
|
|
1286
|
-
data: v.data,
|
|
1287
|
-
value: v.value,
|
|
1288
|
-
gas: gasLimitI,
|
|
1289
|
-
maxFeePerGas,
|
|
1290
|
-
maxPriorityFeePerGas,
|
|
1291
|
-
nonce: currentNonce,
|
|
1292
|
-
chainId: args.chainId
|
|
1293
|
-
});
|
|
1294
|
-
const h = viem.keccak256(ser);
|
|
1295
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
1296
|
-
messageRawBatch.push(ser);
|
|
1297
|
-
proposalTxParamsBatch.push({
|
|
1298
|
-
nonce: currentNonce,
|
|
1299
|
-
gasLimit: gasLimitI.toString(),
|
|
1300
|
-
txType: "eip1559",
|
|
1301
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
1302
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
1303
|
-
});
|
|
1304
|
-
if (i === 0) {
|
|
1305
|
-
firstTxFeePayload = {
|
|
1306
|
-
txNonce: currentNonce,
|
|
1307
|
-
txGasLimit: gasLimitI.toString(),
|
|
1308
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
1309
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
1100
|
+
if (s.kind === "approve") {
|
|
1101
|
+
return {
|
|
1102
|
+
signatureText: JSON.stringify({
|
|
1103
|
+
kind: "EulerV2",
|
|
1104
|
+
name: "ERC20.approve",
|
|
1105
|
+
to: "Euler collateral eVault",
|
|
1106
|
+
function: "approve(address spender, uint256 amount)",
|
|
1107
|
+
collateralVault,
|
|
1108
|
+
amountHuman: args.collateralAmountHuman,
|
|
1109
|
+
note: "Allowance for initial and follow-on collateral deposits (buffered).",
|
|
1110
|
+
approveTotalWei: approveTargetWei.toString()
|
|
1111
|
+
}),
|
|
1112
|
+
evm: { type: "euler_v2_erc20_approve", version: 1, chainId: String(args.chainId) },
|
|
1113
|
+
eulerV2: { vaultMarket: vaultLabel, flow: "borrow_collateral_approve" }
|
|
1310
1114
|
};
|
|
1311
|
-
firstDataNo0x = v.data.startsWith("0x") ? v.data.slice(2) : v.data;
|
|
1312
1115
|
}
|
|
1313
|
-
}
|
|
1314
|
-
if (s.kind === "weth_deposit") {
|
|
1315
|
-
batchMeta.push({
|
|
1316
|
-
destinationAddress: weth,
|
|
1317
|
-
signatureText: JSON.stringify({
|
|
1318
|
-
kind: "EulerV2",
|
|
1319
|
-
name: "WETH.deposit",
|
|
1320
|
-
function: "deposit()",
|
|
1321
|
-
valueWei: collateralWei.toString(),
|
|
1322
|
-
vaultMarket: vaultLabel,
|
|
1323
|
-
note: "Wrap native for Euler v2 isolated borrow collateral (same batch as borrow flow)."
|
|
1324
|
-
}),
|
|
1325
|
-
evm: { type: "euler_v2_weth_deposit", version: 1, chainId: String(args.chainId) },
|
|
1326
|
-
eulerV2: { step: "weth_deposit", vaultMarket: vaultLabel, flow: "borrow" }
|
|
1327
|
-
});
|
|
1328
|
-
} else if (s.kind === "approve") {
|
|
1329
|
-
batchMeta.push({
|
|
1330
|
-
destinationAddress: s.to,
|
|
1331
|
-
signatureText: JSON.stringify({
|
|
1332
|
-
kind: "EulerV2",
|
|
1333
|
-
name: "ERC20.approve",
|
|
1334
|
-
to: "Euler collateral eVault",
|
|
1335
|
-
function: "approve(address spender, uint256 amount)",
|
|
1336
|
-
collateralVault,
|
|
1337
|
-
amountHuman: args.collateralAmountHuman,
|
|
1338
|
-
note: "Allowance for initial and follow-on collateral deposits (buffered).",
|
|
1339
|
-
approveTotalWei: approveTargetWei.toString()
|
|
1340
|
-
}),
|
|
1341
|
-
evm: { type: "euler_v2_erc20_approve", version: 1, chainId: String(args.chainId) },
|
|
1342
|
-
eulerV2: { vaultMarket: vaultLabel, flow: "borrow_collateral_approve" }
|
|
1343
|
-
});
|
|
1344
|
-
} else {
|
|
1345
1116
|
const borrowNote = args.redepositBorrowedToCollateral ? `Same-asset leverage: ${loops.length} borrow\u2192deposit round(s); total borrow wei ${borrowWeiTotal.toString()}.` : "Deposit collateral, enableCollateral, enableController, borrow in one EVC batch.";
|
|
1346
|
-
|
|
1347
|
-
destinationAddress: evc,
|
|
1117
|
+
return {
|
|
1348
1118
|
signatureText: JSON.stringify({
|
|
1349
1119
|
kind: "EulerV2",
|
|
1350
1120
|
name: "EVC.batch",
|
|
@@ -1372,50 +1142,9 @@ async function buildEvmMultisignBodyEulerV2IsolatedBorrowBatch(args) {
|
|
|
1372
1142
|
redepositBorrowedToCollateral: args.redepositBorrowedToCollateral,
|
|
1373
1143
|
borrowWeiTotal: borrowWeiTotal.toString()
|
|
1374
1144
|
}
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
const extraPayload = { batchMeta };
|
|
1379
|
-
if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
|
|
1380
|
-
extraPayload.customGasChainDetails = args.customGasChainDetails;
|
|
1381
|
-
}
|
|
1382
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
1383
|
-
const firstSigText = batchMeta[0].signatureText;
|
|
1384
|
-
const n = steps.length;
|
|
1385
|
-
const hasWrap = args.isNativeCollateralIn;
|
|
1386
|
-
const purposeSuffix = (() => {
|
|
1387
|
-
const tail = args.redepositBorrowedToCollateral ? `deposit collateral, enableCollateral, enableController, then ${loops.length}\xD7 borrow+redeposit on "${vaultLabel}" (same-asset target LTV loop).` : `deposit collateral, enableCollateral, enableController, borrow from "${vaultLabel}".`;
|
|
1388
|
-
if (hasWrap) {
|
|
1389
|
-
return `Euler v2: ${n}-tx batch \u2014 wrap native collateral (if needed), approve collateral eVault (buffered for all deposits), then EVC batch: ${tail}`;
|
|
1145
|
+
};
|
|
1390
1146
|
}
|
|
1391
|
-
|
|
1392
|
-
})();
|
|
1393
|
-
const firstValue = steps[0].value;
|
|
1394
|
-
const bodyForSign = {
|
|
1395
|
-
keyList,
|
|
1396
|
-
pubKey: ph,
|
|
1397
|
-
msgHash: messageHashes[0],
|
|
1398
|
-
msgRaw: firstDataNo0x,
|
|
1399
|
-
messageHashes,
|
|
1400
|
-
messageRawBatch,
|
|
1401
|
-
destinationChainID: String(args.chainId),
|
|
1402
|
-
destinationAddress: steps[0].to,
|
|
1403
|
-
extraJSON,
|
|
1404
|
-
signatureText: firstSigText,
|
|
1405
|
-
purpose: (() => {
|
|
1406
|
-
const t = args.purposeText.trim();
|
|
1407
|
-
return (t ? `${t}
|
|
1408
|
-
|
|
1409
|
-
` : "") + purposeSuffix;
|
|
1410
|
-
})(),
|
|
1411
|
-
...firstTxFeePayload,
|
|
1412
|
-
proposalTxParams: proposalTxParamsBatch
|
|
1413
|
-
};
|
|
1414
|
-
if (firstValue > 0n) {
|
|
1415
|
-
bodyForSign.value = firstValue.toString();
|
|
1416
|
-
}
|
|
1417
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
1418
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
1147
|
+
});
|
|
1419
1148
|
}
|
|
1420
1149
|
var EULER_REPAY_BATCH_FALLBACK = 1200000n;
|
|
1421
1150
|
var EULER_ERC20_APPROVE_FALLBACK3 = 100000n;
|
|
@@ -1428,21 +1157,7 @@ var evaultRepayAbi = viem.parseAbi(["function repay(uint256 amount, address rece
|
|
|
1428
1157
|
var evcAbi2 = viem.parseAbi([
|
|
1429
1158
|
"function batch((address targetContract, address onBehalfOfAccount, uint256 value, bytes data)[])"
|
|
1430
1159
|
]);
|
|
1431
|
-
function gweiToDecimalString4(n) {
|
|
1432
|
-
if (!Number.isFinite(n)) return "0";
|
|
1433
|
-
if (n === 0) return "0";
|
|
1434
|
-
const s = String(n);
|
|
1435
|
-
if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
|
|
1436
|
-
return s;
|
|
1437
|
-
}
|
|
1438
|
-
function txToViemStep3(tx) {
|
|
1439
|
-
return { to: viem.getAddress(tx.to), data: tx.data, value: tx.value };
|
|
1440
|
-
}
|
|
1441
1160
|
async function buildEvmMultisignBodyEulerV2BorrowRepayBatch(args) {
|
|
1442
|
-
const ph = (args.keyGen.pubkeyhex ?? "").trim();
|
|
1443
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
1444
|
-
const keyList = args.keyGen.keylist ?? [];
|
|
1445
|
-
const clientId = firstClientIdFromKeyGen(args.keyGen);
|
|
1446
1161
|
const evc = viem.getAddress(args.evc);
|
|
1447
1162
|
const borrowVault = viem.getAddress(args.borrowVault);
|
|
1448
1163
|
const borrowAsset = viem.getAddress(args.borrowUnderlying);
|
|
@@ -1517,137 +1232,49 @@ async function buildEvmMultisignBodyEulerV2BorrowRepayBatch(args) {
|
|
|
1517
1232
|
args: [batchItems]
|
|
1518
1233
|
});
|
|
1519
1234
|
steps.push({ kind: "evc_batch", to: evc, data: batchData, value: 0n });
|
|
1520
|
-
const feeParams = await fetchChainFeeParams(args.rpcUrl, args.chainId);
|
|
1521
|
-
const legacy = Boolean(args.chainDetail?.legacy) || !feeParams.isEip1559;
|
|
1522
|
-
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
1523
|
-
const useCustomGas = args.useCustomGas;
|
|
1524
|
-
const gasLimitConfig = useCustomGas && args.chainDetail?.gasLimit != null ? Number(args.chainDetail.gasLimit) : void 0;
|
|
1525
|
-
const gasFeeMultiplier = useCustomGas && args.chainDetail?.gasMultiplier != null ? Number(args.chainDetail.gasMultiplier) : void 0;
|
|
1526
|
-
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
1527
|
-
const messageHashes = [];
|
|
1528
|
-
const messageRawBatch = [];
|
|
1529
|
-
const proposalTxParamsBatch = [];
|
|
1530
|
-
const batchMeta = [];
|
|
1531
|
-
let firstTxFeePayload = {};
|
|
1532
|
-
let firstDataNo0x = "";
|
|
1533
1235
|
const vaultLabel = (args.vaultMarketLabel ?? "").trim() || "Euler vault";
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
nonce: currentNonce,
|
|
1574
|
-
gasLimit: gasLimitI.toString(),
|
|
1575
|
-
txType: "legacy",
|
|
1576
|
-
gasPrice: gasPriceWei.toString()
|
|
1577
|
-
});
|
|
1578
|
-
if (i === 0) {
|
|
1579
|
-
firstTxFeePayload = { txNonce: currentNonce, txGasLimit: gasLimitI.toString(), txGasPrice: gasPriceWei.toString() };
|
|
1580
|
-
firstDataNo0x = v.data.startsWith("0x") ? v.data.slice(2) : v.data;
|
|
1581
|
-
}
|
|
1582
|
-
} else {
|
|
1583
|
-
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
1584
|
-
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
1585
|
-
const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
1586
|
-
const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
1587
|
-
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
1588
|
-
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
1589
|
-
const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
1590
|
-
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
1591
|
-
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
1592
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString4(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
1593
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString4(maxFeePerGasGwei));
|
|
1594
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1595
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1596
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1597
|
-
}
|
|
1598
|
-
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
1599
|
-
maxFeePerGas,
|
|
1600
|
-
maxPriorityFeePerGas,
|
|
1601
|
-
latestBaseFeeWei
|
|
1602
|
-
));
|
|
1603
|
-
const ser = viem.serializeTransaction({
|
|
1604
|
-
type: "eip1559",
|
|
1605
|
-
to: v.to,
|
|
1606
|
-
data: v.data,
|
|
1607
|
-
value: v.value,
|
|
1608
|
-
gas: gasLimitI,
|
|
1609
|
-
maxFeePerGas,
|
|
1610
|
-
maxPriorityFeePerGas,
|
|
1611
|
-
nonce: currentNonce,
|
|
1612
|
-
chainId: args.chainId
|
|
1613
|
-
});
|
|
1614
|
-
const h = viem.keccak256(ser);
|
|
1615
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
1616
|
-
messageRawBatch.push(ser);
|
|
1617
|
-
proposalTxParamsBatch.push({
|
|
1618
|
-
nonce: currentNonce,
|
|
1619
|
-
gasLimit: gasLimitI.toString(),
|
|
1620
|
-
txType: "eip1559",
|
|
1621
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
1622
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
1623
|
-
});
|
|
1624
|
-
if (i === 0) {
|
|
1625
|
-
firstTxFeePayload = {
|
|
1626
|
-
txNonce: currentNonce,
|
|
1627
|
-
txGasLimit: gasLimitI.toString(),
|
|
1628
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
1629
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
1236
|
+
const evmSteps = steps.map((s) => ({
|
|
1237
|
+
to: s.to,
|
|
1238
|
+
data: s.data,
|
|
1239
|
+
value: s.value,
|
|
1240
|
+
fallbackGas: s.kind === "approve" ? EULER_ERC20_APPROVE_FALLBACK3 : EULER_REPAY_BATCH_FALLBACK
|
|
1241
|
+
}));
|
|
1242
|
+
const n = steps.length;
|
|
1243
|
+
const purposeSuffix = `Euler v2: ${n}-tx batch \u2014 repay borrow on "${vaultLabel}" (approve if needed, then EVC repay).`;
|
|
1244
|
+
const firstDataNo0x = evmSteps[0].data.startsWith("0x") ? evmSteps[0].data.slice(2) : evmSteps[0].data;
|
|
1245
|
+
return buildEvmMultisignBatch({
|
|
1246
|
+
context: {
|
|
1247
|
+
chainCategory: "evm",
|
|
1248
|
+
keyGen: args.keyGen,
|
|
1249
|
+
purposeText: args.purposeText,
|
|
1250
|
+
chainId: args.chainId,
|
|
1251
|
+
rpcUrl: args.rpcUrl,
|
|
1252
|
+
executorAddress: executor,
|
|
1253
|
+
chainDetail: args.chainDetail,
|
|
1254
|
+
useCustomGas: args.useCustomGas,
|
|
1255
|
+
customGasChainDetails: args.customGasChainDetails
|
|
1256
|
+
},
|
|
1257
|
+
steps: evmSteps,
|
|
1258
|
+
purposeSuffix,
|
|
1259
|
+
firstMsgRawNo0x: firstDataNo0x,
|
|
1260
|
+
destinationAddress: steps[0].to,
|
|
1261
|
+
buildBatchMeta: ({ index }) => {
|
|
1262
|
+
const s = steps[index];
|
|
1263
|
+
if (s.kind === "approve") {
|
|
1264
|
+
return {
|
|
1265
|
+
signatureText: JSON.stringify({
|
|
1266
|
+
kind: "EulerV2",
|
|
1267
|
+
name: "ERC20.approve",
|
|
1268
|
+
function: "approve(address spender, uint256 amount)",
|
|
1269
|
+
spender: borrowVault,
|
|
1270
|
+
borrowUnderlying: borrowAsset,
|
|
1271
|
+
note: "Allow Euler liability vault to pull assets for repay."
|
|
1272
|
+
}),
|
|
1273
|
+
evm: { type: "euler_v2_erc20_approve", version: 1, chainId: String(args.chainId) },
|
|
1274
|
+
eulerV2: { vaultMarket: vaultLabel, flow: "borrow_repay_approve" }
|
|
1630
1275
|
};
|
|
1631
|
-
firstDataNo0x = v.data.startsWith("0x") ? v.data.slice(2) : v.data;
|
|
1632
1276
|
}
|
|
1633
|
-
|
|
1634
|
-
if (s.kind === "approve") {
|
|
1635
|
-
batchMeta.push({
|
|
1636
|
-
destinationAddress: s.to,
|
|
1637
|
-
signatureText: JSON.stringify({
|
|
1638
|
-
kind: "EulerV2",
|
|
1639
|
-
name: "ERC20.approve",
|
|
1640
|
-
function: "approve(address spender, uint256 amount)",
|
|
1641
|
-
spender: borrowVault,
|
|
1642
|
-
borrowUnderlying: borrowAsset,
|
|
1643
|
-
note: "Allow Euler liability vault to pull assets for repay."
|
|
1644
|
-
}),
|
|
1645
|
-
evm: { type: "euler_v2_erc20_approve", version: 1, chainId: String(args.chainId) },
|
|
1646
|
-
eulerV2: { vaultMarket: vaultLabel, flow: "borrow_repay_approve" }
|
|
1647
|
-
});
|
|
1648
|
-
} else {
|
|
1649
|
-
batchMeta.push({
|
|
1650
|
-
destinationAddress: evc,
|
|
1277
|
+
return {
|
|
1651
1278
|
signatureText: JSON.stringify({
|
|
1652
1279
|
kind: "EulerV2",
|
|
1653
1280
|
name: "EVC.batch",
|
|
@@ -1668,39 +1295,9 @@ async function buildEvmMultisignBodyEulerV2BorrowRepayBatch(args) {
|
|
|
1668
1295
|
repayAll: args.repayAll,
|
|
1669
1296
|
amountHuman: args.amountHuman
|
|
1670
1297
|
}
|
|
1671
|
-
}
|
|
1298
|
+
};
|
|
1672
1299
|
}
|
|
1673
|
-
}
|
|
1674
|
-
const extraPayload = { batchMeta };
|
|
1675
|
-
if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
|
|
1676
|
-
extraPayload.customGasChainDetails = args.customGasChainDetails;
|
|
1677
|
-
}
|
|
1678
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
1679
|
-
const firstSigText = batchMeta[0].signatureText;
|
|
1680
|
-
const n = steps.length;
|
|
1681
|
-
const purposeSuffix = `Euler v2: ${n}-tx batch \u2014 repay borrow on "${vaultLabel}" (approve if needed, then EVC repay).`;
|
|
1682
|
-
const bodyForSign = {
|
|
1683
|
-
keyList,
|
|
1684
|
-
pubKey: ph,
|
|
1685
|
-
msgHash: messageHashes[0],
|
|
1686
|
-
msgRaw: firstDataNo0x,
|
|
1687
|
-
messageHashes,
|
|
1688
|
-
messageRawBatch,
|
|
1689
|
-
destinationChainID: String(args.chainId),
|
|
1690
|
-
destinationAddress: steps[0].to,
|
|
1691
|
-
extraJSON,
|
|
1692
|
-
signatureText: firstSigText,
|
|
1693
|
-
purpose: (() => {
|
|
1694
|
-
const t = args.purposeText.trim();
|
|
1695
|
-
return (t ? `${t}
|
|
1696
|
-
|
|
1697
|
-
` : "") + purposeSuffix;
|
|
1698
|
-
})(),
|
|
1699
|
-
...firstTxFeePayload,
|
|
1700
|
-
proposalTxParams: proposalTxParamsBatch
|
|
1701
|
-
};
|
|
1702
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
1703
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
1300
|
+
});
|
|
1704
1301
|
}
|
|
1705
1302
|
var EULER_COLLATERAL_DEPOSIT_BATCH_FALLBACK = 1600000n;
|
|
1706
1303
|
var EULER_ERC20_APPROVE_FALLBACK4 = 100000n;
|
|
@@ -1714,21 +1311,7 @@ var erc4626DepositAbi3 = viem.parseAbi([
|
|
|
1714
1311
|
var evcAbi3 = viem.parseAbi([
|
|
1715
1312
|
"function batch((address targetContract, address onBehalfOfAccount, uint256 value, bytes data)[])"
|
|
1716
1313
|
]);
|
|
1717
|
-
function gweiToDecimalString5(n) {
|
|
1718
|
-
if (!Number.isFinite(n)) return "0";
|
|
1719
|
-
if (n === 0) return "0";
|
|
1720
|
-
const s = String(n);
|
|
1721
|
-
if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
|
|
1722
|
-
return s;
|
|
1723
|
-
}
|
|
1724
|
-
function txToViemStep4(tx) {
|
|
1725
|
-
return { to: viem.getAddress(tx.to), data: tx.data, value: tx.value };
|
|
1726
|
-
}
|
|
1727
1314
|
async function buildEvmMultisignBodyEulerV2BorrowCollateralDepositBatch(args) {
|
|
1728
|
-
const ph = (args.keyGen.pubkeyhex ?? "").trim();
|
|
1729
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
1730
|
-
const keyList = args.keyGen.keylist ?? [];
|
|
1731
|
-
const clientId = firstClientIdFromKeyGen(args.keyGen);
|
|
1732
1315
|
const evc = viem.getAddress(args.evc);
|
|
1733
1316
|
const collateralVault = viem.getAddress(args.collateralVault);
|
|
1734
1317
|
const collateralAsset = viem.getAddress(args.collateralUnderlying);
|
|
@@ -1790,137 +1373,49 @@ async function buildEvmMultisignBodyEulerV2BorrowCollateralDepositBatch(args) {
|
|
|
1790
1373
|
args: [batchItems]
|
|
1791
1374
|
});
|
|
1792
1375
|
steps.push({ kind: "evc_batch", to: evc, data: batchData, value: 0n });
|
|
1793
|
-
const feeParams = await fetchChainFeeParams(args.rpcUrl, args.chainId);
|
|
1794
|
-
const legacy = Boolean(args.chainDetail?.legacy) || !feeParams.isEip1559;
|
|
1795
|
-
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
1796
|
-
const useCustomGas = args.useCustomGas;
|
|
1797
|
-
const gasLimitConfig = useCustomGas && args.chainDetail?.gasLimit != null ? Number(args.chainDetail.gasLimit) : void 0;
|
|
1798
|
-
const gasFeeMultiplier = useCustomGas && args.chainDetail?.gasMultiplier != null ? Number(args.chainDetail.gasMultiplier) : void 0;
|
|
1799
|
-
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
1800
|
-
const messageHashes = [];
|
|
1801
|
-
const messageRawBatch = [];
|
|
1802
|
-
const proposalTxParamsBatch = [];
|
|
1803
|
-
const batchMeta = [];
|
|
1804
|
-
let firstTxFeePayload = {};
|
|
1805
|
-
let firstDataNo0x = "";
|
|
1806
1376
|
const vaultLabel = (args.vaultMarketLabel ?? "").trim() || "Euler vault";
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
nonce: currentNonce,
|
|
1847
|
-
gasLimit: gasLimitI.toString(),
|
|
1848
|
-
txType: "legacy",
|
|
1849
|
-
gasPrice: gasPriceWei.toString()
|
|
1850
|
-
});
|
|
1851
|
-
if (i === 0) {
|
|
1852
|
-
firstTxFeePayload = { txNonce: currentNonce, txGasLimit: gasLimitI.toString(), txGasPrice: gasPriceWei.toString() };
|
|
1853
|
-
firstDataNo0x = v.data.startsWith("0x") ? v.data.slice(2) : v.data;
|
|
1854
|
-
}
|
|
1855
|
-
} else {
|
|
1856
|
-
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
1857
|
-
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
1858
|
-
const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
1859
|
-
const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
1860
|
-
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
1861
|
-
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
1862
|
-
const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
1863
|
-
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
1864
|
-
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
1865
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString5(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
1866
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString5(maxFeePerGasGwei));
|
|
1867
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1868
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1869
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1870
|
-
}
|
|
1871
|
-
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
1872
|
-
maxFeePerGas,
|
|
1873
|
-
maxPriorityFeePerGas,
|
|
1874
|
-
latestBaseFeeWei
|
|
1875
|
-
));
|
|
1876
|
-
const ser = viem.serializeTransaction({
|
|
1877
|
-
type: "eip1559",
|
|
1878
|
-
to: v.to,
|
|
1879
|
-
data: v.data,
|
|
1880
|
-
value: v.value,
|
|
1881
|
-
gas: gasLimitI,
|
|
1882
|
-
maxFeePerGas,
|
|
1883
|
-
maxPriorityFeePerGas,
|
|
1884
|
-
nonce: currentNonce,
|
|
1885
|
-
chainId: args.chainId
|
|
1886
|
-
});
|
|
1887
|
-
const h = viem.keccak256(ser);
|
|
1888
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
1889
|
-
messageRawBatch.push(ser);
|
|
1890
|
-
proposalTxParamsBatch.push({
|
|
1891
|
-
nonce: currentNonce,
|
|
1892
|
-
gasLimit: gasLimitI.toString(),
|
|
1893
|
-
txType: "eip1559",
|
|
1894
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
1895
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
1896
|
-
});
|
|
1897
|
-
if (i === 0) {
|
|
1898
|
-
firstTxFeePayload = {
|
|
1899
|
-
txNonce: currentNonce,
|
|
1900
|
-
txGasLimit: gasLimitI.toString(),
|
|
1901
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
1902
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
1377
|
+
const evmSteps = steps.map((s) => ({
|
|
1378
|
+
to: s.to,
|
|
1379
|
+
data: s.data,
|
|
1380
|
+
value: s.value,
|
|
1381
|
+
fallbackGas: s.kind === "approve" ? EULER_ERC20_APPROVE_FALLBACK4 : EULER_COLLATERAL_DEPOSIT_BATCH_FALLBACK
|
|
1382
|
+
}));
|
|
1383
|
+
const n = steps.length;
|
|
1384
|
+
const purposeSuffix = `Euler v2: ${n}-tx batch \u2014 deposit ${args.amountHuman} collateral into "${vaultLabel}" (approve if needed, then EVC deposit).`;
|
|
1385
|
+
const firstDataNo0x = evmSteps[0].data.startsWith("0x") ? evmSteps[0].data.slice(2) : evmSteps[0].data;
|
|
1386
|
+
return buildEvmMultisignBatch({
|
|
1387
|
+
context: {
|
|
1388
|
+
chainCategory: "evm",
|
|
1389
|
+
keyGen: args.keyGen,
|
|
1390
|
+
purposeText: args.purposeText,
|
|
1391
|
+
chainId: args.chainId,
|
|
1392
|
+
rpcUrl: args.rpcUrl,
|
|
1393
|
+
executorAddress: executor,
|
|
1394
|
+
chainDetail: args.chainDetail,
|
|
1395
|
+
useCustomGas: args.useCustomGas,
|
|
1396
|
+
customGasChainDetails: args.customGasChainDetails
|
|
1397
|
+
},
|
|
1398
|
+
steps: evmSteps,
|
|
1399
|
+
purposeSuffix,
|
|
1400
|
+
firstMsgRawNo0x: firstDataNo0x,
|
|
1401
|
+
destinationAddress: steps[0].to,
|
|
1402
|
+
buildBatchMeta: ({ index }) => {
|
|
1403
|
+
const s = steps[index];
|
|
1404
|
+
if (s.kind === "approve") {
|
|
1405
|
+
return {
|
|
1406
|
+
signatureText: JSON.stringify({
|
|
1407
|
+
kind: "EulerV2",
|
|
1408
|
+
name: "ERC20.approve",
|
|
1409
|
+
function: "approve(address spender, uint256 amount)",
|
|
1410
|
+
spender: collateralVault,
|
|
1411
|
+
collateralUnderlying: collateralAsset,
|
|
1412
|
+
note: "Allow Euler collateral eVault to pull assets for collateral deposit."
|
|
1413
|
+
}),
|
|
1414
|
+
evm: { type: "euler_v2_erc20_approve", version: 1, chainId: String(args.chainId) },
|
|
1415
|
+
eulerV2: { vaultMarket: vaultLabel, flow: "borrow_collateral_deposit_approve" }
|
|
1903
1416
|
};
|
|
1904
|
-
firstDataNo0x = v.data.startsWith("0x") ? v.data.slice(2) : v.data;
|
|
1905
1417
|
}
|
|
1906
|
-
|
|
1907
|
-
if (s.kind === "approve") {
|
|
1908
|
-
batchMeta.push({
|
|
1909
|
-
destinationAddress: s.to,
|
|
1910
|
-
signatureText: JSON.stringify({
|
|
1911
|
-
kind: "EulerV2",
|
|
1912
|
-
name: "ERC20.approve",
|
|
1913
|
-
function: "approve(address spender, uint256 amount)",
|
|
1914
|
-
spender: collateralVault,
|
|
1915
|
-
collateralUnderlying: collateralAsset,
|
|
1916
|
-
note: "Allow Euler collateral eVault to pull assets for collateral deposit."
|
|
1917
|
-
}),
|
|
1918
|
-
evm: { type: "euler_v2_erc20_approve", version: 1, chainId: String(args.chainId) },
|
|
1919
|
-
eulerV2: { vaultMarket: vaultLabel, flow: "borrow_collateral_deposit_approve" }
|
|
1920
|
-
});
|
|
1921
|
-
} else {
|
|
1922
|
-
batchMeta.push({
|
|
1923
|
-
destinationAddress: evc,
|
|
1418
|
+
return {
|
|
1924
1419
|
signatureText: JSON.stringify({
|
|
1925
1420
|
kind: "EulerV2",
|
|
1926
1421
|
name: "EVC.batch",
|
|
@@ -1940,39 +1435,9 @@ async function buildEvmMultisignBodyEulerV2BorrowCollateralDepositBatch(args) {
|
|
|
1940
1435
|
subAccount,
|
|
1941
1436
|
amountHuman: args.amountHuman
|
|
1942
1437
|
}
|
|
1943
|
-
}
|
|
1438
|
+
};
|
|
1944
1439
|
}
|
|
1945
|
-
}
|
|
1946
|
-
const extraPayload = { batchMeta };
|
|
1947
|
-
if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
|
|
1948
|
-
extraPayload.customGasChainDetails = args.customGasChainDetails;
|
|
1949
|
-
}
|
|
1950
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
1951
|
-
const firstSigText = batchMeta[0].signatureText;
|
|
1952
|
-
const n = steps.length;
|
|
1953
|
-
const purposeSuffix = `Euler v2: ${n}-tx batch \u2014 deposit ${args.amountHuman} collateral into "${vaultLabel}" (approve if needed, then EVC deposit).`;
|
|
1954
|
-
const bodyForSign = {
|
|
1955
|
-
keyList,
|
|
1956
|
-
pubKey: ph,
|
|
1957
|
-
msgHash: messageHashes[0],
|
|
1958
|
-
msgRaw: firstDataNo0x,
|
|
1959
|
-
messageHashes,
|
|
1960
|
-
messageRawBatch,
|
|
1961
|
-
destinationChainID: String(args.chainId),
|
|
1962
|
-
destinationAddress: steps[0].to,
|
|
1963
|
-
extraJSON,
|
|
1964
|
-
signatureText: firstSigText,
|
|
1965
|
-
purpose: (() => {
|
|
1966
|
-
const t = args.purposeText.trim();
|
|
1967
|
-
return (t ? `${t}
|
|
1968
|
-
|
|
1969
|
-
` : "") + purposeSuffix;
|
|
1970
|
-
})(),
|
|
1971
|
-
...firstTxFeePayload,
|
|
1972
|
-
proposalTxParams: proposalTxParamsBatch
|
|
1973
|
-
};
|
|
1974
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
1975
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
1440
|
+
});
|
|
1976
1441
|
}
|
|
1977
1442
|
var EULER_COLLATERAL_WITHDRAW_BATCH_FALLBACK = 1400000n;
|
|
1978
1443
|
var erc4626WithdrawAbi3 = viem.parseAbi([
|
|
@@ -1981,33 +1446,12 @@ var erc4626WithdrawAbi3 = viem.parseAbi([
|
|
|
1981
1446
|
var evcAbi4 = viem.parseAbi([
|
|
1982
1447
|
"function batch((address targetContract, address onBehalfOfAccount, uint256 value, bytes data)[])"
|
|
1983
1448
|
]);
|
|
1984
|
-
function gweiToDecimalString6(n) {
|
|
1985
|
-
if (!Number.isFinite(n)) return "0";
|
|
1986
|
-
if (n === 0) return "0";
|
|
1987
|
-
const s = String(n);
|
|
1988
|
-
if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
|
|
1989
|
-
return s;
|
|
1990
|
-
}
|
|
1991
|
-
function txToViemStep5(tx) {
|
|
1992
|
-
return { to: viem.getAddress(tx.to), data: tx.data, value: tx.value };
|
|
1993
|
-
}
|
|
1994
1449
|
async function buildEvmMultisignBodyEulerV2BorrowCollateralWithdrawBatch(args) {
|
|
1995
|
-
const ph = (args.keyGen.pubkeyhex ?? "").trim();
|
|
1996
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
1997
|
-
const keyList = args.keyGen.keylist ?? [];
|
|
1998
|
-
const clientId = firstClientIdFromKeyGen(args.keyGen);
|
|
1999
1450
|
const evc = viem.getAddress(args.evc);
|
|
2000
1451
|
const collateralVault = viem.getAddress(args.collateralVault);
|
|
2001
1452
|
const subAccount = viem.getAddress(args.subAccount);
|
|
2002
1453
|
const receiver = viem.getAddress(args.receiver);
|
|
2003
1454
|
const executor = viem.getAddress(args.executorAddress);
|
|
2004
|
-
const ch = viem.defineChain({
|
|
2005
|
-
id: args.chainId,
|
|
2006
|
-
name: "EulerColWithdraw",
|
|
2007
|
-
nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
|
|
2008
|
-
rpcUrls: { default: { http: [args.rpcUrl] } }
|
|
2009
|
-
});
|
|
2010
|
-
const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(args.rpcUrl) });
|
|
2011
1455
|
const dec = await fetchEulerVaultAssetDecimals({ rpcUrl: args.rpcUrl, chainId: args.chainId, evault: collateralVault });
|
|
2012
1456
|
const amountWei = viem.parseUnits(args.amountHuman, dec);
|
|
2013
1457
|
if (amountWei === 0n) throw new Error("Withdraw amount is zero after converting with token decimals.");
|
|
@@ -2043,122 +1487,29 @@ async function buildEvmMultisignBodyEulerV2BorrowCollateralWithdrawBatch(args) {
|
|
|
2043
1487
|
args: [batchItems]
|
|
2044
1488
|
});
|
|
2045
1489
|
const steps = [{ kind: "evc_batch", to: evc, data: batchData, value: 0n }];
|
|
2046
|
-
const feeParams = await fetchChainFeeParams(args.rpcUrl, args.chainId);
|
|
2047
|
-
const legacy = Boolean(args.chainDetail?.legacy) || !feeParams.isEip1559;
|
|
2048
|
-
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
2049
|
-
const useCustomGas = args.useCustomGas;
|
|
2050
|
-
const gasLimitConfig = useCustomGas && args.chainDetail?.gasLimit != null ? Number(args.chainDetail.gasLimit) : void 0;
|
|
2051
|
-
const gasFeeMultiplier = useCustomGas && args.chainDetail?.gasMultiplier != null ? Number(args.chainDetail.gasMultiplier) : void 0;
|
|
2052
|
-
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
2053
|
-
const messageHashes = [];
|
|
2054
|
-
const messageRawBatch = [];
|
|
2055
|
-
const proposalTxParamsBatch = [];
|
|
2056
|
-
const batchMeta = [];
|
|
2057
|
-
let firstTxFeePayload = {};
|
|
2058
|
-
let firstDataNo0x = "";
|
|
2059
1490
|
const vaultLabel = (args.vaultMarketLabel ?? "").trim() || "Euler vault";
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
const configured = viem.parseGwei(gweiToDecimalString6(Number(args.chainDetail.gasPrice)));
|
|
2083
|
-
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
2084
|
-
}
|
|
2085
|
-
const ser = viem.serializeTransaction({
|
|
2086
|
-
type: "legacy",
|
|
2087
|
-
to: v.to,
|
|
2088
|
-
data: v.data,
|
|
2089
|
-
value: v.value,
|
|
2090
|
-
gas: gasLimitI,
|
|
2091
|
-
gasPrice: gasPriceWei,
|
|
2092
|
-
nonce: currentNonce,
|
|
2093
|
-
chainId: args.chainId
|
|
2094
|
-
});
|
|
2095
|
-
const h = viem.keccak256(ser);
|
|
2096
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
2097
|
-
messageRawBatch.push(ser);
|
|
2098
|
-
proposalTxParamsBatch.push({
|
|
2099
|
-
nonce: currentNonce,
|
|
2100
|
-
gasLimit: gasLimitI.toString(),
|
|
2101
|
-
txType: "legacy",
|
|
2102
|
-
gasPrice: gasPriceWei.toString()
|
|
2103
|
-
});
|
|
2104
|
-
if (i === 0) {
|
|
2105
|
-
firstTxFeePayload = { txNonce: currentNonce, txGasLimit: gasLimitI.toString(), txGasPrice: gasPriceWei.toString() };
|
|
2106
|
-
firstDataNo0x = v.data.startsWith("0x") ? v.data.slice(2) : v.data;
|
|
2107
|
-
}
|
|
2108
|
-
} else {
|
|
2109
|
-
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
2110
|
-
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
2111
|
-
const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
2112
|
-
const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
2113
|
-
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
2114
|
-
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
2115
|
-
const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
2116
|
-
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
2117
|
-
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
2118
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString6(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
2119
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString6(maxFeePerGasGwei));
|
|
2120
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
2121
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
2122
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
2123
|
-
}
|
|
2124
|
-
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
2125
|
-
maxFeePerGas,
|
|
2126
|
-
maxPriorityFeePerGas,
|
|
2127
|
-
latestBaseFeeWei
|
|
2128
|
-
));
|
|
2129
|
-
const ser = viem.serializeTransaction({
|
|
2130
|
-
type: "eip1559",
|
|
2131
|
-
to: v.to,
|
|
2132
|
-
data: v.data,
|
|
2133
|
-
value: v.value,
|
|
2134
|
-
gas: gasLimitI,
|
|
2135
|
-
maxFeePerGas,
|
|
2136
|
-
maxPriorityFeePerGas,
|
|
2137
|
-
nonce: currentNonce,
|
|
2138
|
-
chainId: args.chainId
|
|
2139
|
-
});
|
|
2140
|
-
const h = viem.keccak256(ser);
|
|
2141
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
2142
|
-
messageRawBatch.push(ser);
|
|
2143
|
-
proposalTxParamsBatch.push({
|
|
2144
|
-
nonce: currentNonce,
|
|
2145
|
-
gasLimit: gasLimitI.toString(),
|
|
2146
|
-
txType: "eip1559",
|
|
2147
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
2148
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
2149
|
-
});
|
|
2150
|
-
if (i === 0) {
|
|
2151
|
-
firstTxFeePayload = {
|
|
2152
|
-
txNonce: currentNonce,
|
|
2153
|
-
txGasLimit: gasLimitI.toString(),
|
|
2154
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
2155
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
2156
|
-
};
|
|
2157
|
-
firstDataNo0x = v.data.startsWith("0x") ? v.data.slice(2) : v.data;
|
|
2158
|
-
}
|
|
2159
|
-
}
|
|
2160
|
-
batchMeta.push({
|
|
2161
|
-
destinationAddress: evc,
|
|
1491
|
+
const purposeSuffix = `Euler v2: 1-tx \u2014 withdraw ${args.amountHuman} collateral from "${vaultLabel}" via EVC (sub-account).`;
|
|
1492
|
+
const firstDataNo0x = batchData.startsWith("0x") ? batchData.slice(2) : batchData;
|
|
1493
|
+
const evmSteps = [
|
|
1494
|
+
{ to: evc, data: batchData, value: 0n, fallbackGas: EULER_COLLATERAL_WITHDRAW_BATCH_FALLBACK }
|
|
1495
|
+
];
|
|
1496
|
+
return buildEvmMultisignBatch({
|
|
1497
|
+
context: {
|
|
1498
|
+
chainCategory: "evm",
|
|
1499
|
+
keyGen: args.keyGen,
|
|
1500
|
+
purposeText: args.purposeText,
|
|
1501
|
+
chainId: args.chainId,
|
|
1502
|
+
rpcUrl: args.rpcUrl,
|
|
1503
|
+
executorAddress: executor,
|
|
1504
|
+
chainDetail: args.chainDetail,
|
|
1505
|
+
useCustomGas: args.useCustomGas,
|
|
1506
|
+
customGasChainDetails: args.customGasChainDetails
|
|
1507
|
+
},
|
|
1508
|
+
steps: evmSteps,
|
|
1509
|
+
purposeSuffix,
|
|
1510
|
+
firstMsgRawNo0x: firstDataNo0x,
|
|
1511
|
+
destinationAddress: steps[0].to,
|
|
1512
|
+
buildBatchMeta: () => ({
|
|
2162
1513
|
signatureText: JSON.stringify({
|
|
2163
1514
|
kind: "EulerV2",
|
|
2164
1515
|
name: "EVC.batch",
|
|
@@ -2180,37 +1531,8 @@ async function buildEvmMultisignBodyEulerV2BorrowCollateralWithdrawBatch(args) {
|
|
|
2180
1531
|
receiver,
|
|
2181
1532
|
amountHuman: args.amountHuman
|
|
2182
1533
|
}
|
|
2183
|
-
})
|
|
2184
|
-
}
|
|
2185
|
-
const extraPayload = { batchMeta };
|
|
2186
|
-
if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
|
|
2187
|
-
extraPayload.customGasChainDetails = args.customGasChainDetails;
|
|
2188
|
-
}
|
|
2189
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
2190
|
-
const firstSigText = batchMeta[0].signatureText;
|
|
2191
|
-
const purposeSuffix = `Euler v2: 1-tx \u2014 withdraw ${args.amountHuman} collateral from "${vaultLabel}" via EVC (sub-account).`;
|
|
2192
|
-
const bodyForSign = {
|
|
2193
|
-
keyList,
|
|
2194
|
-
pubKey: ph,
|
|
2195
|
-
msgHash: messageHashes[0],
|
|
2196
|
-
msgRaw: firstDataNo0x,
|
|
2197
|
-
messageHashes,
|
|
2198
|
-
messageRawBatch,
|
|
2199
|
-
destinationChainID: String(args.chainId),
|
|
2200
|
-
destinationAddress: steps[0].to,
|
|
2201
|
-
extraJSON,
|
|
2202
|
-
signatureText: firstSigText,
|
|
2203
|
-
purpose: (() => {
|
|
2204
|
-
const t = args.purposeText.trim();
|
|
2205
|
-
return (t ? `${t}
|
|
2206
|
-
|
|
2207
|
-
` : "") + purposeSuffix;
|
|
2208
|
-
})(),
|
|
2209
|
-
...firstTxFeePayload,
|
|
2210
|
-
proposalTxParams: proposalTxParamsBatch
|
|
2211
|
-
};
|
|
2212
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
2213
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
1534
|
+
})
|
|
1535
|
+
});
|
|
2214
1536
|
}
|
|
2215
1537
|
|
|
2216
1538
|
// src/protocols/evm/euler-v2/index.ts
|