four-flap-meme-sdk 1.4.32 → 1.4.34
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.
|
@@ -63,7 +63,7 @@ export async function fourBundleSwapMerkle(params) {
|
|
|
63
63
|
const needApproval = currentAllowance < APPROVAL_THRESHOLD;
|
|
64
64
|
// 利润配置
|
|
65
65
|
const extractProfit = true;
|
|
66
|
-
const profitRateBps = PROFIT_CONFIG.
|
|
66
|
+
const profitRateBps = PROFIT_CONFIG.RATE_BPS_SWAP;
|
|
67
67
|
const profitAmount = extractProfit && sellerWillGetBNB > 0n
|
|
68
68
|
? (sellerWillGetBNB * BigInt(profitRateBps)) / 10000n
|
|
69
69
|
: 0n;
|
|
@@ -282,7 +282,7 @@ export async function fourBatchSwapMerkle(params) {
|
|
|
282
282
|
const APPROVAL_THRESHOLD = ethers.parseUnits('1000000000', decimals);
|
|
283
283
|
const needApproval = currentAllowance < APPROVAL_THRESHOLD;
|
|
284
284
|
// 利润配置
|
|
285
|
-
const profitRateBps = PROFIT_CONFIG.
|
|
285
|
+
const profitRateBps = PROFIT_CONFIG.RATE_BPS_SWAP;
|
|
286
286
|
const profitAmount = totalBuyerFunds > 0n
|
|
287
287
|
? (totalBuyerFunds * BigInt(profitRateBps)) / 10000n
|
|
288
288
|
: 0n;
|
|
@@ -493,8 +493,8 @@ export async function fourQuickBatchSwapMerkle(params) {
|
|
|
493
493
|
const estimatedBNBOut = sellQuote.funds;
|
|
494
494
|
console.log(`[fourQuickBatchSwapMerkle] 卖出数量: ${ethers.formatUnits(sellAmountWei, decimals)}`);
|
|
495
495
|
console.log(`[fourQuickBatchSwapMerkle] 预估卖出所得: ${ethers.formatEther(estimatedBNBOut)} BNB`);
|
|
496
|
-
// ✅
|
|
497
|
-
const profitRateBps = PROFIT_CONFIG.
|
|
496
|
+
// ✅ 计算利润(万分之六)
|
|
497
|
+
const profitRateBps = PROFIT_CONFIG.RATE_BPS_SWAP;
|
|
498
498
|
const profitAmount = estimatedBNBOut > 0n
|
|
499
499
|
? (estimatedBNBOut * BigInt(profitRateBps)) / 10000n
|
|
500
500
|
: 0n;
|
|
@@ -467,7 +467,7 @@ function calculateProfitAmount(quotedNative) {
|
|
|
467
467
|
if (quotedNative <= 0n) {
|
|
468
468
|
return 0n;
|
|
469
469
|
}
|
|
470
|
-
return (quotedNative * BigInt(PROFIT_CONFIG.
|
|
470
|
+
return (quotedNative * BigInt(PROFIT_CONFIG.RATE_BPS_SWAP)) / 10000n;
|
|
471
471
|
}
|
|
472
472
|
function countTruthy(values) {
|
|
473
473
|
return values.filter(Boolean).length;
|
|
@@ -756,7 +756,7 @@ export async function flapQuickBatchSwapMerkle(params) {
|
|
|
756
756
|
console.log(`[flapQuickBatchSwapMerkle] 模式: ${useNativeToken ? '原生代币' : 'ERC20'}`);
|
|
757
757
|
console.log(`[flapQuickBatchSwapMerkle] 卖出数量: ${ethers.formatUnits(sellAmountWei, decimals)}`);
|
|
758
758
|
console.log(`[flapQuickBatchSwapMerkle] 预估卖出所得: ${outputFormatted}`);
|
|
759
|
-
// ✅
|
|
759
|
+
// ✅ 计算利润(万分之六)
|
|
760
760
|
let tokenProfitAmount = calculateProfitAmount(estimatedOutput);
|
|
761
761
|
let nativeProfitAmount = tokenProfitAmount;
|
|
762
762
|
if (!useNativeToken && tokenProfitAmount > 0n) {
|
|
@@ -217,7 +217,7 @@ function calculateProfitAmount(estimatedBNBOut) {
|
|
|
217
217
|
if (estimatedBNBOut <= 0n) {
|
|
218
218
|
return 0n;
|
|
219
219
|
}
|
|
220
|
-
return (estimatedBNBOut * BigInt(PROFIT_CONFIG.
|
|
220
|
+
return (estimatedBNBOut * BigInt(PROFIT_CONFIG.RATE_BPS_SWAP)) / 10000n;
|
|
221
221
|
}
|
|
222
222
|
/**
|
|
223
223
|
* ✅ 获取 ERC20 代币 → 原生代币(BNB)的报价
|
|
@@ -599,7 +599,14 @@ export async function pancakeBatchSwapMerkle(params) {
|
|
|
599
599
|
if (routeParams.routeType === 'v2') {
|
|
600
600
|
const { v2Path } = routeParams;
|
|
601
601
|
const v2RouterSeller = new Contract(PANCAKE_V2_ROUTER_ADDRESS, PANCAKE_V2_ROUTER_ABI, seller);
|
|
602
|
-
|
|
602
|
+
if (useNativeToken) {
|
|
603
|
+
// ✅ 原生代币模式(BNB):Token → WBNB → BNB
|
|
604
|
+
sellUnsigned = await v2RouterSeller.swapExactTokensForETHSupportingFeeOnTransferTokens.populateTransaction(sellAmountWei, 0n, v2Path, seller.address, deadline);
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
// ✅ ERC20 模式(USDT):Token → USDT
|
|
608
|
+
sellUnsigned = await v2RouterSeller.swapExactTokensForTokensSupportingFeeOnTransferTokens.populateTransaction(sellAmountWei, 0n, v2Path, seller.address, deadline);
|
|
609
|
+
}
|
|
603
610
|
}
|
|
604
611
|
else if (routeParams.routeType === 'v3-single') {
|
|
605
612
|
const { v3TokenIn, v3TokenOut, v3Fee } = routeParams;
|
|
@@ -608,13 +615,20 @@ export async function pancakeBatchSwapMerkle(params) {
|
|
|
608
615
|
tokenIn: v3TokenIn,
|
|
609
616
|
tokenOut: v3TokenOut,
|
|
610
617
|
fee: v3Fee,
|
|
611
|
-
recipient: PANCAKE_V3_ROUTER_ADDRESS,
|
|
618
|
+
recipient: useNativeToken ? PANCAKE_V3_ROUTER_ADDRESS : seller.address,
|
|
612
619
|
amountIn: sellAmountWei,
|
|
613
620
|
amountOutMinimum: 0n,
|
|
614
621
|
sqrtPriceLimitX96: 0n
|
|
615
622
|
}]);
|
|
616
|
-
|
|
617
|
-
|
|
623
|
+
if (useNativeToken) {
|
|
624
|
+
// 原生代币:需要 unwrap WBNB
|
|
625
|
+
const sellUnwrapData = v3RouterIface.encodeFunctionData('unwrapWETH9', [0n, seller.address]);
|
|
626
|
+
sellUnsigned = await v3RouterSeller.multicall.populateTransaction(deadline, [sellSwapData, sellUnwrapData]);
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
// ERC20:直接接收代币
|
|
630
|
+
sellUnsigned = await v3RouterSeller.multicall.populateTransaction(deadline, [sellSwapData]);
|
|
631
|
+
}
|
|
618
632
|
}
|
|
619
633
|
else {
|
|
620
634
|
throw new Error('V3 多跳路由暂不支持官方合约,请使用 V2 路由或 V3 单跳');
|
|
@@ -622,12 +636,20 @@ export async function pancakeBatchSwapMerkle(params) {
|
|
|
622
636
|
// ✅ 并行构建多个买入交易(使用官方 Router)
|
|
623
637
|
const buyUnsignedList = await Promise.all(buyers.map(async (buyer, i) => {
|
|
624
638
|
const buyAmount = buyAmountsWei[i];
|
|
625
|
-
|
|
639
|
+
// ✅ ERC20 模式:value = 0(通过代币授权支付)
|
|
640
|
+
const buyValue = useNativeToken ? buyAmount + FLAT_FEE : 0n;
|
|
626
641
|
if (routeParams.routeType === 'v2') {
|
|
627
642
|
const { v2Path } = routeParams;
|
|
628
643
|
const reversePath = [...v2Path].reverse();
|
|
629
644
|
const v2RouterBuyer = new Contract(PANCAKE_V2_ROUTER_ADDRESS, PANCAKE_V2_ROUTER_ABI, buyer);
|
|
630
|
-
|
|
645
|
+
if (useNativeToken) {
|
|
646
|
+
// ✅ 原生代币模式(BNB):BNB → WBNB → Token
|
|
647
|
+
return await v2RouterBuyer.swapExactETHForTokensSupportingFeeOnTransferTokens.populateTransaction(0n, reversePath, buyer.address, deadline, { value: buyValue });
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
// ✅ ERC20 模式(USDT):USDT → Token
|
|
651
|
+
return await v2RouterBuyer.swapExactTokensForTokensSupportingFeeOnTransferTokens.populateTransaction(buyAmount, 0n, reversePath, buyer.address, deadline);
|
|
652
|
+
}
|
|
631
653
|
}
|
|
632
654
|
else if (routeParams.routeType === 'v3-single') {
|
|
633
655
|
const { v3TokenIn, v3TokenOut, v3Fee } = routeParams;
|
|
@@ -868,7 +890,7 @@ export async function pancakeQuickBatchSwapMerkle(params) {
|
|
|
868
890
|
? ethers.formatEther(estimatedOutput)
|
|
869
891
|
: ethers.formatUnits(estimatedOutput, quoteTokenDecimals);
|
|
870
892
|
console.log(`[pancakeQuickBatchSwapMerkle] 预估卖出所得: ${outputFormatted} ${useNativeToken ? 'BNB' : 'ERC20'}`);
|
|
871
|
-
// ✅
|
|
893
|
+
// ✅ 计算利润(万分之六)
|
|
872
894
|
let profitAmount;
|
|
873
895
|
if (useNativeToken) {
|
|
874
896
|
profitAmount = calculateProfitAmount(estimatedOutput);
|
|
@@ -954,7 +976,14 @@ export async function pancakeQuickBatchSwapMerkle(params) {
|
|
|
954
976
|
if (routeParams.routeType === 'v2') {
|
|
955
977
|
const { v2Path } = routeParams;
|
|
956
978
|
const v2RouterSeller = new Contract(PANCAKE_V2_ROUTER_ADDRESS, PANCAKE_V2_ROUTER_ABI, seller);
|
|
957
|
-
|
|
979
|
+
if (useNativeToken) {
|
|
980
|
+
// ✅ 原生代币模式(BNB):Token → WBNB → BNB
|
|
981
|
+
sellUnsigned = await v2RouterSeller.swapExactTokensForETHSupportingFeeOnTransferTokens.populateTransaction(sellAmountWei, 0n, v2Path, seller.address, deadline);
|
|
982
|
+
}
|
|
983
|
+
else {
|
|
984
|
+
// ✅ ERC20 模式(USDT):Token → USDT
|
|
985
|
+
sellUnsigned = await v2RouterSeller.swapExactTokensForTokensSupportingFeeOnTransferTokens.populateTransaction(sellAmountWei, 0n, v2Path, seller.address, deadline);
|
|
986
|
+
}
|
|
958
987
|
}
|
|
959
988
|
else if (routeParams.routeType === 'v3-single') {
|
|
960
989
|
const { v3TokenIn, v3TokenOut, v3Fee } = routeParams;
|
|
@@ -963,13 +992,20 @@ export async function pancakeQuickBatchSwapMerkle(params) {
|
|
|
963
992
|
tokenIn: v3TokenIn,
|
|
964
993
|
tokenOut: v3TokenOut,
|
|
965
994
|
fee: v3Fee,
|
|
966
|
-
recipient: PANCAKE_V3_ROUTER_ADDRESS,
|
|
995
|
+
recipient: useNativeToken ? PANCAKE_V3_ROUTER_ADDRESS : seller.address,
|
|
967
996
|
amountIn: sellAmountWei,
|
|
968
997
|
amountOutMinimum: 0n,
|
|
969
998
|
sqrtPriceLimitX96: 0n
|
|
970
999
|
}]);
|
|
971
|
-
|
|
972
|
-
|
|
1000
|
+
if (useNativeToken) {
|
|
1001
|
+
// 原生代币:需要 unwrap WBNB
|
|
1002
|
+
const sellUnwrapData = v3RouterIface2.encodeFunctionData('unwrapWETH9', [0n, seller.address]);
|
|
1003
|
+
sellUnsigned = await v3RouterSeller.multicall.populateTransaction(deadline, [sellSwapData, sellUnwrapData]);
|
|
1004
|
+
}
|
|
1005
|
+
else {
|
|
1006
|
+
// ERC20:直接接收代币
|
|
1007
|
+
sellUnsigned = await v3RouterSeller.multicall.populateTransaction(deadline, [sellSwapData]);
|
|
1008
|
+
}
|
|
973
1009
|
}
|
|
974
1010
|
else {
|
|
975
1011
|
throw new Error('V3 多跳路由暂不支持官方合约,请使用 V2 路由或 V3 单跳');
|
|
@@ -1035,15 +1071,21 @@ export async function pancakeQuickBatchSwapMerkle(params) {
|
|
|
1035
1071
|
: await Promise.all(buyers.map(buyer => nonceManager.getNextNonce(buyer)));
|
|
1036
1072
|
const signedBuys = await Promise.all(buyers.map(async (buyer, i) => {
|
|
1037
1073
|
const buyAmount = transferAmountsWei[i];
|
|
1038
|
-
//
|
|
1039
|
-
|
|
1040
|
-
const buyValue = useNativeToken ? buyAmount + FLAT_FEE : FLAT_FEE;
|
|
1074
|
+
// ✅ ERC20 模式:value = 0(通过代币授权支付)
|
|
1075
|
+
const buyValue = useNativeToken ? buyAmount + FLAT_FEE : 0n;
|
|
1041
1076
|
let buyUnsigned;
|
|
1042
1077
|
if (routeParams.routeType === 'v2') {
|
|
1043
1078
|
const { v2Path } = routeParams;
|
|
1044
1079
|
const reversePath = [...v2Path].reverse();
|
|
1045
1080
|
const v2RouterBuyer = new Contract(PANCAKE_V2_ROUTER_ADDRESS, PANCAKE_V2_ROUTER_ABI, buyer);
|
|
1046
|
-
|
|
1081
|
+
if (useNativeToken) {
|
|
1082
|
+
// ✅ 原生代币模式(BNB):BNB → WBNB → Token
|
|
1083
|
+
buyUnsigned = await v2RouterBuyer.swapExactETHForTokensSupportingFeeOnTransferTokens.populateTransaction(0n, reversePath, buyer.address, deadline, { value: buyValue });
|
|
1084
|
+
}
|
|
1085
|
+
else {
|
|
1086
|
+
// ✅ ERC20 模式(USDT):USDT → Token
|
|
1087
|
+
buyUnsigned = await v2RouterBuyer.swapExactTokensForTokensSupportingFeeOnTransferTokens.populateTransaction(buyAmount, 0n, reversePath, buyer.address, deadline);
|
|
1088
|
+
}
|
|
1047
1089
|
}
|
|
1048
1090
|
else if (routeParams.routeType === 'v3-single') {
|
|
1049
1091
|
const { v3TokenIn, v3TokenOut, v3Fee } = routeParams;
|
|
@@ -17,8 +17,10 @@ export declare const PROFIT_CONFIG: {
|
|
|
17
17
|
readonly RECIPIENT: "0xe8D0334fAf713884133640CAEe4ECdd2106AF103";
|
|
18
18
|
/** 利润比例(基点):30 bps = 0.3% = 千分之三(普通模式) */
|
|
19
19
|
readonly RATE_BPS: 30;
|
|
20
|
-
/** 利润比例(基点):
|
|
21
|
-
readonly RATE_BPS_CAPITAL:
|
|
20
|
+
/** 利润比例(基点):6 bps = 0.06% = 万分之六(资金利用率模式) */
|
|
21
|
+
readonly RATE_BPS_CAPITAL: 6;
|
|
22
|
+
/** 利润比例(基点):6 bps = 0.06% = 万分之六(捆绑换手模式) */
|
|
23
|
+
readonly RATE_BPS_SWAP: 6;
|
|
22
24
|
};
|
|
23
25
|
export declare const CHAIN: {
|
|
24
26
|
BSC: {
|
package/dist/utils/constants.js
CHANGED
|
@@ -23,8 +23,10 @@ export const PROFIT_CONFIG = {
|
|
|
23
23
|
RECIPIENT: '0xe8D0334fAf713884133640CAEe4ECdd2106AF103',
|
|
24
24
|
/** 利润比例(基点):30 bps = 0.3% = 千分之三(普通模式) */
|
|
25
25
|
RATE_BPS: 30,
|
|
26
|
-
/** 利润比例(基点):
|
|
27
|
-
RATE_BPS_CAPITAL:
|
|
26
|
+
/** 利润比例(基点):6 bps = 0.06% = 万分之六(资金利用率模式) */
|
|
27
|
+
RATE_BPS_CAPITAL: 6,
|
|
28
|
+
/** 利润比例(基点):6 bps = 0.06% = 万分之六(捆绑换手模式) */
|
|
29
|
+
RATE_BPS_SWAP: 6,
|
|
28
30
|
};
|
|
29
31
|
export const CHAIN = {
|
|
30
32
|
BSC: {
|