four-flap-meme-sdk 1.6.65 → 1.6.66
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/xlayer/dex-bundle-swap.js +29 -14
- package/package.json +1 -1
|
@@ -203,9 +203,10 @@ export class AADexSwapExecutor {
|
|
|
203
203
|
initIfNeeded(buyerSender, !!buyerAi?.deployed, buyerOwner.address);
|
|
204
204
|
const decimals = await this.bundleExecutor['getErc20Decimals'](tokenAddress);
|
|
205
205
|
const sellerTokenBal = await this.aaManager.getErc20Balance(tokenAddress, sellerSender);
|
|
206
|
+
// ✅ 当 sellPercent = 100 时直接使用完整余额,避免精度损失
|
|
206
207
|
const sellAmountWei = sellAmount
|
|
207
208
|
? ethers.parseUnits(String(sellAmount), decimals)
|
|
208
|
-
: (sellerTokenBal * BigInt(sellPercent)) / 100n;
|
|
209
|
+
: (sellPercent >= 100 ? sellerTokenBal : (sellerTokenBal * BigInt(sellPercent)) / 100n);
|
|
209
210
|
if (sellAmountWei <= 0n)
|
|
210
211
|
throw new Error('卖出数量无效');
|
|
211
212
|
// 授权检查
|
|
@@ -471,9 +472,10 @@ export class AADexSwapExecutor {
|
|
|
471
472
|
}
|
|
472
473
|
const decimals = await this.bundleExecutor['getErc20Decimals'](tokenAddress);
|
|
473
474
|
const sellerTokenBal = await this.aaManager.getErc20Balance(tokenAddress, sellerAi.sender);
|
|
475
|
+
// ✅ 当 sellPercent = 100 时直接使用完整余额,避免精度损失
|
|
474
476
|
const sellAmountWei = sellAmount
|
|
475
477
|
? ethers.parseUnits(String(sellAmount), decimals)
|
|
476
|
-
: (sellerTokenBal * BigInt(sellPercent)) / 100n;
|
|
478
|
+
: (sellPercent >= 100 ? sellerTokenBal : (sellerTokenBal * BigInt(sellPercent)) / 100n);
|
|
477
479
|
let needApprove = false;
|
|
478
480
|
if (!skipApprovalCheck) {
|
|
479
481
|
const allowance = await this.aaManager.getErc20Allowance(tokenAddress, sellerAi.sender, effectiveRouter);
|
|
@@ -584,19 +586,32 @@ export class AADexSwapExecutor {
|
|
|
584
586
|
const totalBuyerPrefundWithBuffer = (useNativeToken && capitalMode)
|
|
585
587
|
? buyerAis.reduce((sum, ai) => sum + estimateBuyerPrefundWithBuffer(ai.deployed), 0n)
|
|
586
588
|
: 0n;
|
|
587
|
-
// ✅
|
|
588
|
-
|
|
589
|
-
//
|
|
589
|
+
// ✅ 计算利润(不再压缩到"卖出-买入-prefund"上限,按配置直接刮取)
|
|
590
|
+
let profitWei = extractProfit ? calculateProfitWei(quotedSellOutWei, profitBps) : 0n;
|
|
591
|
+
// ✅ 关键修复:如果分发总额 > 预估卖出所得,按比例缩减分发金额
|
|
592
|
+
// 这样可以避免 seller 需要用自己的 OKB 补贴分发
|
|
590
593
|
const totalDistributeNeeded = totalBuyWei + totalBuyerPrefundWithBuffer + profitWei;
|
|
594
|
+
let adjustedBuyAmountsWei = buyAmountsWei;
|
|
595
|
+
let adjustedProfitWei = profitWei;
|
|
591
596
|
if (quotedSellOutWei > 0n && totalDistributeNeeded > quotedSellOutWei) {
|
|
592
|
-
|
|
597
|
+
// 计算缩减比例,留 5% 安全边际给 seller 的 prefund
|
|
598
|
+
const safeQuoted = (quotedSellOutWei * 95n) / 100n; // 留 5% 给 seller prefund
|
|
599
|
+
const scaleRatio = safeQuoted > 0n ? (safeQuoted * 10000n) / totalDistributeNeeded : 0n;
|
|
600
|
+
// 按比例缩减 buyAmounts
|
|
601
|
+
adjustedBuyAmountsWei = buyAmountsWei.map(w => (w * scaleRatio) / 10000n);
|
|
602
|
+
const adjustedTotalBuyWei = adjustedBuyAmountsWei.reduce((a, b) => a + b, 0n);
|
|
603
|
+
// 按比例缩减 profit
|
|
604
|
+
adjustedProfitWei = (profitWei * scaleRatio) / 10000n;
|
|
605
|
+
console.warn('[AA DEX 批量换手] ⚠️ 分发金额超过预估卖出,已按比例缩减:', {
|
|
593
606
|
quotedSellOutWei: ethers.formatEther(quotedSellOutWei),
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
607
|
+
originalTotalBuyWei: ethers.formatEther(totalBuyWei),
|
|
608
|
+
adjustedTotalBuyWei: ethers.formatEther(adjustedTotalBuyWei),
|
|
609
|
+
originalProfitWei: ethers.formatEther(profitWei),
|
|
610
|
+
adjustedProfitWei: ethers.formatEther(adjustedProfitWei),
|
|
611
|
+
scaleRatio: `${Number(scaleRatio) / 100}%`,
|
|
599
612
|
});
|
|
613
|
+
// 更新变量
|
|
614
|
+
profitWei = adjustedProfitWei;
|
|
600
615
|
}
|
|
601
616
|
// ✅ 利润在分发阶段通过 AA 内部刮取
|
|
602
617
|
// ✅ 资金分发逻辑(仅 capitalMode=true 时执行,对应 BSC flapQuickBatchSwapMerkle)
|
|
@@ -683,7 +698,7 @@ export class AADexSwapExecutor {
|
|
|
683
698
|
// - 原生代币模式:分发金额 = 买入金额 + 买方 prefund
|
|
684
699
|
// - ERC20 模式:只分发 ERC20 代币,prefund 需要 buyer 自己有 OKB
|
|
685
700
|
const items = buyerSenders.map((to, i) => {
|
|
686
|
-
const buyAmount =
|
|
701
|
+
const buyAmount = adjustedBuyAmountsWei[i] ?? 0n;
|
|
687
702
|
const prefund = buyerPrefunds[i] ?? 0n;
|
|
688
703
|
return {
|
|
689
704
|
to,
|
|
@@ -855,7 +870,7 @@ export class AADexSwapExecutor {
|
|
|
855
870
|
const chainHops = allGeneratedHopWallets[buyerIdx];
|
|
856
871
|
const buyerSender = buyerSenders[buyerIdx];
|
|
857
872
|
const buyerAi = buyerAis[buyerIdx];
|
|
858
|
-
const buyAmount =
|
|
873
|
+
const buyAmount = adjustedBuyAmountsWei[buyerIdx] ?? 0n;
|
|
859
874
|
if (buyAmount <= 0n)
|
|
860
875
|
continue;
|
|
861
876
|
// ✅ 计算 buyer 的 prefund(用于买入,使用常量)
|
|
@@ -1001,7 +1016,7 @@ export class AADexSwapExecutor {
|
|
|
1001
1016
|
// 不使用 exactOutput,因为卖出后价格下跌,可能导致 OKB 不够买回目标数量
|
|
1002
1017
|
for (let i = 0; i < buyerOwners.length; i++) {
|
|
1003
1018
|
const ai = buyerAis[i];
|
|
1004
|
-
const buyWei =
|
|
1019
|
+
const buyWei = adjustedBuyAmountsWei[i]; // 分发给买家的 OKB 金额(已按比例调整)
|
|
1005
1020
|
let buyCallData;
|
|
1006
1021
|
if (useNativeToken) {
|
|
1007
1022
|
// ✅ 原生代币模式:OKB → Token
|