four-flap-meme-sdk 4.0.8 → 4.0.10
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/bundle/four-meme/swap/batch.js +4 -4
- package/dist/bundle/four-meme/swap/bundle.js +7 -4
- package/dist/bundle/four-meme/swap/quick-batch.js +4 -4
- package/dist/bundle/four-meme/swap-buy-first/multi-wallet.js +3 -6
- package/dist/bundle/four-meme/swap-buy-first/single.js +5 -6
- package/dist/bundle/four-meme/swap-sign-helpers.d.ts +2 -0
- package/dist/bundle/four-meme/swap-sign-helpers.js +16 -0
- package/dist/chains/bsc/pancake/bundle-buy-first-multi-wallet.js +10 -14
- package/dist/chains/bsc/pancake/bundle-buy-first.js +10 -15
- package/dist/chains/bsc/pancake/quote.d.ts +12 -1
- package/dist/chains/bsc/pancake/quote.js +21 -4
- package/dist/chains/bsc/pancake/swap-batch.js +15 -8
- package/dist/chains/bsc/pancake/swap-quick.js +15 -7
- package/dist/chains/bsc/pancake/swap-single.js +15 -13
- package/dist/chains/eni/platforms/daoaas/portal-direct-submit.js +4 -4
- package/dist/chains/xlayer/eip7702/bundle-swap-multi.js +4 -4
- package/dist/chains/xlayer/eip7702/profit.d.ts +6 -12
- package/dist/chains/xlayer/eip7702/profit.js +15 -16
- package/dist/chains/xlayer/eip7702/volume-bundle.js +5 -5
- package/dist/chains/xlayer/eip7702/volume-wash.js +4 -4
- package/dist/chains/xlayer/eoa/quote.d.ts +1 -1
- package/dist/chains/xlayer/eoa/quote.js +3 -4
- package/dist/core/constants/index.d.ts +2 -2
- package/dist/core/constants/index.js +2 -2
- package/dist/core/constants/profit.d.ts +6 -1
- package/dist/core/constants/profit.js +11 -1
- package/dist/core/constants/profit.test.d.ts +1 -0
- package/dist/core/constants/profit.test.js +18 -0
- package/dist/core/constants/quote.d.ts +2 -0
- package/dist/core/constants/quote.js +13 -0
- package/dist/core/quote/quote-helpers.d.ts +11 -0
- package/dist/core/quote/quote-helpers.js +48 -4
- package/dist/domains/flap/portal-bundle-merkle/core-helpers.js +3 -35
- package/dist/domains/flap/portal-bundle-merkle/swap-batch.js +18 -7
- package/dist/domains/flap/portal-bundle-merkle/swap-buy-first-multi-wallet.js +11 -15
- package/dist/domains/flap/portal-bundle-merkle/swap-buy-first-quote.js +3 -24
- package/dist/domains/flap/portal-bundle-merkle/swap-buy-first.js +12 -17
- package/dist/domains/flap/portal-bundle-merkle/swap-helpers.js +3 -23
- package/dist/domains/flap/portal-bundle-merkle/swap-planning.d.ts +10 -1
- package/dist/domains/flap/portal-bundle-merkle/swap-planning.js +23 -8
- package/dist/domains/flap/portal-bundle-merkle/swap-quick-batch.js +15 -7
- package/dist/domains/flap/portal-bundle-merkle/swap-single.js +18 -9
- package/dist/exports/root-foundations.d.ts +1 -1
- package/dist/exports/root-foundations.js +1 -1
- package/dist/utils/constants.d.ts +1 -1
- package/dist/utils/constants.js +1 -1
- package/package.json +1 -1
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Four.meme 内盘批量换手(Merkle Bundle)— 一卖多买流程
|
|
3
3
|
*/
|
|
4
4
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
5
|
-
import { countSellerNonceSlots, createFourSwapGasContext, fetchFourSwapSellQuoteAllowanceAndBalances,
|
|
5
|
+
import { countSellerNonceSlots, createFourSwapGasContext, fetchFourSwapSellQuoteAllowanceAndBalances, grossUpFourSellProceedsToBuySide, needsTmTokenApproval, planSellerNonces, signTmMaxApprovalTx, } from '../swap-sign-helpers.js';
|
|
6
6
|
import { signBribeTransaction } from '../../../core/sign-context-helpers.js';
|
|
7
7
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
8
8
|
import { NonceManager, getOptimizedGasPrice, getGasPriceConfig, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
9
9
|
import { getBribeAmount, getProfitRecipient } from '../../config-helpers.js';
|
|
10
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
10
11
|
import { TM_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
11
12
|
/**
|
|
12
13
|
* Four 内盘批量换手(一卖多买)
|
|
@@ -57,9 +58,8 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
57
58
|
});
|
|
58
59
|
// 检查是否需要授权
|
|
59
60
|
const needApproval = needsTmTokenApproval(currentAllowance, decimals);
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
const profitAmount = totalBuyerFunds > 0n ? (totalBuyerFunds * BigInt(profitRateBps)) / 10000n : 0n;
|
|
61
|
+
const profitNotional = await grossUpFourSellProceedsToBuySide(provider, tokenAddress, sellAmountWei, totalBuyerFunds);
|
|
62
|
+
const profitAmount = profitNotional > 0n ? calculateBundleSwapRoundTripProfit(profitNotional, profitNotional) : 0n;
|
|
63
63
|
// ✅ 获取贿赂金额
|
|
64
64
|
const bribeAmount = getBribeAmount(config);
|
|
65
65
|
const needBribeTx = bribeAmount > 0n;
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Four.meme 内盘捆绑换手(Merkle Bundle)— 单卖单买流程
|
|
3
3
|
*/
|
|
4
4
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
5
|
-
import { countSellerNonceSlots, createFourSwapGasContext, fetchFourSwapSellQuoteAndAllowance,
|
|
5
|
+
import { countSellerNonceSlots, createFourSwapGasContext, fetchFourSwapSellQuoteAndAllowance, grossUpFourSellProceedsToBuySide, needsTmTokenApproval, planSellerNonces, signTmMaxApprovalTx, } from '../swap-sign-helpers.js';
|
|
6
6
|
import { signBribeTransaction } from '../../../core/sign-context-helpers.js';
|
|
7
7
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
8
8
|
import { NonceManager, getOptimizedGasPrice, getGasPriceConfig, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
9
9
|
import { getBribeAmount, getProfitRecipient } from '../../config-helpers.js';
|
|
10
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
10
11
|
import { TM_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
11
12
|
/**
|
|
12
13
|
* Four内盘捆绑换手
|
|
@@ -39,10 +40,12 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
39
40
|
}
|
|
40
41
|
// 检查是否需要授权
|
|
41
42
|
const needApproval = needsTmTokenApproval(currentAllowance, decimals);
|
|
42
|
-
//
|
|
43
|
+
// 利润配置:按卖出代币的买侧计价收万六,避免曲线折价后只剩万五点多
|
|
43
44
|
const extractProfit = true;
|
|
44
|
-
const
|
|
45
|
-
const profitAmount = extractProfit &&
|
|
45
|
+
const profitNotional = await grossUpFourSellProceedsToBuySide(provider, tokenAddress, sellAmountWei, sellerWillGetBNB);
|
|
46
|
+
const profitAmount = extractProfit && profitNotional > 0n
|
|
47
|
+
? calculateBundleSwapRoundTripProfit(profitNotional, profitNotional)
|
|
48
|
+
: 0n;
|
|
46
49
|
// ✅ 获取贿赂金额
|
|
47
50
|
const bribeAmount = getBribeAmount(config);
|
|
48
51
|
const needBribeTx = bribeAmount > 0n;
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* Four.meme 内盘快捷批量换手(Merkle Bundle)— 资金利用率模式流程
|
|
3
3
|
*/
|
|
4
4
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
5
|
-
import { createFourSwapGasContext,
|
|
5
|
+
import { createFourSwapGasContext, grossUpFourSellProceedsToBuySide, quoteFourSwapSellFunds, } from '../swap-sign-helpers.js';
|
|
6
6
|
import { generateDisperseHopPaths, buildNativeHopChain, NATIVE_TRANSFER_GAS_LIMIT } from '../swap-hop-helpers.js';
|
|
7
7
|
import { signBribeTransaction } from '../../../core/sign-context-helpers.js';
|
|
8
8
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
9
9
|
import { NonceManager, getOptimizedGasPrice, getGasPriceConfig, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
10
10
|
import { getBribeAmount, getProfitRecipient } from '../../config-helpers.js';
|
|
11
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
11
12
|
import { TM_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
12
13
|
/**
|
|
13
14
|
* Four 内盘快捷批量换手(资金利用率模式)
|
|
@@ -50,9 +51,8 @@ export async function fourQuickBatchSwapMerkle(params) {
|
|
|
50
51
|
]);
|
|
51
52
|
const { amount: sellAmountWei, decimals } = sellAmountResult;
|
|
52
53
|
const estimatedBNBOut = await quoteFourSwapSellFunds(provider, tokenAddress, sellAmountWei);
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
const profitAmount = estimatedBNBOut > 0n ? (estimatedBNBOut * BigInt(profitRateBps)) / 10000n : 0n;
|
|
54
|
+
const profitNotional = await grossUpFourSellProceedsToBuySide(provider, tokenAddress, sellAmountWei, estimatedBNBOut);
|
|
55
|
+
const profitAmount = profitNotional > 0n ? calculateBundleSwapRoundTripProfit(profitNotional, profitNotional) : 0n;
|
|
56
56
|
const distributableAmount = estimatedBNBOut - profitAmount;
|
|
57
57
|
// ✅ 计算每个买方分到的金额
|
|
58
58
|
let transferAmountsWei;
|
|
@@ -5,12 +5,12 @@ import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
|
5
5
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
6
6
|
import { createSignProvider } from '../../../core/sign-context-helpers.js';
|
|
7
7
|
import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
8
|
-
import { ADDRESSES, BLOCKRAZOR_BUILDER_EOA, CHAINS } from '../../../core/constants/index.js';
|
|
8
|
+
import { ADDRESSES, BLOCKRAZOR_BUILDER_EOA, CHAINS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
9
9
|
import { TM_ABI, HELPER3_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
10
10
|
import { getTxType, getGasPriceConfig, getProfitRecipient, getBribeAmount } from '../../config-helpers.js';
|
|
11
11
|
import { trySell } from '../../../domains/four/contracts/tm.js';
|
|
12
12
|
import { splitAmountByWeight as splitAmount } from '../../../core/amount/split-by-weight.js';
|
|
13
|
-
import {
|
|
13
|
+
import { validateSwapCounts } from './helpers.js';
|
|
14
14
|
/**
|
|
15
15
|
* ✅ Four 多钱包捆绑换手
|
|
16
16
|
* - 多个买方钱包执行买入(每个钱包1笔)
|
|
@@ -28,9 +28,6 @@ export async function fourBundleBuyFirstMultiWallet(params) {
|
|
|
28
28
|
throw new Error('卖方钱包数量不能为0');
|
|
29
29
|
// 验证总交易数不超过限制
|
|
30
30
|
validateSwapCounts(buyCount, sellCount);
|
|
31
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
32
|
-
const totalTxCount = buyCount + sellCount;
|
|
33
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
34
31
|
const chainIdNum = config.chainId ?? CHAINS.BSC.chainId;
|
|
35
32
|
const provider = createSignProvider(config.rpcUrl, chainIdNum, 'BSC');
|
|
36
33
|
const nonceManager = new NonceManager(provider);
|
|
@@ -85,7 +82,7 @@ export async function fourBundleBuyFirstMultiWallet(params) {
|
|
|
85
82
|
noncesMap.set(wallet.address.toLowerCase(), noncesArray[i]);
|
|
86
83
|
});
|
|
87
84
|
const estimatedSellFunds = sellResult.funds;
|
|
88
|
-
const profitAmount = (estimatedSellFunds
|
|
85
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalFundsWei, estimatedSellFunds > 0n ? estimatedSellFunds : totalFundsWei);
|
|
89
86
|
// ✅ 第三批并行:构建并签名所有交易
|
|
90
87
|
const allTransactions = [];
|
|
91
88
|
const tm = new Contract(TM_ADDRESS, TM_ABI, provider);
|
|
@@ -7,12 +7,12 @@ import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
|
7
7
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
8
8
|
import { createSignProvider } from '../../../core/sign-context-helpers.js';
|
|
9
9
|
import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
10
|
-
import { ADDRESSES, BLOCKRAZOR_BUILDER_EOA, CHAINS } from '../../../core/constants/index.js';
|
|
10
|
+
import { ADDRESSES, BLOCKRAZOR_BUILDER_EOA, CHAINS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
11
11
|
import { TM_ABI, HELPER3_ABI, TM_ADDRESS } from '../swap-internal.js';
|
|
12
12
|
import { getTxType, getGasPriceConfig, getProfitRecipient, getBribeAmount } from '../../config-helpers.js';
|
|
13
13
|
import { trySell } from '../../../domains/four/contracts/tm.js';
|
|
14
14
|
import { splitAmountByWeight as splitAmount } from '../../../core/amount/split-by-weight.js';
|
|
15
|
-
import {
|
|
15
|
+
import { validateSwapCounts } from './helpers.js';
|
|
16
16
|
import { fourBundleBuyFirstMultiWallet } from './multi-wallet.js';
|
|
17
17
|
export async function fourBundleBuyFirstMerkle(params) {
|
|
18
18
|
const { buyerPrivateKey, buyerPrivateKeys, buyerFunds, buyerFundsPercentage, sellerPrivateKey, sellerPrivateKeys, tokenAddress, config, buyCount: _buyCount, sellCount: _sellCount, } = params;
|
|
@@ -35,9 +35,6 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
35
35
|
throw new Error('单钱包模式需要提供 buyerPrivateKey 和 sellerPrivateKey');
|
|
36
36
|
}
|
|
37
37
|
validateSwapCounts(buyCount, sellCount);
|
|
38
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
39
|
-
const totalTxCount = buyCount + sellCount;
|
|
40
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
41
38
|
const chainIdNum = config.chainId ?? CHAINS.BSC.chainId;
|
|
42
39
|
const provider = createSignProvider(config.rpcUrl, chainIdNum, 'BSC');
|
|
43
40
|
const buyer = new Wallet(buyerPrivateKey, provider);
|
|
@@ -117,7 +114,9 @@ export async function fourBundleBuyFirstMerkle(params) {
|
|
|
117
114
|
Promise.all(sellUnsignedPromises),
|
|
118
115
|
]);
|
|
119
116
|
const estimatedSellFunds = sellResult.funds;
|
|
120
|
-
const profitAmount = extractProfit
|
|
117
|
+
const profitAmount = extractProfit
|
|
118
|
+
? calculateBundleSwapRoundTripProfit(buyerFundsWei, estimatedSellFunds > 0n ? estimatedSellFunds : buyerFundsWei)
|
|
119
|
+
: 0n;
|
|
121
120
|
// ✅ 贿赂交易放在首位
|
|
122
121
|
let bribeTx = null;
|
|
123
122
|
if (needBribeTx && multiNoncePlan.bribeNonce !== undefined) {
|
|
@@ -8,6 +8,8 @@ export declare function countSellerNonceSlots(needBribeTx: boolean, needApproval
|
|
|
8
8
|
export declare function planSellerNonces(sellerNonces: number[], needBribeTx: boolean, needApproval: boolean, extractProfit: boolean): SellerNoncePlan;
|
|
9
9
|
export declare function signTmMaxApprovalTx(seller: Wallet, tokenAddress: string, approvalNonce: number, gasPrice: bigint, chainIdNum: number, txType: 0 | 2): Promise<string>;
|
|
10
10
|
export declare function quoteFourSwapSellFunds(provider: JsonRpcProvider, tokenAddress: string, sellAmountWei: bigint): Promise<bigint>;
|
|
11
|
+
/** 换手按卖出所得收万六会像万五点多:用所得能买回的数量把计价额抬到买侧。 */
|
|
12
|
+
export declare function grossUpFourSellProceedsToBuySide(provider: JsonRpcProvider, tokenAddress: string, sellAmountWei: bigint, sellProceedsWei: bigint): Promise<bigint>;
|
|
11
13
|
export declare function fetchFourSwapSellQuoteAndAllowance(provider: JsonRpcProvider, tokenAddress: string, sellerAddress: string, sellAmountWei: bigint): Promise<{
|
|
12
14
|
sellFunds: bigint;
|
|
13
15
|
allowance: bigint;
|
|
@@ -54,6 +54,22 @@ export async function quoteFourSwapSellFunds(provider, tokenAddress, sellAmountW
|
|
|
54
54
|
const sellQuote = await helper3.trySell(tokenAddress, sellAmountWei);
|
|
55
55
|
return sellQuote.funds;
|
|
56
56
|
}
|
|
57
|
+
/** 换手按卖出所得收万六会像万五点多:用所得能买回的数量把计价额抬到买侧。 */
|
|
58
|
+
export async function grossUpFourSellProceedsToBuySide(provider, tokenAddress, sellAmountWei, sellProceedsWei) {
|
|
59
|
+
if (sellProceedsWei <= 0n || sellAmountWei <= 0n)
|
|
60
|
+
return sellProceedsWei;
|
|
61
|
+
try {
|
|
62
|
+
const helper3 = new Contract(ADDRESSES.BSC.TokenManagerHelper3, HELPER3_ABI, provider);
|
|
63
|
+
const buyQuote = await helper3.tryBuy(tokenAddress, 0n, sellProceedsWei);
|
|
64
|
+
const tokensBought = buyQuote.estimatedAmount;
|
|
65
|
+
if (tokensBought <= 0n || tokensBought >= sellAmountWei)
|
|
66
|
+
return sellProceedsWei;
|
|
67
|
+
return (sellProceedsWei * sellAmountWei) / tokensBought;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return sellProceedsWei;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
57
73
|
export async function fetchFourSwapSellQuoteAndAllowance(provider, tokenAddress, sellerAddress, sellAmountWei) {
|
|
58
74
|
const helper3 = new Contract(ADDRESSES.BSC.TokenManagerHelper3, HELPER3_ABI, provider);
|
|
59
75
|
const erc20 = new Contract(tokenAddress, ERC20_ALLOWANCE_ABI, provider);
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
import { ethers, Wallet } from 'ethers';
|
|
5
5
|
import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
6
6
|
import { NonceManager, getDeadline } from '../../../utils/bundle-helpers.js';
|
|
7
|
-
import { BLOCKRAZOR_BUILDER_EOA, ZERO_ADDRESS, GAS_LIMITS } from '../../../core/constants/index.js';
|
|
8
|
-
import {
|
|
7
|
+
import { BLOCKRAZOR_BUILDER_EOA, ZERO_ADDRESS, GAS_LIMITS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
8
|
+
import { quoteRoundTripProfitToNative } from '../../../core/quote/quote-helpers.js';
|
|
9
9
|
import { splitAmountByWeight as splitAmount } from '../../../core/amount/split-by-weight.js';
|
|
10
10
|
import { createPancakeContext, getGasPrice, quoteTokenOutput } from './bundle-buy-first-quote.js';
|
|
11
|
-
import {
|
|
11
|
+
import { validateSwapCounts } from './bundle-buy-first-plan.js';
|
|
12
12
|
import { buildSingleBuyTx, buildSingleSellTx } from './bundle-buy-first-build.js';
|
|
13
13
|
import { buildProfitTransaction } from './bundle-buy-first-profit.js';
|
|
14
14
|
/**
|
|
@@ -29,9 +29,6 @@ export async function pancakeBundleBuyFirstMultiWallet(params) {
|
|
|
29
29
|
throw new Error('卖方钱包数量不能为0');
|
|
30
30
|
// 验证总交易数不超过限制
|
|
31
31
|
validateSwapCounts(buyCount, sellCount);
|
|
32
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
33
|
-
const totalTxCount = buyCount + sellCount;
|
|
34
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
35
32
|
// ✅ 判断是否使用原生代币
|
|
36
33
|
const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
|
|
37
34
|
const context = createPancakeContext(config);
|
|
@@ -91,16 +88,15 @@ export async function pancakeBundleBuyFirstMultiWallet(params) {
|
|
|
91
88
|
}
|
|
92
89
|
// ✅ 将代币平均分配给卖方
|
|
93
90
|
const sellAmountsWei = splitAmount(actualTokenOut, sellCount);
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (
|
|
91
|
+
// 买合计万三 + 卖合计万三。ERC-20 先把买入合计折成 BNB 再计提,避免 ANTFUN 微额报价为 0
|
|
92
|
+
let profitAmount = 0n;
|
|
93
|
+
if (useNativeToken) {
|
|
94
|
+
profitAmount = calculateBundleSwapRoundTripProfit(totalFundsWei, totalFundsWei);
|
|
95
|
+
}
|
|
96
|
+
else if (quoteToken && totalFundsWei > 0n) {
|
|
100
97
|
const version = routeParams.routeType === 'v2' ? 'v2' : 'v3';
|
|
101
98
|
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
102
|
-
profitAmount = await
|
|
103
|
-
// ERC20→BNB 转换完成
|
|
99
|
+
profitAmount = await quoteRoundTripProfitToNative(context.provider, quoteToken, totalFundsWei, totalFundsWei, 'BSC', version, fee, config.v2RouterAddress);
|
|
104
100
|
}
|
|
105
101
|
// ✅ 第三批并行:构建并签名所有交易
|
|
106
102
|
const allTransactions = [];
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
import { ethers, Wallet } from 'ethers';
|
|
5
5
|
import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
6
6
|
import { NonceManager } from '../../../utils/bundle-helpers.js';
|
|
7
|
-
import { BLOCKRAZOR_BUILDER_EOA, ZERO_ADDRESS, GAS_LIMITS } from '../../../core/constants/index.js';
|
|
8
|
-
import {
|
|
9
|
-
import { buildMultiRouteTransactions, buildProfitTransaction, calculateBuyerFunds, createPancakeContext, getGasPrice,
|
|
7
|
+
import { BLOCKRAZOR_BUILDER_EOA, ZERO_ADDRESS, GAS_LIMITS, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
8
|
+
import { quoteRoundTripProfitToNative } from '../../../core/quote/quote-helpers.js';
|
|
9
|
+
import { buildMultiRouteTransactions, buildProfitTransaction, calculateBuyerFunds, createPancakeContext, getGasPrice, pancakeBundleBuyFirstMultiWallet, planMultiNonces, quoteTokenOutput, splitAmount, validateFinalBalances, validateSwapCounts, } from './bundle-buy-first-helpers.js';
|
|
10
10
|
export async function pancakeBundleBuyFirstMerkle(params) {
|
|
11
11
|
const { buyerPrivateKey, buyerPrivateKeys, sellerPrivateKey, sellerPrivateKeys, routeParams, buyerFunds, buyerFundsPercentage, config, quoteToken, quoteTokenDecimals = 18, buyCount: _buyCount, sellCount: _sellCount, taxRateBps = 0, // ✅ 税率(基点),用于计算实际可卖出代币数量
|
|
12
12
|
} = params;
|
|
@@ -34,9 +34,6 @@ export async function pancakeBundleBuyFirstMerkle(params) {
|
|
|
34
34
|
throw new Error('单钱包模式需要提供 buyerPrivateKey 和 sellerPrivateKey');
|
|
35
35
|
}
|
|
36
36
|
validateSwapCounts(buyCount, sellCount);
|
|
37
|
-
// ✅ 计算利润比例(根据 userType 动态调整)
|
|
38
|
-
const totalTxCount = buyCount + sellCount;
|
|
39
|
-
const profitRateBps = getProfitRatePerTxBps(config.userType) * totalTxCount;
|
|
40
37
|
// ✅ 判断是否使用原生代币(BNB)或 ERC20 代币(如 USDT)
|
|
41
38
|
const useNativeToken = !quoteToken || quoteToken === ZERO_ADDRESS;
|
|
42
39
|
const context = createPancakeContext(config);
|
|
@@ -83,17 +80,15 @@ export async function pancakeBundleBuyFirstMerkle(params) {
|
|
|
83
80
|
const gasPrice = await getGasPrice(context.provider, config);
|
|
84
81
|
const txType = config.txType ?? 0;
|
|
85
82
|
const nonceManager = new NonceManager(context.provider);
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (!useNativeToken && tokenProfitAmount > 0n && quoteToken) {
|
|
83
|
+
// 买合计万三 + 卖合计万三。ERC-20 先把买入合计折成 BNB 再计提,避免 ANTFUN 微额报价为 0
|
|
84
|
+
let profitAmount = 0n;
|
|
85
|
+
if (useNativeToken) {
|
|
86
|
+
profitAmount = calculateBundleSwapRoundTripProfit(buyerFundsInfo.buyerFundsWei, buyerFundsInfo.buyerFundsWei);
|
|
87
|
+
}
|
|
88
|
+
else if (quoteToken && buyerFundsInfo.buyerFundsWei > 0n) {
|
|
93
89
|
const version = routeParams.routeType === 'v2' ? 'v2' : 'v3';
|
|
94
90
|
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
95
|
-
profitAmount = await
|
|
96
|
-
// ERC20→BNB 转换完成
|
|
91
|
+
profitAmount = await quoteRoundTripProfitToNative(context.provider, quoteToken, buyerFundsInfo.buyerFundsWei, buyerFundsInfo.buyerFundsWei, 'BSC', version, fee, config.v2RouterAddress);
|
|
97
92
|
}
|
|
98
93
|
// ✅ 获取贿赂金额
|
|
99
94
|
const bribeAmount = config.bribeAmount && config.bribeAmount > 0 ? ethers.parseEther(String(config.bribeAmount)) : 0n;
|
|
@@ -5,7 +5,18 @@ export declare function quoteSellOutput({ routeParams, sellAmountWei, provider,
|
|
|
5
5
|
* 根据 userType 计算利润率
|
|
6
6
|
*/
|
|
7
7
|
export declare function getProfitRateBps(_userType?: UserType): number;
|
|
8
|
-
export declare function calculateProfitAmount(estimatedBNBOut: bigint,
|
|
8
|
+
export declare function calculateProfitAmount(estimatedBNBOut: bigint, _userType?: UserType): bigint;
|
|
9
|
+
/** 换手按卖出所得收万六会像万五点多:用所得能买回的数量把计价额抬到买侧。 */
|
|
10
|
+
export declare function grossUpPancakeSellProceedsToBuySide(params: {
|
|
11
|
+
provider: ethers.JsonRpcProvider;
|
|
12
|
+
tokenAddress: string;
|
|
13
|
+
sellAmountWei: bigint;
|
|
14
|
+
sellProceedsWei: bigint;
|
|
15
|
+
quoteTokenIn: string;
|
|
16
|
+
version: 'v2' | 'v3';
|
|
17
|
+
fee?: number;
|
|
18
|
+
v2RouterAddress?: string;
|
|
19
|
+
}): Promise<bigint>;
|
|
9
20
|
/**
|
|
10
21
|
* ✅ 获取 ERC20 代币 → 原生代币(BNB)的报价
|
|
11
22
|
* 用于将 ERC20 利润转换为 BNB
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ADDRESSES, getProfitRateBps as getSharedProfitRateBps } from '../../../core/constants/index.js';
|
|
1
|
+
import { ADDRESSES, getProfitRateBps as getSharedProfitRateBps, calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
2
2
|
import { quoteV2, quoteV3 } from '../../../core/quote/quote-helpers.js';
|
|
3
3
|
import { WBNB_ADDRESS, } from './bundle-swap-types.js';
|
|
4
4
|
export async function quoteSellOutput({ routeParams, sellAmountWei, provider, v2RouterAddress, }) {
|
|
@@ -44,12 +44,29 @@ export async function quoteSellOutput({ routeParams, sellAmountWei, provider, v2
|
|
|
44
44
|
export function getProfitRateBps(_userType) {
|
|
45
45
|
return getSharedProfitRateBps('bundleSwap');
|
|
46
46
|
}
|
|
47
|
-
export function calculateProfitAmount(estimatedBNBOut,
|
|
47
|
+
export function calculateProfitAmount(estimatedBNBOut, _userType) {
|
|
48
48
|
if (estimatedBNBOut <= 0n) {
|
|
49
49
|
return 0n;
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
return calculateBundleSwapRoundTripProfit(estimatedBNBOut, estimatedBNBOut);
|
|
52
|
+
}
|
|
53
|
+
/** 换手按卖出所得收万六会像万五点多:用所得能买回的数量把计价额抬到买侧。 */
|
|
54
|
+
export async function grossUpPancakeSellProceedsToBuySide(params) {
|
|
55
|
+
const { sellAmountWei, sellProceedsWei } = params;
|
|
56
|
+
if (sellProceedsWei <= 0n || sellAmountWei <= 0n)
|
|
57
|
+
return sellProceedsWei;
|
|
58
|
+
try {
|
|
59
|
+
const quoted = params.version === 'v3'
|
|
60
|
+
? await quoteV3(params.provider, params.quoteTokenIn, params.tokenAddress, sellProceedsWei, 'BSC', params.fee)
|
|
61
|
+
: await quoteV2(params.provider, params.quoteTokenIn, params.tokenAddress, sellProceedsWei, 'BSC', params.v2RouterAddress);
|
|
62
|
+
const tokensBought = quoted.amountOut;
|
|
63
|
+
if (tokensBought <= 0n || tokensBought >= sellAmountWei)
|
|
64
|
+
return sellProceedsWei;
|
|
65
|
+
return (sellProceedsWei * sellAmountWei) / tokensBought;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return sellProceedsWei;
|
|
69
|
+
}
|
|
53
70
|
}
|
|
54
71
|
/**
|
|
55
72
|
* ✅ 获取 ERC20 代币 → 原生代币(BNB)的报价
|
|
@@ -6,7 +6,7 @@ import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
|
6
6
|
import { ethers, Contract, Wallet } from 'ethers';
|
|
7
7
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
8
8
|
import { NonceManager, getDeadline, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
9
|
-
import { BRIBE_GAS_LIMIT, ERC20_BALANCE_OF_ABI, FLAT_FEE, PANCAKE_V2_ROUTER_ABI, PANCAKE_V2_ROUTER_ADDRESS, PANCAKE_V3_ROUTER_ABI, PANCAKE_V3_ROUTER_ADDRESS, ZERO_ADDRESS, calculateProfitAmount, createPancakeContext, getERC20ToNativeQuote, getGasPrice, quoteSellOutput, } from './bundle-swap-helpers.js';
|
|
9
|
+
import { BRIBE_GAS_LIMIT, ERC20_BALANCE_OF_ABI, FLAT_FEE, PANCAKE_V2_ROUTER_ABI, PANCAKE_V2_ROUTER_ADDRESS, PANCAKE_V3_ROUTER_ABI, PANCAKE_V3_ROUTER_ADDRESS, WBNB_ADDRESS, ZERO_ADDRESS, calculateProfitAmount, createPancakeContext, getERC20ToNativeQuote, getGasPrice, grossUpPancakeSellProceedsToBuySide, quoteSellOutput, } from './bundle-swap-helpers.js';
|
|
10
10
|
/**
|
|
11
11
|
* PancakeSwap 批量换手(一卖多买)
|
|
12
12
|
*
|
|
@@ -203,18 +203,25 @@ export async function pancakeBatchSwapMerkle(params) {
|
|
|
203
203
|
type: txType,
|
|
204
204
|
});
|
|
205
205
|
}
|
|
206
|
-
|
|
206
|
+
const version = routeParams.routeType === 'v2' ? 'v2' : 'v3';
|
|
207
|
+
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
208
|
+
const profitNotional = await grossUpPancakeSellProceedsToBuySide({
|
|
209
|
+
provider: context.provider,
|
|
210
|
+
tokenAddress,
|
|
211
|
+
sellAmountWei,
|
|
212
|
+
sellProceedsWei: estimatedBNBOut,
|
|
213
|
+
quoteTokenIn: useNativeToken ? WBNB_ADDRESS : quoteToken,
|
|
214
|
+
version,
|
|
215
|
+
fee,
|
|
216
|
+
v2RouterAddress: config.v2RouterAddress,
|
|
217
|
+
});
|
|
207
218
|
let profitAmount;
|
|
208
219
|
if (useNativeToken) {
|
|
209
|
-
profitAmount = calculateProfitAmount(
|
|
210
|
-
// 利润计算完成
|
|
220
|
+
profitAmount = calculateProfitAmount(profitNotional, config.userType);
|
|
211
221
|
}
|
|
212
222
|
else {
|
|
213
|
-
const
|
|
214
|
-
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
215
|
-
const estimatedBNBValue = await getERC20ToNativeQuote(context.provider, quoteToken, estimatedBNBOut, version, fee);
|
|
223
|
+
const estimatedBNBValue = await getERC20ToNativeQuote(context.provider, quoteToken, profitNotional, version, fee);
|
|
216
224
|
profitAmount = calculateProfitAmount(estimatedBNBValue, config.userType);
|
|
217
|
-
// ERC20→BNB 报价完成
|
|
218
225
|
}
|
|
219
226
|
// 计算利润 nonce
|
|
220
227
|
const profitNonce = profitAmount > 0n
|
|
@@ -7,7 +7,7 @@ import { ethers, Contract, Wallet } from 'ethers';
|
|
|
7
7
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
8
8
|
import { NonceManager, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
9
9
|
import { ERC20_ABI } from '../../../abis/common.js';
|
|
10
|
-
import { BRIBE_GAS_LIMIT, FLAT_FEE, NATIVE_TRANSFER_GAS_LIMIT, PANCAKE_V2_ROUTER_ABI, PANCAKE_V2_ROUTER_ADDRESS, PANCAKE_V3_ROUTER_ABI, PANCAKE_V3_ROUTER_ADDRESS, ZERO_ADDRESS, buildBNBHopChainForERC20, buildERC20HopChain, buildNativeHopChain, calculateProfitAmount, createPancakeContext, generateDisperseHopPaths, getERC20ToNativeQuote, getGasPrice, quoteSellOutput, } from './bundle-swap-helpers.js';
|
|
10
|
+
import { BRIBE_GAS_LIMIT, FLAT_FEE, NATIVE_TRANSFER_GAS_LIMIT, PANCAKE_V2_ROUTER_ABI, PANCAKE_V2_ROUTER_ADDRESS, PANCAKE_V3_ROUTER_ABI, PANCAKE_V3_ROUTER_ADDRESS, WBNB_ADDRESS, ZERO_ADDRESS, buildBNBHopChainForERC20, buildERC20HopChain, buildNativeHopChain, calculateProfitAmount, createPancakeContext, generateDisperseHopPaths, getERC20ToNativeQuote, getGasPrice, grossUpPancakeSellProceedsToBuySide, quoteSellOutput, } from './bundle-swap-helpers.js';
|
|
11
11
|
/**
|
|
12
12
|
* PancakeSwap 快捷批量换手(资金自动流转)
|
|
13
13
|
*
|
|
@@ -120,16 +120,24 @@ export async function pancakeQuickBatchSwapMerkle(params) {
|
|
|
120
120
|
v2RouterAddress: config.v2RouterAddress,
|
|
121
121
|
});
|
|
122
122
|
const estimatedOutput = quoteResult.estimatedBNBOut;
|
|
123
|
-
|
|
123
|
+
const version = routeParams.routeType === 'v2' ? 'v2' : 'v3';
|
|
124
|
+
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
125
|
+
const profitNotional = await grossUpPancakeSellProceedsToBuySide({
|
|
126
|
+
provider: context.provider,
|
|
127
|
+
tokenAddress,
|
|
128
|
+
sellAmountWei,
|
|
129
|
+
sellProceedsWei: estimatedOutput,
|
|
130
|
+
quoteTokenIn: useNativeToken ? WBNB_ADDRESS : quoteToken,
|
|
131
|
+
version,
|
|
132
|
+
fee,
|
|
133
|
+
v2RouterAddress: config.v2RouterAddress,
|
|
134
|
+
});
|
|
124
135
|
let profitAmount;
|
|
125
136
|
if (useNativeToken) {
|
|
126
|
-
profitAmount = calculateProfitAmount(
|
|
137
|
+
profitAmount = calculateProfitAmount(profitNotional, config.userType);
|
|
127
138
|
}
|
|
128
139
|
else {
|
|
129
|
-
|
|
130
|
-
const version = routeParams.routeType === 'v2' ? 'v2' : 'v3';
|
|
131
|
-
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
132
|
-
const estimatedBNBValue = await getERC20ToNativeQuote(context.provider, quoteToken, estimatedOutput, version, fee);
|
|
140
|
+
const estimatedBNBValue = await getERC20ToNativeQuote(context.provider, quoteToken, profitNotional, version, fee);
|
|
133
141
|
profitAmount = calculateProfitAmount(estimatedBNBValue, config.userType);
|
|
134
142
|
}
|
|
135
143
|
const distributableAmount = estimatedOutput - (useNativeToken ? profitAmount : 0n);
|
|
@@ -6,7 +6,7 @@ import { getGasLimit } from '../../../core/gas/bundle-gas.js';
|
|
|
6
6
|
import { ethers, Wallet } from 'ethers';
|
|
7
7
|
import { calculateSellAmount } from '../../../utils/swap-helpers.js';
|
|
8
8
|
import { NonceManager, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
9
|
-
import { BRIBE_GAS_LIMIT, ZERO_ADDRESS, buildNoncePlanFromNonces, buildSwapTransactions, calculateBuyerBudget, calculateProfitAmount, createPancakeContext, getERC20ToNativeQuote, getGasPrice, planNonces, quoteSellOutput, validateFinalBalances, } from './bundle-swap-helpers.js';
|
|
9
|
+
import { BRIBE_GAS_LIMIT, ZERO_ADDRESS, buildNoncePlanFromNonces, buildSwapTransactions, WBNB_ADDRESS, calculateBuyerBudget, calculateProfitAmount, createPancakeContext, getERC20ToNativeQuote, getGasPrice, grossUpPancakeSellProceedsToBuySide, planNonces, quoteSellOutput, validateFinalBalances, } from './bundle-swap-helpers.js';
|
|
10
10
|
export async function pancakeBundleSwapMerkle(params) {
|
|
11
11
|
const { sellerPrivateKey, sellAmount, sellPercentage, buyerPrivateKey, tokenAddress, routeParams, config, quoteToken, quoteTokenDecimals = 18, startNonces, // ✅ 可选:前端预获取的 nonces
|
|
12
12
|
} = params;
|
|
@@ -51,23 +51,25 @@ export async function pancakeBundleSwapMerkle(params) {
|
|
|
51
51
|
useNativeToken,
|
|
52
52
|
v2RouterAddress: config.v2RouterAddress,
|
|
53
53
|
});
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
const version = routeParams.routeType === 'v2' ? 'v2' : 'v3';
|
|
55
|
+
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
56
|
+
const profitNotional = await grossUpPancakeSellProceedsToBuySide({
|
|
57
|
+
provider: context.provider,
|
|
58
|
+
tokenAddress,
|
|
59
|
+
sellAmountWei,
|
|
60
|
+
sellProceedsWei: quoteResult.estimatedBNBOut,
|
|
61
|
+
quoteTokenIn: useNativeToken ? WBNB_ADDRESS : quoteToken,
|
|
62
|
+
version,
|
|
63
|
+
fee,
|
|
64
|
+
v2RouterAddress: config.v2RouterAddress,
|
|
65
|
+
});
|
|
57
66
|
let profitAmount;
|
|
58
67
|
if (useNativeToken) {
|
|
59
|
-
|
|
60
|
-
profitAmount = calculateProfitAmount(quoteResult.estimatedBNBOut, config.userType);
|
|
61
|
-
// 利润计算完成
|
|
68
|
+
profitAmount = calculateProfitAmount(profitNotional, config.userType);
|
|
62
69
|
}
|
|
63
70
|
else {
|
|
64
|
-
|
|
65
|
-
const version = routeParams.routeType === 'v2' ? 'v2' : 'v3';
|
|
66
|
-
const fee = routeParams.routeType === 'v3-single' ? routeParams.v3Fee : undefined;
|
|
67
|
-
const estimatedBNBValue = await getERC20ToNativeQuote(context.provider, quoteToken, quoteResult.estimatedBNBOut, // 这实际上是 ERC20 数量
|
|
68
|
-
version, fee);
|
|
71
|
+
const estimatedBNBValue = await getERC20ToNativeQuote(context.provider, quoteToken, profitNotional, version, fee);
|
|
69
72
|
profitAmount = calculateProfitAmount(estimatedBNBValue, config.userType);
|
|
70
|
-
// ERC20→BNB 报价完成
|
|
71
73
|
}
|
|
72
74
|
// ✅ 获取贿赂金额
|
|
73
75
|
const bribeAmount = config.bribeAmount && config.bribeAmount > 0 ? ethers.parseEther(String(config.bribeAmount)) : 0n;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { Wallet, JsonRpcProvider } from 'ethers';
|
|
8
8
|
import { ENI_CHAIN_ID, ENI_RPC_URL, DAOAAS_PORTAL, NATIVE_TRANSFER_GAS_LIMIT } from '../../constants.js';
|
|
9
9
|
import { encodeBuyCall, encodeSellCall, applySlippage, DaoaasPortalQuery } from './portal.js';
|
|
10
|
-
import { getProfitRecipient, getProfitRateBps, calculateProfitAmount } from '../../../../core/constants/profit.js';
|
|
10
|
+
import { getProfitRecipient, getProfitRateBps, calculateProfitAmount, calculateBundleSwapRoundTripProfit, } from '../../../../core/constants/profit.js';
|
|
11
11
|
import { directBuy, directSell, directBatchBuy, directBatchSell } from './portal-direct-tx.js';
|
|
12
12
|
import { buildProfitTransfer } from './portal-direct-profit.js';
|
|
13
13
|
const NORMAL_PROFIT_BPS = getProfitRateBps('normal');
|
|
@@ -301,7 +301,7 @@ export async function directQuickSwapForSubmit(params) {
|
|
|
301
301
|
const hopGasFee = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
|
|
302
302
|
const totalFlow = params.buyAmounts.reduce((sum, a) => sum + a, 0n);
|
|
303
303
|
const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
|
|
304
|
-
const profitAmount =
|
|
304
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalFlow, totalFlow) + profitTxGasCost;
|
|
305
305
|
const profitGasPerBuyer = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
|
|
306
306
|
for (let i = 0; i < params.buyerKeys.length; i++) {
|
|
307
307
|
const buyerAddress = new Wallet(params.buyerKeys[i]).address;
|
|
@@ -366,10 +366,10 @@ export async function directQuickSwapForSubmit(params) {
|
|
|
366
366
|
gasPrice: maxFeePerGas,
|
|
367
367
|
});
|
|
368
368
|
const allTxs = [...sellResult.transactions, ...distributeTxs, ...buyResult.transactions];
|
|
369
|
-
// 4)
|
|
369
|
+
// 4) 利润:买合计万三 + 卖合计万三(金额对齐时万六),与钱包数无关
|
|
370
370
|
const totalFlow = params.buyAmounts.reduce((sum, amount) => sum + amount, 0n);
|
|
371
371
|
const profitTxGasCost = NATIVE_TRANSFER_GAS_LIMIT * maxFeePerGas;
|
|
372
|
-
const profitAmount =
|
|
372
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalFlow, totalFlow) + profitTxGasCost;
|
|
373
373
|
const payerIndex = pickMaxAmountIndex(params.buyAmounts);
|
|
374
374
|
const payerKey = params.buyerKeys[payerIndex] || primarySellerKey;
|
|
375
375
|
const payerAddress = new Wallet(payerKey).address.toLowerCase();
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* 只生成签名,由调用方决定如何提交
|
|
8
8
|
*/
|
|
9
9
|
import { ethers } from 'ethers';
|
|
10
|
-
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync,
|
|
10
|
+
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync, getProfitRecipient, } from './utils.js';
|
|
11
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
11
12
|
import { UNIFIED_DELEGATE_ADDRESS, UNIFIED_DELEGATE_ABI, FLAP_PORTAL_ABI, ERC20_ABI, V3_FEE_TIERS, } from './constants.js';
|
|
12
13
|
import { getDefaultRouter, truncateDecimals, buildBuyCallInternal, buildSellCallWithAmountInternal, } from './bundle-swap-helpers.js';
|
|
13
14
|
/**
|
|
@@ -74,9 +75,8 @@ export async function bundleMultiSwap(params) {
|
|
|
74
75
|
// 计算买入金额
|
|
75
76
|
const totalBuyAmountWei = ethers.parseEther(truncateDecimals(totalBuyAmount));
|
|
76
77
|
const buyAmountPerWallet = totalBuyAmountWei / BigInt(buyerWallets.length);
|
|
77
|
-
//
|
|
78
|
-
const
|
|
79
|
-
const profitAmount = calculateProfitAmountByTxCount(totalBuyAmountWei, totalTxCount, userType);
|
|
78
|
+
// 买合计万三 + 卖合计万三(金额对齐时万六),与钱包数无关
|
|
79
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalBuyAmountWei, totalBuyAmountWei);
|
|
80
80
|
const profitRecipient = getProfitRecipient(config);
|
|
81
81
|
// ========================================
|
|
82
82
|
// 并行获取数据
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
import type { EIP7702Config } from './types.js';
|
|
2
2
|
export type UserType = 'v0' | 'v1' | 'default';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* - v0: 8 bps
|
|
6
|
-
* - v1: 10 bps
|
|
7
|
-
*
|
|
4
|
+
* 根据用户类型获取利润率(单边:发币/买卖/捆绑购买)
|
|
5
|
+
* - v0 / default: 8 bps
|
|
6
|
+
* - v1: 10 bps
|
|
7
|
+
* 刷量/换手不要走这里,用 calculateBundleSwapRoundTripProfit
|
|
8
8
|
*/
|
|
9
|
-
export declare function getProfitRateBps(
|
|
9
|
+
export declare function getProfitRateBps(userType?: UserType): number;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* 双边/换手单腿(仅兼容旧调用)。新换手路径用 round-trip 万六。
|
|
12
12
|
*/
|
|
13
13
|
export declare function getProfitRateBpsDouble(_userType?: UserType): number;
|
|
14
14
|
/**
|
|
15
15
|
* 计算利润金额(旧版兼容)
|
|
16
16
|
*/
|
|
17
17
|
export declare function calculateProfitAmount(totalFlowWei: bigint, isSwapMode?: boolean): bigint;
|
|
18
|
-
/**
|
|
19
|
-
* 计算利润金额(基于用户类型)
|
|
20
|
-
* @param totalFlowWei 总资金流水
|
|
21
|
-
* @param userType 用户类型
|
|
22
|
-
* @param isDoubleMode 是否双边模式(换手模式)
|
|
23
|
-
*/
|
|
24
18
|
export declare function calculateProfitAmountByUserType(totalFlowWei: bigint, userType?: UserType, isDoubleMode?: boolean): bigint;
|
|
25
19
|
/**
|
|
26
20
|
* 根据交易数量计算利润金额
|