four-flap-meme-sdk 4.0.7 → 4.0.9
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/abis/flap/portal.js +2 -0
- package/dist/bundle/four-meme/swap/batch.js +4 -3
- package/dist/bundle/four-meme/swap/bundle.js +5 -3
- package/dist/bundle/four-meme/swap/quick-batch.js +3 -3
- package/dist/bundle/four-meme/swap-buy-first/helpers.d.ts +1 -1
- package/dist/bundle/four-meme/swap-buy-first/helpers.js +2 -5
- 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 +1 -1
- package/dist/bundle/four-meme/swap-sign-helpers.js +2 -6
- package/dist/chains/bsc/pancake/bundle-buy-first-multi-wallet.js +10 -14
- package/dist/chains/bsc/pancake/bundle-buy-first-plan.d.ts +1 -1
- package/dist/chains/bsc/pancake/bundle-buy-first-plan.js +2 -5
- package/dist/chains/bsc/pancake/bundle-buy-first.js +10 -15
- package/dist/chains/bsc/pancake/quote.d.ts +2 -2
- package/dist/chains/bsc/pancake/quote.js +5 -12
- package/dist/chains/bsc/platforms/iro/token.d.ts +1 -1
- package/dist/chains/bsc/platforms/iro/token.js +3 -5
- 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 +13 -22
- 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 +2 -2
- package/dist/chains/xlayer/eoa/quote.js +5 -10
- package/dist/core/constants/index.d.ts +2 -2
- package/dist/core/constants/index.js +2 -2
- package/dist/core/constants/profit.d.ts +7 -2
- package/dist/core/constants/profit.js +16 -6
- 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 +42 -1
- package/dist/domains/flap/index.d.ts +1 -1
- package/dist/domains/flap/module.d.ts +1 -1
- package/dist/domains/flap/portal-bundle-merkle/core-helpers.js +3 -35
- package/dist/domains/flap/portal-bundle-merkle/core.js +3 -3
- package/dist/domains/flap/portal-bundle-merkle/swap-batch.js +9 -6
- package/dist/domains/flap/portal-bundle-merkle/swap-buy-first-multi-wallet.js +10 -12
- package/dist/domains/flap/portal-bundle-merkle/swap-buy-first-plan.d.ts +1 -1
- package/dist/domains/flap/portal-bundle-merkle/swap-buy-first-plan.js +2 -5
- 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 +10 -14
- package/dist/domains/flap/portal-bundle-merkle/swap-helpers.js +3 -23
- package/dist/domains/flap/portal-bundle-merkle/swap-planning.d.ts +1 -1
- package/dist/domains/flap/portal-bundle-merkle/swap-planning.js +3 -14
- package/dist/domains/flap/portal-bundle-merkle/swap-quick-batch.js +4 -4
- package/dist/domains/flap/portal-bundle-merkle/swap-single.js +9 -8
- package/dist/domains/flap/portal.d.ts +1 -1
- package/dist/domains/flap/reader.d.ts +8 -1
- package/dist/domains/flap/reader.js +48 -1
- package/dist/domains/flap/types.d.ts +14 -0
- package/dist/domains/holders/holders-maker.js +3 -7
- package/dist/domains/lp-inspect/inspect.js +33 -9
- package/dist/exports/root-foundations.d.ts +2 -2
- 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
package/dist/abis/flap/portal.js
CHANGED
|
@@ -10,6 +10,8 @@ export const PORTAL_ABI = [
|
|
|
10
10
|
'function getTokenV4(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,address,bool,bytes32))',
|
|
11
11
|
'function getTokenV5(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32))',
|
|
12
12
|
'function getTokenV7(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32,uint256,address,uint256,uint8))',
|
|
13
|
+
'function getTokenV8(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32,uint256,uint256,address,uint256,uint8,uint8))',
|
|
14
|
+
'function getTokenV8Safe(address token) external view returns ((uint8,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256,address,bool,bytes32,uint256,uint256,address,uint256,uint8,uint8))',
|
|
13
15
|
// 报价方法
|
|
14
16
|
'function previewBuy(address token, uint256 ethAmount) external view returns (uint256)',
|
|
15
17
|
'function previewSell(address token, uint256 tokenAmount) external view returns (uint256)',
|
|
@@ -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, 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 内盘批量换手(一卖多买)
|
|
@@ -58,8 +59,8 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
58
59
|
// 检查是否需要授权
|
|
59
60
|
const needApproval = needsTmTokenApproval(currentAllowance, decimals);
|
|
60
61
|
// 利润配置
|
|
61
|
-
const
|
|
62
|
-
const profitAmount = totalBuyerFunds > 0n ? (totalBuyerFunds
|
|
62
|
+
const buySum = buyAmountsWei.reduce((a, b) => a + b, 0n);
|
|
63
|
+
const profitAmount = totalBuyerFunds > 0n ? calculateBundleSwapRoundTripProfit(buySum, totalBuyerFunds) : 0n;
|
|
63
64
|
// ✅ 获取贿赂金额
|
|
64
65
|
const bribeAmount = getBribeAmount(config);
|
|
65
66
|
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, 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内盘捆绑换手
|
|
@@ -41,8 +42,9 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
41
42
|
const needApproval = needsTmTokenApproval(currentAllowance, decimals);
|
|
42
43
|
// 利润配置
|
|
43
44
|
const extractProfit = true;
|
|
44
|
-
const
|
|
45
|
-
|
|
45
|
+
const profitAmount = extractProfit && sellerWillGetBNB > 0n
|
|
46
|
+
? calculateBundleSwapRoundTripProfit(buyerFunds, sellerWillGetBNB)
|
|
47
|
+
: 0n;
|
|
46
48
|
// ✅ 获取贿赂金额
|
|
47
49
|
const bribeAmount = getBribeAmount(config);
|
|
48
50
|
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, 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 内盘快捷批量换手(资金利用率模式)
|
|
@@ -51,8 +52,7 @@ export async function fourQuickBatchSwapMerkle(params) {
|
|
|
51
52
|
const { amount: sellAmountWei, decimals } = sellAmountResult;
|
|
52
53
|
const estimatedBNBOut = await quoteFourSwapSellFunds(provider, tokenAddress, sellAmountWei);
|
|
53
54
|
// ✅ 计算利润(根据 userType 动态调整)
|
|
54
|
-
const
|
|
55
|
-
const profitAmount = estimatedBNBOut > 0n ? (estimatedBNBOut * BigInt(profitRateBps)) / 10000n : 0n;
|
|
55
|
+
const profitAmount = estimatedBNBOut > 0n ? calculateBundleSwapRoundTripProfit(estimatedBNBOut, estimatedBNBOut) : 0n;
|
|
56
56
|
const distributableAmount = estimatedBNBOut - profitAmount;
|
|
57
57
|
// ✅ 计算每个买方分到的金额
|
|
58
58
|
let transferAmountsWei;
|
|
@@ -13,7 +13,7 @@ export declare const MAX_SWAP_TX_COUNT: number;
|
|
|
13
13
|
/**
|
|
14
14
|
* 根据 userType 获取每笔交易的利润率
|
|
15
15
|
*/
|
|
16
|
-
export declare function getProfitRatePerTxBps(
|
|
16
|
+
export declare function getProfitRatePerTxBps(_userType?: UserType): number;
|
|
17
17
|
/**
|
|
18
18
|
* 验证买卖笔数
|
|
19
19
|
*/
|
|
@@ -15,11 +15,8 @@ export const MAX_SWAP_TX_COUNT = MAX_BUNDLE_SIGNATURES - BRIBE_TX_COUNT - PROFIT
|
|
|
15
15
|
/**
|
|
16
16
|
* 根据 userType 获取每笔交易的利润率
|
|
17
17
|
*/
|
|
18
|
-
export function getProfitRatePerTxBps(
|
|
19
|
-
|
|
20
|
-
return getSharedProfitRateBps('v1Double');
|
|
21
|
-
}
|
|
22
|
-
return getSharedProfitRateBps('v0Double');
|
|
18
|
+
export function getProfitRatePerTxBps(_userType) {
|
|
19
|
+
return getSharedProfitRateBps('bundleSwap');
|
|
23
20
|
}
|
|
24
21
|
/**
|
|
25
22
|
* 验证买卖笔数
|
|
@@ -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) {
|
|
@@ -2,7 +2,7 @@ import { Wallet, type JsonRpcProvider } from 'ethers';
|
|
|
2
2
|
import { type CommonBundleConfig } from '../../utils/bundle-helpers.js';
|
|
3
3
|
import type { FourSwapSignConfig, SellerNoncePlan, UserType } from './types/index.js';
|
|
4
4
|
export type { SellerNoncePlan } from './types/index.js';
|
|
5
|
-
export declare function getFourSwapProfitRateBps(
|
|
5
|
+
export declare function getFourSwapProfitRateBps(_userType?: UserType): number;
|
|
6
6
|
export declare function needsTmTokenApproval(currentAllowance: bigint, decimals: number): boolean;
|
|
7
7
|
export declare function countSellerNonceSlots(needBribeTx: boolean, needApproval: boolean, includeProfit: boolean): number;
|
|
8
8
|
export declare function planSellerNonces(sellerNonces: number[], needBribeTx: boolean, needApproval: boolean, extractProfit: boolean): SellerNoncePlan;
|
|
@@ -7,12 +7,8 @@ import { createSignProvider } from '../../core/sign-context-helpers.js';
|
|
|
7
7
|
import { HELPER3_ABI, TM_ADDRESS } from './swap-internal.js';
|
|
8
8
|
const APPROVE_INTERFACE = new ethers.Interface(['function approve(address,uint256) returns (bool)']);
|
|
9
9
|
const ERC20_ALLOWANCE_ABI = ['function allowance(address,address) view returns (uint256)'];
|
|
10
|
-
export function getFourSwapProfitRateBps(
|
|
11
|
-
|
|
12
|
-
return getSharedProfitRateBps('v0Single');
|
|
13
|
-
if (userType === 'v1')
|
|
14
|
-
return getSharedProfitRateBps('v1Single');
|
|
15
|
-
return getSharedProfitRateBps('v0Single');
|
|
10
|
+
export function getFourSwapProfitRateBps(_userType) {
|
|
11
|
+
return getSharedProfitRateBps('bundleSwap');
|
|
16
12
|
}
|
|
17
13
|
export function needsTmTokenApproval(currentAllowance, decimals) {
|
|
18
14
|
const threshold = ethers.parseUnits('1000000000', decimals);
|
|
@@ -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 = [];
|
|
@@ -2,7 +2,7 @@ import type { MultiNoncePlan, PlanMultiNonceParams, UserType } from './bundle-bu
|
|
|
2
2
|
/**
|
|
3
3
|
* 根据 userType 获取每笔交易的利润率
|
|
4
4
|
*/
|
|
5
|
-
export declare function getProfitRatePerTxBps(
|
|
5
|
+
export declare function getProfitRatePerTxBps(_userType?: UserType): number;
|
|
6
6
|
/**
|
|
7
7
|
* 验证买卖笔数
|
|
8
8
|
*/
|
|
@@ -6,11 +6,8 @@ import { BRIBE_TX_COUNT, MAX_BUNDLE_SIGNATURES, MAX_SWAP_TX_COUNT, PROFIT_TX_COU
|
|
|
6
6
|
/**
|
|
7
7
|
* 根据 userType 获取每笔交易的利润率
|
|
8
8
|
*/
|
|
9
|
-
export function getProfitRatePerTxBps(
|
|
10
|
-
|
|
11
|
-
return getProfitRateBps('v1Double');
|
|
12
|
-
}
|
|
13
|
-
return getProfitRateBps('v0Double'); // v0 或默认
|
|
9
|
+
export function getProfitRatePerTxBps(_userType) {
|
|
10
|
+
return getProfitRateBps('bundleSwap');
|
|
14
11
|
}
|
|
15
12
|
/**
|
|
16
13
|
* 验证买卖笔数
|
|
@@ -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;
|
|
@@ -4,8 +4,8 @@ export declare function quoteSellOutput({ routeParams, sellAmountWei, provider,
|
|
|
4
4
|
/**
|
|
5
5
|
* 根据 userType 计算利润率
|
|
6
6
|
*/
|
|
7
|
-
export declare function getProfitRateBps(
|
|
8
|
-
export declare function calculateProfitAmount(estimatedBNBOut: bigint,
|
|
7
|
+
export declare function getProfitRateBps(_userType?: UserType): number;
|
|
8
|
+
export declare function calculateProfitAmount(estimatedBNBOut: bigint, _userType?: UserType): bigint;
|
|
9
9
|
/**
|
|
10
10
|
* ✅ 获取 ERC20 代币 → 原生代币(BNB)的报价
|
|
11
11
|
* 用于将 ERC20 利润转换为 BNB
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ADDRESSES } 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, }) {
|
|
@@ -41,21 +41,14 @@ export async function quoteSellOutput({ routeParams, sellAmountWei, provider, v2
|
|
|
41
41
|
/**
|
|
42
42
|
* 根据 userType 计算利润率
|
|
43
43
|
*/
|
|
44
|
-
export function getProfitRateBps(
|
|
45
|
-
|
|
46
|
-
return 4; // 0.06%
|
|
47
|
-
}
|
|
48
|
-
else if (userType === 'v1') {
|
|
49
|
-
return 5; // 0.05%
|
|
50
|
-
}
|
|
51
|
-
return 4; // 默认 0.06%
|
|
44
|
+
export function getProfitRateBps(_userType) {
|
|
45
|
+
return getSharedProfitRateBps('bundleSwap');
|
|
52
46
|
}
|
|
53
|
-
export function calculateProfitAmount(estimatedBNBOut,
|
|
47
|
+
export function calculateProfitAmount(estimatedBNBOut, _userType) {
|
|
54
48
|
if (estimatedBNBOut <= 0n) {
|
|
55
49
|
return 0n;
|
|
56
50
|
}
|
|
57
|
-
|
|
58
|
-
return (estimatedBNBOut * BigInt(rateBps)) / 10000n;
|
|
51
|
+
return calculateBundleSwapRoundTripProfit(estimatedBNBOut, estimatedBNBOut);
|
|
59
52
|
}
|
|
60
53
|
/**
|
|
61
54
|
* ✅ 获取 ERC20 代币 → 原生代币(BNB)的报价
|
|
@@ -112,7 +112,7 @@ export interface IroBatchSubscribeForSubmitResult {
|
|
|
112
112
|
*
|
|
113
113
|
* 和 Flap 发币一致的逻辑:
|
|
114
114
|
* 1. 签名所有 subscribe 交易
|
|
115
|
-
* 2. 从买入金额最大的钱包抽取 BNB
|
|
115
|
+
* 2. 从买入金额最大的钱包抽取 BNB 利润(按地址固定费率)
|
|
116
116
|
* 3. 利润通过 2 跳中转转给利润地址 (BSC: payer → hop1 → hop2 → 利润地址)
|
|
117
117
|
* 4. 返回 [...approvalTxs, ...subscribeTxs, ...profitTxs]
|
|
118
118
|
*
|
|
@@ -10,7 +10,7 @@ import { Contract, Interface, Wallet, JsonRpcProvider } from 'ethers';
|
|
|
10
10
|
import { BSC_CHAIN_ID, BSC_RPC_URL } from '../../constants.js';
|
|
11
11
|
import { IRO_TOKEN_ABI, SUBSCRIBE_GAS_LIMIT } from './constants.js';
|
|
12
12
|
import { buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../../../utils/bundle-helpers.js';
|
|
13
|
-
import { getProfitRecipient } from '../../../../core/constants/profit.js';
|
|
13
|
+
import { getProfitRecipient, getTransferFeePerAddress } from '../../../../core/constants/profit.js';
|
|
14
14
|
const tokenIface = new Interface(IRO_TOKEN_ABI);
|
|
15
15
|
// ============================================================================
|
|
16
16
|
// 查询
|
|
@@ -213,7 +213,7 @@ export async function batchSubscribe(params) {
|
|
|
213
213
|
*
|
|
214
214
|
* 和 Flap 发币一致的逻辑:
|
|
215
215
|
* 1. 签名所有 subscribe 交易
|
|
216
|
-
* 2. 从买入金额最大的钱包抽取 BNB
|
|
216
|
+
* 2. 从买入金额最大的钱包抽取 BNB 利润(按地址固定费率)
|
|
217
217
|
* 3. 利润通过 2 跳中转转给利润地址 (BSC: payer → hop1 → hop2 → 利润地址)
|
|
218
218
|
* 4. 返回 [...approvalTxs, ...subscribeTxs, ...profitTxs]
|
|
219
219
|
*
|
|
@@ -248,9 +248,7 @@ export async function batchSubscribeForSubmit(params) {
|
|
|
248
248
|
wallets.push(new Wallet(sub.privateKey, provider));
|
|
249
249
|
nonces.push(result.nonce);
|
|
250
250
|
}
|
|
251
|
-
|
|
252
|
-
// 使用固定费率:每个地址 0.001 BNB (和 TRANSFER_FEE_PER_ADDRESS 一致)
|
|
253
|
-
const profitPerAddress = 1000000000000000n; // 0.001 BNB
|
|
251
|
+
const profitPerAddress = getTransferFeePerAddress(chainId);
|
|
254
252
|
const totalProfit = profitPerAddress * BigInt(subscribers.length);
|
|
255
253
|
// 从买入金额最大的钱包支付利润
|
|
256
254
|
let maxIndex = 0;
|
|
@@ -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
9
|
export declare function getProfitRateBps(userType?: UserType): number;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* 双边/换手单腿(仅兼容旧调用)。新换手路径用 round-trip 万六。
|
|
12
12
|
*/
|
|
13
|
-
export declare function getProfitRateBpsDouble(
|
|
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
|
* 根据交易数量计算利润金额
|
|
@@ -1,45 +1,36 @@
|
|
|
1
|
-
import { getProfitRateBps as getSharedProfitRateBps, getProfitRecipient as pickRandomProfitRecipient, } from '../../../core/constants/index.js';
|
|
1
|
+
import { getProfitRateBps as getSharedProfitRateBps, getProfitRecipient as pickRandomProfitRecipient, calculateBundleSwapRoundTripProfit, } from '../../../core/constants/index.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* - v0: 8 bps
|
|
5
|
-
* - v1: 10 bps
|
|
6
|
-
*
|
|
3
|
+
* 根据用户类型获取利润率(单边:发币/买卖/捆绑购买)
|
|
4
|
+
* - v0 / default: 8 bps
|
|
5
|
+
* - v1: 10 bps
|
|
6
|
+
* 刷量/换手不要走这里,用 calculateBundleSwapRoundTripProfit
|
|
7
7
|
*/
|
|
8
8
|
export function getProfitRateBps(userType) {
|
|
9
|
-
if (userType === 'v0')
|
|
10
|
-
return getSharedProfitRateBps('v0Single');
|
|
11
9
|
if (userType === 'v1')
|
|
12
10
|
return getSharedProfitRateBps('v1Single');
|
|
13
11
|
return getSharedProfitRateBps('v0Single');
|
|
14
12
|
}
|
|
15
13
|
/**
|
|
16
|
-
*
|
|
14
|
+
* 双边/换手单腿(仅兼容旧调用)。新换手路径用 round-trip 万六。
|
|
17
15
|
*/
|
|
18
|
-
export function getProfitRateBpsDouble(
|
|
19
|
-
|
|
20
|
-
return getSharedProfitRateBps('v0Double');
|
|
21
|
-
if (userType === 'v1')
|
|
22
|
-
return getSharedProfitRateBps('v1Double');
|
|
23
|
-
return getSharedProfitRateBps('v0Double');
|
|
16
|
+
export function getProfitRateBpsDouble(_userType) {
|
|
17
|
+
return getSharedProfitRateBps('bundleSwap');
|
|
24
18
|
}
|
|
25
19
|
/**
|
|
26
20
|
* 计算利润金额(旧版兼容)
|
|
27
21
|
*/
|
|
28
22
|
export function calculateProfitAmount(totalFlowWei, isSwapMode = false) {
|
|
29
23
|
const rateBps = getSharedProfitRateBps(isSwapMode ? 'bundleSwap' : 'normal');
|
|
24
|
+
if (isSwapMode)
|
|
25
|
+
return calculateBundleSwapRoundTripProfit(totalFlowWei, totalFlowWei);
|
|
30
26
|
return (totalFlowWei * BigInt(rateBps)) / 10000n;
|
|
31
27
|
}
|
|
32
|
-
/**
|
|
33
|
-
* 计算利润金额(基于用户类型)
|
|
34
|
-
* @param totalFlowWei 总资金流水
|
|
35
|
-
* @param userType 用户类型
|
|
36
|
-
* @param isDoubleMode 是否双边模式(换手模式)
|
|
37
|
-
*/
|
|
38
28
|
export function calculateProfitAmountByUserType(totalFlowWei, userType, isDoubleMode = false) {
|
|
39
29
|
if (totalFlowWei <= 0n)
|
|
40
30
|
return 0n;
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
if (isDoubleMode)
|
|
32
|
+
return calculateBundleSwapRoundTripProfit(totalFlowWei, totalFlowWei);
|
|
33
|
+
return (totalFlowWei * BigInt(getProfitRateBps(userType))) / 10000n;
|
|
43
34
|
}
|
|
44
35
|
/**
|
|
45
36
|
* 根据交易数量计算利润金额
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { ethers } from 'ethers';
|
|
8
8
|
import { truncateDecimals } from './volume-helpers.js';
|
|
9
|
-
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync,
|
|
9
|
+
import { getCachedProvider, createWallet, signAuthorizationsWithNonces, batchGetNonces, buildEIP7702TransactionSync, getProfitRecipient, } from './utils.js';
|
|
10
|
+
import { calculateBundleSwapRoundTripProfit } from '../../../core/constants/index.js';
|
|
10
11
|
import { UNIFIED_DELEGATE_ADDRESS, UNIFIED_DELEGATE_ABI, FLAP_PORTAL_ABI, FLAP_PORTAL_ADDRESS, POTATOSWAP_V2_ROUTER, WOKB_ADDRESS, V3_FEE_TIERS, ERC20_ABI, V2_ROUTER_ABI, } from './constants.js';
|
|
11
12
|
import { getDefaultRouter, buildBuyCall, buildSellCall, buildSellCallWithAmount } from './volume-internal.js';
|
|
12
13
|
/**
|
|
@@ -15,7 +16,7 @@ import { getDefaultRouter, buildBuyCall, buildSellCall, buildSellCallWithAmount
|
|
|
15
16
|
* 核心逻辑:[利润刮取] + [买入Ops...] + [卖出Ops...]
|
|
16
17
|
*/
|
|
17
18
|
export async function bundleVolume(params) {
|
|
18
|
-
const { mainPrivateKey, buyerPrivateKeys, buyAmounts, sellerPrivateKeys, sellAmounts, sellPercent = 100, tokenAddress, tokenDecimals = 18, poolType = 'V3', routerAddress, fee = V3_FEE_TIERS.MEDIUM, userType = 'v0', //
|
|
19
|
+
const { mainPrivateKey, buyerPrivateKeys, buyAmounts, sellerPrivateKeys, sellAmounts, sellPercent = 100, tokenAddress, tokenDecimals = 18, poolType = 'V3', routerAddress, fee = V3_FEE_TIERS.MEDIUM, userType: _userType = 'v0', // 档位已统一为 bundleSwap 两腿万六
|
|
19
20
|
config, } = params;
|
|
20
21
|
// ✅ 验证私钥格式的辅助函数
|
|
21
22
|
const isValidPrivateKey = (pk) => {
|
|
@@ -66,9 +67,8 @@ export async function bundleVolume(params) {
|
|
|
66
67
|
// 计算买入金额(使用验证后的金额数组)
|
|
67
68
|
const buyAmountsWei = validBuyAmounts.map((amt) => ethers.parseEther(truncateDecimals(amt)));
|
|
68
69
|
const totalBuyAmount = buyAmountsWei.reduce((sum, amt) => sum + amt, 0n);
|
|
69
|
-
//
|
|
70
|
-
const
|
|
71
|
-
const profitAmount = calculateProfitAmountByTxCount(totalBuyAmount, totalTxCount, userType);
|
|
70
|
+
// 买合计万三 + 卖合计万三(买卖总额对齐时为万六),与钱包数无关
|
|
71
|
+
const profitAmount = calculateBundleSwapRoundTripProfit(totalBuyAmount, totalBuyAmount);
|
|
72
72
|
const profitRecipient = getProfitRecipient(config);
|
|
73
73
|
// ========================================
|
|
74
74
|
// 并行获取数据
|