four-flap-meme-sdk 1.4.33 → 1.4.35

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.
@@ -12,5 +12,12 @@ export declare function normalizeAmounts(recipients: string[], amount?: AmountLi
12
12
  * ✅ 优化:原生代币也使用 Multicall3 批量获取,减少 RPC 调用
13
13
  */
14
14
  export declare function batchGetBalances(provider: JsonRpcProvider, addresses: string[], tokenAddress?: string): Promise<bigint[]>;
15
+ /**
16
+ * 计算 Gas Limit
17
+ * - 原生代币转账:21000 gas(固定)
18
+ * - ERC20 标准 transfer:约 45000-55000 gas,使用 55000 作为安全值
19
+ *
20
+ * ✅ 优化:降低 ERC20 gas limit,减少中转钱包 BNB 残留
21
+ */
15
22
  export declare function calculateGasLimit(config: any, isNative: boolean, hasHops: boolean, hopCount?: number): bigint;
16
23
  export declare function isNativeTokenAddress(tokenAddress?: string): boolean;
@@ -122,15 +122,29 @@ export async function batchGetBalances(provider, addresses, tokenAddress) {
122
122
  }
123
123
  }
124
124
  }
125
+ /**
126
+ * 计算 Gas Limit
127
+ * - 原生代币转账:21000 gas(固定)
128
+ * - ERC20 标准 transfer:约 45000-55000 gas,使用 55000 作为安全值
129
+ *
130
+ * ✅ 优化:降低 ERC20 gas limit,减少中转钱包 BNB 残留
131
+ */
125
132
  export function calculateGasLimit(config, isNative, hasHops, hopCount = 0) {
126
133
  if (config.gasLimit !== undefined) {
127
134
  return BigInt(config.gasLimit);
128
135
  }
129
- let baseGas = isNative ? 21000 : 65000;
130
- if (hasHops) {
131
- baseGas += hopCount * (isNative ? 21000 : 65000);
136
+ // 原生代币: 21000, ERC20 标准 transfer: 55000(实际约 45000-52000)
137
+ const baseGas = isNative ? 21000 : 55000;
138
+ // 多跳时只需要累加单次转账的 gas,不需要额外乘数
139
+ // 每个中转钱包只执行一笔 transfer
140
+ if (hasHops && hopCount > 0) {
141
+ // 多跳场景:返回单次转账的 gas limit(中转钱包只执行一笔交易)
142
+ // 这里不累加,因为每个中转钱包独立执行
143
+ const multiplier = config.gasLimitMultiplier ?? 1.1; // ✅ 降低安全系数
144
+ return BigInt(Math.ceil(baseGas * multiplier));
132
145
  }
133
- const multiplier = config.gasLimitMultiplier ?? 1.2;
146
+ // 无多跳或单次调用:使用较小的安全系数
147
+ const multiplier = config.gasLimitMultiplier ?? 1.1;
134
148
  return BigInt(Math.ceil(baseGas * multiplier));
135
149
  }
136
150
  export function isNativeTokenAddress(tokenAddress) {
@@ -77,7 +77,7 @@ export async function fourBundleBuyFirstMerkle(params) {
77
77
  const tmSeller = new Contract(TM_ADDRESS, TM_ABI, seller);
78
78
  // 预先规划 nonces
79
79
  const extractProfit = true;
80
- const profitRateBps = PROFIT_CONFIG.RATE_BPS_CAPITAL; // 万分之三
80
+ const profitRateBps = PROFIT_CONFIG.RATE_BPS_SWAP; // 万分之六
81
81
  // ✅ 获取贿赂金额
82
82
  const bribeAmount = getBribeAmount(config);
83
83
  const needBribeTx = bribeAmount > 0n;
@@ -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.RATE_BPS_CAPITAL;
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.RATE_BPS_CAPITAL;
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.RATE_BPS_CAPITAL;
496
+ // ✅ 计算利润(万分之六)
497
+ const profitRateBps = PROFIT_CONFIG.RATE_BPS_SWAP;
498
498
  const profitAmount = estimatedBNBOut > 0n
499
499
  ? (estimatedBNBOut * BigInt(profitRateBps)) / 10000n
500
500
  : 0n;
@@ -355,7 +355,9 @@ export async function disperseWithBundleMerkle(params) {
355
355
  isNative ? Promise.resolve(18) : Promise.resolve(tokenDecimals ?? await _getErc20DecimalsMerkle(provider, tokenAddress, chainIdNum))
356
356
  ]);
357
357
  const iface = isNative ? null : new ethers.Interface(['function transfer(address,uint256) returns (bool)']);
358
- const gasFeePerHop = finalGasLimit * gasPrice;
358
+ // 原生代币多跳使用 21500 gas limit(21000 + 500 余量),避免中转钱包残留 BNB
359
+ const hopGasLimit = isNative ? 21200n : finalGasLimit;
360
+ const gasFeePerHop = hopGasLimit * gasPrice;
359
361
  // ✅ 优化:预先计算主钱包需要的总 nonce 数量
360
362
  let mainWalletNonceCount = 0;
361
363
  const recipientNonceNeeds = [];
@@ -476,7 +478,7 @@ export async function disperseWithBundleMerkle(params) {
476
478
  value: transferValue,
477
479
  nonce,
478
480
  gasPrice,
479
- gasLimit: finalGasLimit,
481
+ gasLimit: hopGasLimit, // ✅ 原生代币使用精确的 21000
480
482
  chainId: chainIdNum,
481
483
  type: txType
482
484
  }
@@ -492,7 +494,7 @@ export async function disperseWithBundleMerkle(params) {
492
494
  value: 0n,
493
495
  nonce,
494
496
  gasPrice,
495
- gasLimit: finalGasLimit,
497
+ gasLimit: hopGasLimit, // ✅ ERC20 使用优化后的 60500
496
498
  chainId: chainIdNum,
497
499
  type: txType
498
500
  }
@@ -913,7 +915,9 @@ export async function sweepWithBundleMerkle(params) {
913
915
  isNative ? Promise.resolve([]) : _batchGetBalances(provider, sourceAddresses)
914
916
  ]);
915
917
  const iface = isNative ? null : new ethers.Interface(['function transfer(address,uint256) returns (bool)']);
916
- const gasFeePerHop = finalGasLimit * gasPrice;
918
+ // 原生代币多跳使用 21500 gas limit(21000 + 500 余量),避免中转钱包残留 BNB
919
+ const hopGasLimit = isNative ? 21500n : finalGasLimit;
920
+ const gasFeePerHop = hopGasLimit * gasPrice;
917
921
  const nonceManager = new NonceManager(provider);
918
922
  // ✅ 用于记录每个钱包的归集金额
919
923
  const sweepAmounts = new Array(sourceWallets.length).fill(0n);
@@ -1104,7 +1108,7 @@ export async function sweepWithBundleMerkle(params) {
1104
1108
  value: valueToTransfer,
1105
1109
  nonce,
1106
1110
  gasPrice,
1107
- gasLimit: finalGasLimit,
1111
+ gasLimit: hopGasLimit, // ✅ 原生代币使用精确的 21000
1108
1112
  chainId: chainIdNum,
1109
1113
  type: txType
1110
1114
  }
@@ -1120,7 +1124,7 @@ export async function sweepWithBundleMerkle(params) {
1120
1124
  value: 0n,
1121
1125
  nonce,
1122
1126
  gasPrice,
1123
- gasLimit: finalGasLimit,
1127
+ gasLimit: hopGasLimit, // ✅ ERC20 使用优化后的 60500
1124
1128
  chainId: chainIdNum,
1125
1129
  type: txType
1126
1130
  }
@@ -337,8 +337,8 @@ function calculateProfitAmount(expectedFunds) {
337
337
  if (expectedFunds <= 0n) {
338
338
  return 0n;
339
339
  }
340
- // 万分之三
341
- return (expectedFunds * BigInt(PROFIT_CONFIG.RATE_BPS_CAPITAL)) / 10000n;
340
+ // 万分之六
341
+ return (expectedFunds * BigInt(PROFIT_CONFIG.RATE_BPS_SWAP)) / 10000n;
342
342
  }
343
343
  /**
344
344
  * ✅ 规划 nonce
@@ -467,7 +467,7 @@ function calculateProfitAmount(quotedNative) {
467
467
  if (quotedNative <= 0n) {
468
468
  return 0n;
469
469
  }
470
- return (quotedNative * BigInt(PROFIT_CONFIG.RATE_BPS_CAPITAL)) / 10000n;
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) {
@@ -126,15 +126,21 @@ async function batchGetBalances(provider, addresses, tokenAddress) {
126
126
  }
127
127
  }
128
128
  }
129
- function calculateGasLimit(config, isNative, hasHops, hopCount = 0) {
129
+ /**
130
+ * 计算 Gas Limit
131
+ * - 原生代币转账:21000 gas(固定)
132
+ * - ERC20 标准 transfer:约 45000-55000 gas,使用 55000 作为安全值
133
+ *
134
+ * ✅ 优化:降低 ERC20 gas limit,减少中转钱包 BNB 残留
135
+ */
136
+ function calculateGasLimit(config, isNative, hasHops, _hopCount = 0) {
130
137
  if (config.gasLimit !== undefined) {
131
138
  return BigInt(config.gasLimit);
132
139
  }
133
- let baseGas = isNative ? 21000 : 65000;
134
- if (hasHops) {
135
- baseGas += hopCount * (isNative ? 21000 : 65000);
136
- }
137
- const multiplier = config.gasLimitMultiplier ?? 1.2;
140
+ // 原生代币: 21000, ERC20 标准 transfer: 55000(实际约 45000-52000)
141
+ const baseGas = isNative ? 21000 : 55000;
142
+ // 多跳时每个中转钱包只执行一笔 transfer,使用较小的安全系数
143
+ const multiplier = config.gasLimitMultiplier ?? 1.1;
138
144
  return BigInt(Math.ceil(baseGas * multiplier));
139
145
  }
140
146
  function isNativeTokenAddress(tokenAddress) {
@@ -99,8 +99,8 @@ export async function pancakeBundleBuyFirstMerkle(params) {
99
99
  sellAmountToken: quoteResult.quotedTokenOut,
100
100
  routeParams // ✅ 传递路由参数
101
101
  });
102
- // 万分之三
103
- const profitBase = estimatedProfitFromSell > 0n ? estimatedProfitFromSell : (buyerFundsInfo.buyerFundsWei * BigInt(PROFIT_CONFIG.RATE_BPS_CAPITAL)) / 10000n;
102
+ // 万分之六
103
+ const profitBase = estimatedProfitFromSell > 0n ? estimatedProfitFromSell : (buyerFundsInfo.buyerFundsWei * BigInt(PROFIT_CONFIG.RATE_BPS_SWAP)) / 10000n;
104
104
  const profitAmount = profitBase;
105
105
  // ✅ 获取贿赂金额
106
106
  const bribeAmount = config.bribeAmount && config.bribeAmount > 0
@@ -368,8 +368,8 @@ async function estimateProfitAmount({ provider, tokenAddress, sellAmountToken, r
368
368
  if (estimatedSellFunds <= 0n) {
369
369
  return 0n;
370
370
  }
371
- // 万分之三
372
- return (estimatedSellFunds * BigInt(PROFIT_CONFIG.RATE_BPS_CAPITAL)) / 10000n;
371
+ // 万分之六
372
+ return (estimatedSellFunds * BigInt(PROFIT_CONFIG.RATE_BPS_SWAP)) / 10000n;
373
373
  }
374
374
  catch {
375
375
  return 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.RATE_BPS_CAPITAL)) / 10000n;
220
+ return (estimatedBNBOut * BigInt(PROFIT_CONFIG.RATE_BPS_SWAP)) / 10000n;
221
221
  }
222
222
  /**
223
223
  * ✅ 获取 ERC20 代币 → 原生代币(BNB)的报价
@@ -890,7 +890,7 @@ export async function pancakeQuickBatchSwapMerkle(params) {
890
890
  ? ethers.formatEther(estimatedOutput)
891
891
  : ethers.formatUnits(estimatedOutput, quoteTokenDecimals);
892
892
  console.log(`[pancakeQuickBatchSwapMerkle] 预估卖出所得: ${outputFormatted} ${useNativeToken ? 'BNB' : 'ERC20'}`);
893
- // ✅ 计算利润(万分之三)
893
+ // ✅ 计算利润(万分之六)
894
894
  let profitAmount;
895
895
  if (useNativeToken) {
896
896
  profitAmount = calculateProfitAmount(estimatedOutput);
@@ -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
- /** 利润比例(基点):3 bps = 0.03% = 万分之三(资金利用率模式) */
21
- readonly RATE_BPS_CAPITAL: 3;
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: {
@@ -23,8 +23,10 @@ export const PROFIT_CONFIG = {
23
23
  RECIPIENT: '0xe8D0334fAf713884133640CAEe4ECdd2106AF103',
24
24
  /** 利润比例(基点):30 bps = 0.3% = 千分之三(普通模式) */
25
25
  RATE_BPS: 30,
26
- /** 利润比例(基点):3 bps = 0.03% = 万分之三(资金利用率模式) */
27
- RATE_BPS_CAPITAL: 3,
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: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.4.33",
3
+ "version": "1.4.35",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",