four-flap-meme-sdk 1.4.38 → 1.4.40
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/dist/contracts/tm-bundle-merkle/core.js +36 -28
- package/dist/contracts/tm-bundle-merkle/pancake-proxy.js +25 -19
- package/dist/contracts/tm-bundle-merkle/private.js +47 -37
- package/dist/contracts/tm-bundle-merkle/swap-buy-first.js +17 -19
- package/dist/contracts/tm-bundle-merkle/swap.js +51 -52
- package/dist/contracts/tm-bundle-merkle/utils.js +76 -97
- package/dist/contracts/tm-bundle.js +35 -25
- package/dist/dex/direct-router.js +37 -34
- package/dist/flap/portal-bundle-merkle/core.js +34 -28
- package/dist/flap/portal-bundle-merkle/pancake-proxy.js +25 -17
- package/dist/flap/portal-bundle-merkle/private.js +73 -53
- package/dist/flap/portal-bundle-merkle/swap-buy-first.js +26 -20
- package/dist/flap/portal-bundle-merkle/swap.js +60 -55
- package/dist/flap/portal-bundle-merkle/utils.js +69 -44
- package/dist/pancake/bundle-buy-first.js +27 -20
- package/dist/pancake/bundle-swap.js +56 -56
- package/dist/utils/bundle-helpers.d.ts +38 -0
- package/dist/utils/bundle-helpers.js +85 -1
- package/dist/utils/private-sale.js +22 -19
- package/package.json +1 -1
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - V3 Quoter (BSC): 0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997
|
|
8
8
|
*/
|
|
9
9
|
import { ethers, Wallet, JsonRpcProvider, Contract, Interface } from 'ethers';
|
|
10
|
-
import { NonceManager, getOptimizedGasPrice, getDeadline, encodeV3Path } from '../../utils/bundle-helpers.js';
|
|
10
|
+
import { NonceManager, getOptimizedGasPrice, getDeadline, encodeV3Path, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../utils/bundle-helpers.js';
|
|
11
11
|
import { ADDRESSES, ZERO_ADDRESS } from '../../utils/constants.js';
|
|
12
12
|
import { MULTICALL3_ABI, V2_ROUTER_ABI, V3_ROUTER02_ABI, V3_QUOTER_ABI, ERC20_ABI } from '../../abis/common.js';
|
|
13
13
|
import { CHAIN_ID_MAP, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient, getBribeAmount, BLOCKRAZOR_BUILDER_EOA } from './config.js';
|
|
@@ -394,19 +394,23 @@ export async function pancakeProxyBatchBuyMerkle(params) {
|
|
|
394
394
|
value: txValue
|
|
395
395
|
}));
|
|
396
396
|
});
|
|
397
|
+
const signedTxs = await Promise.all(signPromises);
|
|
398
|
+
// 利润多跳转账(强制 2 跳中转)
|
|
397
399
|
if (shouldExtractProfitForBuy && nativeProfitAmount > 0n && maxFundsIndex >= 0) {
|
|
398
400
|
const profitNonce = mutableNonces[maxFundsIndex] + 1;
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
401
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
402
|
+
provider,
|
|
403
|
+
payerWallet: buyers[maxFundsIndex],
|
|
404
|
+
profitAmount: nativeProfitAmount,
|
|
405
|
+
profitRecipient: getProfitRecipient(),
|
|
406
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
403
407
|
gasPrice,
|
|
404
|
-
gasLimit: 21000n,
|
|
405
408
|
chainId,
|
|
406
|
-
|
|
407
|
-
|
|
409
|
+
txType,
|
|
410
|
+
startNonce: profitNonce
|
|
411
|
+
});
|
|
412
|
+
signedTxs.push(...profitHopResult.signedTransactions);
|
|
408
413
|
}
|
|
409
|
-
const signedTxs = await Promise.all(signPromises);
|
|
410
414
|
nonceManager.clearTemp();
|
|
411
415
|
return {
|
|
412
416
|
signedTransactions: signedTxs
|
|
@@ -578,18 +582,22 @@ export async function pancakeProxyBatchSellMerkle(params) {
|
|
|
578
582
|
value: txValue
|
|
579
583
|
}));
|
|
580
584
|
});
|
|
585
|
+
const signedTxs = await Promise.all(signPromises);
|
|
586
|
+
// 利润多跳转账(强制 2 跳中转)
|
|
581
587
|
if (needProfitTx && profitNonce !== undefined) {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
588
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
589
|
+
provider,
|
|
590
|
+
payerWallet: sellers[maxRevenueIndex],
|
|
591
|
+
profitAmount: totalProfit,
|
|
592
|
+
profitRecipient: getProfitRecipient(),
|
|
593
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
586
594
|
gasPrice,
|
|
587
|
-
gasLimit: 21000n,
|
|
588
595
|
chainId,
|
|
589
|
-
|
|
590
|
-
|
|
596
|
+
txType,
|
|
597
|
+
startNonce: profitNonce
|
|
598
|
+
});
|
|
599
|
+
signedTxs.push(...profitHopResult.signedTransactions);
|
|
591
600
|
}
|
|
592
|
-
const signedTxs = await Promise.all(signPromises);
|
|
593
601
|
nonceManager.clearTemp();
|
|
594
602
|
return {
|
|
595
603
|
signedTransactions: signedTxs
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ethers, Wallet } from 'ethers';
|
|
2
2
|
import { MerkleClient } from '../../clients/merkle.js';
|
|
3
|
-
import { getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
3
|
+
import { getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../utils/bundle-helpers.js';
|
|
4
4
|
import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
|
|
5
5
|
import { ZERO_ADDRESS } from '../../utils/constants.js';
|
|
6
6
|
import { CHAIN_ID_MAP, PORTAL_ABI, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, calculateBatchProfit, getProfitRecipient, getBribeAmount, BLOCKRAZOR_BUILDER_EOA } from './config.js';
|
|
@@ -67,20 +67,23 @@ export async function flapPrivateBuyMerkle(params) {
|
|
|
67
67
|
type: txType,
|
|
68
68
|
value: actualAmountWei
|
|
69
69
|
}));
|
|
70
|
-
//
|
|
70
|
+
// ✅ 并行签名完成后按顺序返回
|
|
71
|
+
const signedTxs = await Promise.all(signPromises);
|
|
72
|
+
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
71
73
|
if (needProfitTx && profitNonce !== undefined) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
75
|
+
provider,
|
|
76
|
+
payerWallet: wallet,
|
|
77
|
+
profitAmount: profitWei,
|
|
78
|
+
profitRecipient: getProfitRecipient(),
|
|
79
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
76
80
|
gasPrice,
|
|
77
|
-
gasLimit: 21000n,
|
|
78
81
|
chainId,
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
txType,
|
|
83
|
+
startNonce: profitNonce
|
|
84
|
+
});
|
|
85
|
+
signedTxs.push(...profitHopResult.signedTransactions);
|
|
81
86
|
}
|
|
82
|
-
// ✅ 并行签名完成后按顺序返回
|
|
83
|
-
const signedTxs = await Promise.all(signPromises);
|
|
84
87
|
return { signedTransactions: signedTxs };
|
|
85
88
|
}
|
|
86
89
|
/**
|
|
@@ -146,20 +149,23 @@ export async function flapPrivateSellMerkle(params) {
|
|
|
146
149
|
chainId,
|
|
147
150
|
type: txType
|
|
148
151
|
}));
|
|
149
|
-
//
|
|
152
|
+
// ✅ 并行签名完成后按顺序返回
|
|
153
|
+
const signedTxs = await Promise.all(signPromises);
|
|
154
|
+
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
150
155
|
if (needProfitTx && profitNonce !== undefined) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
157
|
+
provider,
|
|
158
|
+
payerWallet: wallet,
|
|
159
|
+
profitAmount: profitWei,
|
|
160
|
+
profitRecipient: getProfitRecipient(),
|
|
161
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
155
162
|
gasPrice,
|
|
156
|
-
gasLimit: 21000n,
|
|
157
163
|
chainId,
|
|
158
|
-
|
|
159
|
-
|
|
164
|
+
txType,
|
|
165
|
+
startNonce: profitNonce
|
|
166
|
+
});
|
|
167
|
+
signedTxs.push(...profitHopResult.signedTransactions);
|
|
160
168
|
}
|
|
161
|
-
// ✅ 并行签名完成后按顺序返回
|
|
162
|
-
const signedTxs = await Promise.all(signPromises);
|
|
163
169
|
return { signedTransactions: signedTxs };
|
|
164
170
|
}
|
|
165
171
|
/**
|
|
@@ -241,18 +247,20 @@ export async function flapBatchPrivateBuyMerkle(params) {
|
|
|
241
247
|
values: actualAmountsWei
|
|
242
248
|
});
|
|
243
249
|
signedTxs.push(...signedList);
|
|
244
|
-
// ✅
|
|
250
|
+
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
245
251
|
if (needProfitTx && profitNonce !== undefined && maxFundsIndex >= 0) {
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
252
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
253
|
+
provider,
|
|
254
|
+
payerWallet: wallets[maxFundsIndex],
|
|
255
|
+
profitAmount: totalProfit,
|
|
256
|
+
profitRecipient: getProfitRecipient(),
|
|
257
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
250
258
|
gasPrice,
|
|
251
|
-
gasLimit: 21000n,
|
|
252
259
|
chainId,
|
|
253
|
-
|
|
260
|
+
txType: getTxType(config),
|
|
261
|
+
startNonce: profitNonce
|
|
254
262
|
});
|
|
255
|
-
signedTxs.push(
|
|
263
|
+
signedTxs.push(...profitHopResult.signedTransactions);
|
|
256
264
|
}
|
|
257
265
|
return { signedTransactions: signedTxs };
|
|
258
266
|
}
|
|
@@ -337,18 +345,20 @@ export async function flapBatchPrivateSellMerkle(params) {
|
|
|
337
345
|
config
|
|
338
346
|
});
|
|
339
347
|
signedTxs.push(...signedList);
|
|
340
|
-
// ✅
|
|
348
|
+
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
341
349
|
if (needProfitTx && profitNonce !== undefined && maxRevenueIndex >= 0) {
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
350
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
351
|
+
provider,
|
|
352
|
+
payerWallet: wallets[maxRevenueIndex],
|
|
353
|
+
profitAmount: totalProfit,
|
|
354
|
+
profitRecipient: getProfitRecipient(),
|
|
355
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
346
356
|
gasPrice,
|
|
347
|
-
gasLimit: 21000n,
|
|
348
357
|
chainId,
|
|
349
|
-
|
|
358
|
+
txType: getTxType(config),
|
|
359
|
+
startNonce: profitNonce
|
|
350
360
|
});
|
|
351
|
-
signedTxs.push(
|
|
361
|
+
signedTxs.push(...profitHopResult.signedTransactions);
|
|
352
362
|
}
|
|
353
363
|
return { signedTransactions: signedTxs };
|
|
354
364
|
}
|
|
@@ -395,20 +405,25 @@ function resolveGasLimit(multiplier, defaultGas = DEFAULT_GAS_LIMIT) {
|
|
|
395
405
|
const factor = multiplier ?? 1.0;
|
|
396
406
|
return BigInt(Math.ceil(defaultGas * factor));
|
|
397
407
|
}
|
|
398
|
-
|
|
408
|
+
/**
|
|
409
|
+
* 追加利润多跳转账交易(强制 2 跳中转)
|
|
410
|
+
*/
|
|
411
|
+
async function appendSingleProfitTransfer({ extractProfit, profitWei, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
|
|
399
412
|
if (!extractProfit || profitWei === 0n) {
|
|
400
413
|
return;
|
|
401
414
|
}
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
415
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
416
|
+
provider,
|
|
417
|
+
payerWallet: wallet,
|
|
418
|
+
profitAmount: profitWei,
|
|
419
|
+
profitRecipient: getProfitRecipient(),
|
|
420
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
406
421
|
gasPrice,
|
|
407
|
-
gasLimit: 21000n,
|
|
408
422
|
chainId,
|
|
409
|
-
|
|
423
|
+
txType: getTxType(config),
|
|
424
|
+
startNonce: baseNonce + 1
|
|
410
425
|
});
|
|
411
|
-
signedTxs.push(
|
|
426
|
+
signedTxs.push(...profitHopResult.signedTransactions);
|
|
412
427
|
}
|
|
413
428
|
async function resolveSingleSellOutputs(portal, tokenAddress, amountWei, minOutputAmount) {
|
|
414
429
|
if (minOutputAmount !== undefined) {
|
|
@@ -438,7 +453,10 @@ async function resolveSingleSellOutputs(portal, tokenAddress, amountWei, minOutp
|
|
|
438
453
|
};
|
|
439
454
|
}
|
|
440
455
|
}
|
|
441
|
-
|
|
456
|
+
/**
|
|
457
|
+
* 追加卖出利润多跳转账交易(强制 2 跳中转)
|
|
458
|
+
*/
|
|
459
|
+
async function appendSingleSellProfitTransfer({ extractProfit, quotedOutput, wallet, baseNonce, provider, gasPrice, chainId, config, signedTxs }) {
|
|
442
460
|
if (!extractProfit || quotedOutput <= 0n) {
|
|
443
461
|
return;
|
|
444
462
|
}
|
|
@@ -446,16 +464,18 @@ async function appendSingleSellProfitTransfer({ extractProfit, quotedOutput, wal
|
|
|
446
464
|
if (profit === 0n) {
|
|
447
465
|
return;
|
|
448
466
|
}
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
467
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
468
|
+
provider,
|
|
469
|
+
payerWallet: wallet,
|
|
470
|
+
profitAmount: profit,
|
|
471
|
+
profitRecipient: getProfitRecipient(),
|
|
472
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
453
473
|
gasPrice,
|
|
454
|
-
gasLimit: 21000n,
|
|
455
474
|
chainId,
|
|
456
|
-
|
|
475
|
+
txType: getTxType(config),
|
|
476
|
+
startNonce: baseNonce + 1
|
|
457
477
|
});
|
|
458
|
-
signedTxs.push(
|
|
478
|
+
signedTxs.push(...profitHopResult.signedTransactions);
|
|
459
479
|
}
|
|
460
480
|
function resolveBatchMinOutputs(minOutputAmounts, walletCount) {
|
|
461
481
|
if (minOutputAmounts && minOutputAmounts.length === walletCount) {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 功能:钱包B先买入代币 → 钱包A卖出相同数量 → 原子执行
|
|
5
5
|
*/
|
|
6
6
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
7
|
-
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
7
|
+
import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../utils/bundle-helpers.js';
|
|
8
8
|
import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
|
|
9
9
|
import { PROFIT_CONFIG, ADDRESSES, ZERO_ADDRESS } from '../../utils/constants.js';
|
|
10
10
|
import { ERC20_BALANCE_ABI, V2_ROUTER_QUOTE_ABI } from '../../abis/common.js';
|
|
@@ -202,23 +202,24 @@ export async function flapBundleBuyFirstMerkle(params) {
|
|
|
202
202
|
buyer.signTransaction(buyTx),
|
|
203
203
|
seller.signTransaction(sellTx)
|
|
204
204
|
]);
|
|
205
|
-
|
|
206
|
-
|
|
205
|
+
nonceManager.clearTemp();
|
|
206
|
+
// ✅ 组装顺序:贿赂 → 买入 → 卖出
|
|
207
|
+
const allTransactions = [];
|
|
208
|
+
if (bribeTx)
|
|
209
|
+
allTransactions.push(bribeTx);
|
|
210
|
+
allTransactions.push(signedBuy, signedSell);
|
|
211
|
+
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
212
|
+
const profitTxs = await buildProfitTransaction({
|
|
213
|
+
provider: chainContext.provider,
|
|
207
214
|
seller,
|
|
208
|
-
profitAmount: nativeProfitAmount,
|
|
215
|
+
profitAmount: nativeProfitAmount,
|
|
209
216
|
profitNonce: noncePlan.profitNonce,
|
|
210
217
|
gasPrice,
|
|
211
218
|
chainId: chainContext.chainId,
|
|
212
219
|
txType
|
|
213
220
|
});
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const allTransactions = [];
|
|
217
|
-
if (bribeTx)
|
|
218
|
-
allTransactions.push(bribeTx);
|
|
219
|
-
allTransactions.push(signedBuy, signedSell);
|
|
220
|
-
if (profitTx)
|
|
221
|
-
allTransactions.push(profitTx);
|
|
221
|
+
if (profitTxs)
|
|
222
|
+
allTransactions.push(...profitTxs);
|
|
222
223
|
return {
|
|
223
224
|
signedTransactions: allTransactions,
|
|
224
225
|
metadata: {
|
|
@@ -396,20 +397,25 @@ function buildTransactionRequest(unsigned, { from, nonce, gasLimit, gasPrice, pr
|
|
|
396
397
|
}
|
|
397
398
|
return tx;
|
|
398
399
|
}
|
|
399
|
-
|
|
400
|
+
/**
|
|
401
|
+
* 构建利润多跳转账交易(强制 2 跳中转)
|
|
402
|
+
*/
|
|
403
|
+
async function buildProfitTransaction({ provider, seller, profitAmount, profitNonce, gasPrice, chainId, txType }) {
|
|
400
404
|
if (profitNonce === undefined || profitAmount === 0n) {
|
|
401
405
|
return null;
|
|
402
406
|
}
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
408
|
+
provider,
|
|
409
|
+
payerWallet: seller,
|
|
410
|
+
profitAmount,
|
|
411
|
+
profitRecipient: getProfitRecipient(),
|
|
412
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
407
413
|
gasPrice,
|
|
408
|
-
gasLimit: 21000n,
|
|
409
414
|
chainId,
|
|
410
|
-
|
|
415
|
+
txType,
|
|
416
|
+
startNonce: profitNonce
|
|
411
417
|
});
|
|
412
|
-
return
|
|
418
|
+
return profitHopResult.signedTransactions;
|
|
413
419
|
}
|
|
414
420
|
function countTruthy(values) {
|
|
415
421
|
return values.filter(Boolean).length;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
7
7
|
import { calculateSellAmount } from '../../utils/swap-helpers.js';
|
|
8
|
-
import { NonceManager, getOptimizedGasPrice } from '../../utils/bundle-helpers.js';
|
|
8
|
+
import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../utils/bundle-helpers.js';
|
|
9
9
|
import { FLAP_PORTAL_ADDRESSES } from '../constants.js';
|
|
10
10
|
import { PROFIT_CONFIG, ADDRESSES, ZERO_ADDRESS } from '../../utils/constants.js';
|
|
11
11
|
import { ERC20_ALLOWANCE_ABI, V2_ROUTER_QUOTE_ABI, ERC20_BALANCE_ABI } from '../../abis/common.js';
|
|
@@ -229,25 +229,26 @@ export async function flapBundleSwapMerkle(params) {
|
|
|
229
229
|
seller.signTransaction(sellTx),
|
|
230
230
|
buyer.signTransaction(buyTx)
|
|
231
231
|
]);
|
|
232
|
-
// ✅ 利润交易放在末尾
|
|
233
|
-
const profitTx = await buildProfitTransaction({
|
|
234
|
-
seller,
|
|
235
|
-
profitAmount: nativeProfitAmount, // ✅ 使用转换后的原生代币利润
|
|
236
|
-
profitNonce: noncePlan.profitNonce,
|
|
237
|
-
gasPrice,
|
|
238
|
-
chainId: chainContext.chainId,
|
|
239
|
-
txType
|
|
240
|
-
});
|
|
241
232
|
nonceManager.clearTemp();
|
|
242
|
-
// ✅ 组装顺序:贿赂 → 授权 → 卖出 → 买入
|
|
233
|
+
// ✅ 组装顺序:贿赂 → 授权 → 卖出 → 买入
|
|
243
234
|
const allTransactions = [];
|
|
244
235
|
if (bribeTx)
|
|
245
236
|
allTransactions.push(bribeTx);
|
|
246
237
|
if (approvalTx)
|
|
247
238
|
allTransactions.push(approvalTx);
|
|
248
239
|
allTransactions.push(signedSell, signedBuy);
|
|
249
|
-
|
|
250
|
-
|
|
240
|
+
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
241
|
+
const profitTxs = await buildProfitTransaction({
|
|
242
|
+
provider: chainContext.provider,
|
|
243
|
+
seller,
|
|
244
|
+
profitAmount: nativeProfitAmount,
|
|
245
|
+
profitNonce: noncePlan.profitNonce,
|
|
246
|
+
gasPrice,
|
|
247
|
+
chainId: chainContext.chainId,
|
|
248
|
+
txType
|
|
249
|
+
});
|
|
250
|
+
if (profitTxs)
|
|
251
|
+
allTransactions.push(...profitTxs);
|
|
251
252
|
return {
|
|
252
253
|
signedTransactions: allTransactions,
|
|
253
254
|
metadata: {
|
|
@@ -449,19 +450,25 @@ function buildTransactionRequest(unsigned, { from, nonce, gasLimit, gasPrice, pr
|
|
|
449
450
|
}
|
|
450
451
|
return tx;
|
|
451
452
|
}
|
|
452
|
-
|
|
453
|
+
/**
|
|
454
|
+
* 构建利润多跳转账交易(强制 2 跳中转)
|
|
455
|
+
*/
|
|
456
|
+
async function buildProfitTransaction({ provider, seller, profitAmount, profitNonce, gasPrice, chainId, txType }) {
|
|
453
457
|
if (!profitNonce || profitAmount === 0n) {
|
|
454
458
|
return null;
|
|
455
459
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
+
const profitHopResult = await buildProfitHopTransactions({
|
|
461
|
+
provider,
|
|
462
|
+
payerWallet: seller,
|
|
463
|
+
profitAmount,
|
|
464
|
+
profitRecipient: getProfitRecipient(),
|
|
465
|
+
hopCount: PROFIT_HOP_COUNT,
|
|
460
466
|
gasPrice,
|
|
461
|
-
gasLimit: 21000n,
|
|
462
467
|
chainId,
|
|
463
|
-
|
|
468
|
+
txType,
|
|
469
|
+
startNonce: profitNonce
|
|
464
470
|
});
|
|
471
|
+
return profitHopResult.signedTransactions;
|
|
465
472
|
}
|
|
466
473
|
function calculateProfitAmount(quotedNative) {
|
|
467
474
|
if (quotedNative <= 0n) {
|
|
@@ -620,22 +627,9 @@ export async function flapBatchSwapMerkle(params) {
|
|
|
620
627
|
});
|
|
621
628
|
bribeNonceOffset = 1; // 卖出交易的 nonce 需要 +1
|
|
622
629
|
}
|
|
623
|
-
// 利润交易放在末尾(由卖方发送,与贿赂交易同一钱包)
|
|
624
|
-
let profitTx = null;
|
|
625
|
-
if (nativeProfitAmount > 0n) {
|
|
626
|
-
// 利润交易 nonce = 卖出 nonce + 1
|
|
627
|
-
const profitNonce = sellNonce + bribeNonceOffset + 1;
|
|
628
|
-
profitTx = await seller.signTransaction({
|
|
629
|
-
to: getProfitRecipient(),
|
|
630
|
-
value: nativeProfitAmount,
|
|
631
|
-
nonce: profitNonce,
|
|
632
|
-
gasPrice,
|
|
633
|
-
gasLimit: 21000n,
|
|
634
|
-
chainId: chainContext.chainId,
|
|
635
|
-
type: txType
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
630
|
nonceManager.clearTemp();
|
|
631
|
+
// 利润多跳交易 nonce 计算
|
|
632
|
+
const profitNonce = nativeProfitAmount > 0n ? sellNonce + bribeNonceOffset + 1 : undefined;
|
|
639
633
|
// ✅ 并行签名所有交易
|
|
640
634
|
const sellTx = buildTransactionRequest(sellUnsigned, {
|
|
641
635
|
from: seller.address,
|
|
@@ -663,7 +657,7 @@ export async function flapBatchSwapMerkle(params) {
|
|
|
663
657
|
return buyer.signTransaction(buyTx);
|
|
664
658
|
})
|
|
665
659
|
]);
|
|
666
|
-
// ✅ 按顺序组装交易数组:贿赂 → 授权 → 卖出 → 买入
|
|
660
|
+
// ✅ 按顺序组装交易数组:贿赂 → 授权 → 卖出 → 买入
|
|
667
661
|
const signedTransactions = [];
|
|
668
662
|
if (bribeTx)
|
|
669
663
|
signedTransactions.push(bribeTx);
|
|
@@ -671,8 +665,20 @@ export async function flapBatchSwapMerkle(params) {
|
|
|
671
665
|
signedTransactions.push(approvalTx);
|
|
672
666
|
signedTransactions.push(signedSell);
|
|
673
667
|
signedTransactions.push(...signedBuys);
|
|
674
|
-
|
|
675
|
-
|
|
668
|
+
// ✅ 利润多跳转账(强制 2 跳中转)
|
|
669
|
+
if (profitNonce !== undefined && nativeProfitAmount > 0n) {
|
|
670
|
+
const profitTxs = await buildProfitTransaction({
|
|
671
|
+
provider: chainContext.provider,
|
|
672
|
+
seller,
|
|
673
|
+
profitAmount: nativeProfitAmount,
|
|
674
|
+
profitNonce,
|
|
675
|
+
gasPrice,
|
|
676
|
+
chainId: chainContext.chainId,
|
|
677
|
+
txType
|
|
678
|
+
});
|
|
679
|
+
if (profitTxs)
|
|
680
|
+
signedTransactions.push(...profitTxs);
|
|
681
|
+
}
|
|
676
682
|
return {
|
|
677
683
|
signedTransactions,
|
|
678
684
|
metadata: {
|
|
@@ -923,20 +929,6 @@ export async function flapQuickBatchSwapMerkle(params) {
|
|
|
923
929
|
return buyer.signTransaction(buyTx);
|
|
924
930
|
}));
|
|
925
931
|
console.log(`[flapQuickBatchSwapMerkle] ${signedBuys.length} 笔买入交易已签名`);
|
|
926
|
-
// ==================== 5. 利润交易 ====================
|
|
927
|
-
let profitTx = null;
|
|
928
|
-
if (nativeProfitAmount > 0n) {
|
|
929
|
-
profitTx = await seller.signTransaction({
|
|
930
|
-
to: getProfitRecipient(),
|
|
931
|
-
value: nativeProfitAmount,
|
|
932
|
-
nonce: sellerNonce++,
|
|
933
|
-
gasPrice,
|
|
934
|
-
gasLimit: 21000n,
|
|
935
|
-
chainId: chainContext.chainId,
|
|
936
|
-
type: txType
|
|
937
|
-
});
|
|
938
|
-
console.log(`[flapQuickBatchSwapMerkle] 利润交易已签名`);
|
|
939
|
-
}
|
|
940
932
|
nonceManager.clearTemp();
|
|
941
933
|
// ==================== 组装交易数组 ====================
|
|
942
934
|
const signedTransactions = [];
|
|
@@ -945,14 +937,27 @@ export async function flapQuickBatchSwapMerkle(params) {
|
|
|
945
937
|
signedTransactions.push(signedSell);
|
|
946
938
|
signedTransactions.push(...transferTxs);
|
|
947
939
|
signedTransactions.push(...signedBuys);
|
|
948
|
-
|
|
949
|
-
|
|
940
|
+
// ==================== 5. 利润多跳转账(强制 2 跳中转)====================
|
|
941
|
+
if (nativeProfitAmount > 0n) {
|
|
942
|
+
const profitTxs = await buildProfitTransaction({
|
|
943
|
+
provider: chainContext.provider,
|
|
944
|
+
seller,
|
|
945
|
+
profitAmount: nativeProfitAmount,
|
|
946
|
+
profitNonce: sellerNonce++,
|
|
947
|
+
gasPrice,
|
|
948
|
+
chainId: chainContext.chainId,
|
|
949
|
+
txType
|
|
950
|
+
});
|
|
951
|
+
if (profitTxs)
|
|
952
|
+
signedTransactions.push(...profitTxs);
|
|
953
|
+
console.log(`[flapQuickBatchSwapMerkle] 利润多跳交易已签名: ${profitTxs?.length || 0} 笔`);
|
|
954
|
+
}
|
|
950
955
|
console.log(`[flapQuickBatchSwapMerkle] 交易组装完成: ${signedTransactions.length} 笔`);
|
|
951
956
|
console.log(` - 贿赂: ${bribeTx ? 1 : 0}`);
|
|
952
957
|
console.log(` - 卖出: 1`);
|
|
953
958
|
console.log(` - 转账: ${transferTxs.length}`);
|
|
954
959
|
console.log(` - 买入: ${signedBuys.length}`);
|
|
955
|
-
console.log(` -
|
|
960
|
+
console.log(` - 利润多跳: ${nativeProfitAmount > 0n ? PROFIT_HOP_COUNT + 1 : 0}`);
|
|
956
961
|
return {
|
|
957
962
|
signedTransactions,
|
|
958
963
|
metadata: {
|