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