four-flap-meme-sdk 1.6.45 → 1.6.47
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.
|
@@ -557,12 +557,42 @@ export class AADexSwapExecutor {
|
|
|
557
557
|
return 0n;
|
|
558
558
|
}
|
|
559
559
|
})();
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
560
|
+
// ✅ 关键修复:提前计算 buyerPrefund,用于资金充足性检查
|
|
561
|
+
// 在 capitalMode 下,分发金额 = 买入金额 + buyerPrefund + 利润
|
|
562
|
+
// 必须确保卖出所得 >= 分发金额,否则交易会失败
|
|
563
|
+
const feeDataEarly = await this.aaManager.getFeeData();
|
|
564
|
+
const gasPriceEarly = feeDataEarly.gasPrice ?? feeDataEarly.maxFeePerGas ?? 5000000000n;
|
|
565
|
+
const estimateBuyerPrefundEarly = (deployed) => {
|
|
566
|
+
const callGas = DEX_BUY_CALL_GAS_LIMIT;
|
|
567
|
+
const verifyGas = deployed ? VERIFICATION_GAS_LIMIT_NORMAL : VERIFICATION_GAS_LIMIT_DEPLOY;
|
|
568
|
+
const preVerifyGas = PRE_VERIFICATION_GAS;
|
|
569
|
+
const totalGas = callGas + verifyGas + preVerifyGas;
|
|
570
|
+
return (totalGas * gasPriceEarly * PREFUND_BUFFER_PERCENT) / 100n;
|
|
571
|
+
};
|
|
572
|
+
// ✅ 计算所有 buyer 需要的 prefund 总和(仅原生代币模式 + capitalMode 需要)
|
|
573
|
+
const totalBuyerPrefundEarly = (useNativeToken && capitalMode)
|
|
574
|
+
? buyerAis.reduce((sum, ai) => sum + estimateBuyerPrefundEarly(ai.deployed), 0n)
|
|
575
|
+
: 0n;
|
|
576
|
+
// ✅ 计算利润(考虑 buyerPrefund 后的可用利润空间)
|
|
563
577
|
const profitWeiRaw = extractProfit ? calculateProfitWei(quotedSellOutWei, profitBps) : 0n;
|
|
564
|
-
|
|
565
|
-
const
|
|
578
|
+
// 利润上限 = 卖出所得 - 买入金额 - buyerPrefund
|
|
579
|
+
const profitCapWithPrefund = quotedSellOutWei > (totalBuyWei + totalBuyerPrefundEarly)
|
|
580
|
+
? (quotedSellOutWei - totalBuyWei - totalBuyerPrefundEarly)
|
|
581
|
+
: 0n;
|
|
582
|
+
const profitWei = profitWeiRaw > profitCapWithPrefund ? profitCapWithPrefund : profitWeiRaw;
|
|
583
|
+
// ✅ 资金充足性检查:卖出所得 >= 买入金额 + buyerPrefund + 利润
|
|
584
|
+
const totalDistributeNeeded = totalBuyWei + totalBuyerPrefundEarly + profitWei;
|
|
585
|
+
if (quotedSellOutWei > 0n && totalDistributeNeeded > quotedSellOutWei) {
|
|
586
|
+
console.error('[AA DEX 批量换手] ❌ 资金不足:', {
|
|
587
|
+
quotedSellOutWei: ethers.formatEther(quotedSellOutWei),
|
|
588
|
+
totalBuyWei: ethers.formatEther(totalBuyWei),
|
|
589
|
+
totalBuyerPrefund: ethers.formatEther(totalBuyerPrefundEarly),
|
|
590
|
+
profitWei: ethers.formatEther(profitWei),
|
|
591
|
+
totalNeeded: ethers.formatEther(totalDistributeNeeded),
|
|
592
|
+
shortfall: ethers.formatEther(totalDistributeNeeded - quotedSellOutWei),
|
|
593
|
+
});
|
|
594
|
+
throw new Error(`AA 批量换手:资金不足!卖出预估 ${ethers.formatEther(quotedSellOutWei)} OKB,但分发需要 ${ethers.formatEther(totalDistributeNeeded)} OKB(买入 ${ethers.formatEther(totalBuyWei)} + prefund ${ethers.formatEther(totalBuyerPrefundEarly)} + 利润 ${ethers.formatEther(profitWei)}),缺口 ${ethers.formatEther(totalDistributeNeeded - quotedSellOutWei)} OKB`);
|
|
595
|
+
}
|
|
566
596
|
// ✅ 利润在分发阶段通过 AA 内部刮取
|
|
567
597
|
// ✅ 资金分发逻辑(仅 capitalMode=true 时执行,对应 BSC flapQuickBatchSwapMerkle)
|
|
568
598
|
// capitalMode=false 时跳过分发,买方用自己的 OKB(对应 BSC flapBatchSwapMerkle)
|
|
@@ -757,6 +787,24 @@ export class AADexSwapExecutor {
|
|
|
757
787
|
allGeneratedHopWallets.push(chainHops);
|
|
758
788
|
}
|
|
759
789
|
console.log(`[AA DEX 多跳] ✅ 使用预充值 hop 钱包: ${totalHopsNeeded} 个 (${buyerSenders.length} 条链 × ${effectiveHopCount} 跳)`);
|
|
790
|
+
// ✅ 关键修复:检查 buyer 钱包是否有足够的 OKB 支付 prefund
|
|
791
|
+
// ERC-4337 的 handleOps 会先验证所有 UserOps(需要 prefund),然后才执行
|
|
792
|
+
// 所以 buyer 需要在交易前就有足够的 OKB,不能依赖 hop 链在 execution 阶段转入的资金
|
|
793
|
+
const buyerBalances = await Promise.all(buyerSenders.map(s => provider.getBalance(s)));
|
|
794
|
+
const insufficientBuyers = [];
|
|
795
|
+
for (let i = 0; i < buyerSenders.length; i++) {
|
|
796
|
+
const buyerAi = buyerAis[i];
|
|
797
|
+
const buyerPrefundNeeded = estimatePrefund(DEX_BUY_CALL_GAS_LIMIT, buyerAi.deployed);
|
|
798
|
+
if (buyerBalances[i] < buyerPrefundNeeded) {
|
|
799
|
+
insufficientBuyers.push(`${buyerSenders[i]} (余额: ${ethers.formatEther(buyerBalances[i])} OKB, 需要: ${ethers.formatEther(buyerPrefundNeeded)} OKB, 缺口: ${ethers.formatEther(buyerPrefundNeeded - buyerBalances[i])} OKB)`);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
if (insufficientBuyers.length > 0) {
|
|
803
|
+
console.error('[AA DEX 多跳] ❌ 以下 buyer 钱包 OKB 余额不足以支付 prefund:', insufficientBuyers);
|
|
804
|
+
throw new Error(`Buyer 钱包 OKB 余额不足!在 ERC-4337 的 handleOps 中,所有 UserOps 在 Validation 阶段就需要支付 prefund,此时 hop 链还没有执行。` +
|
|
805
|
+
`请先给 buyer 钱包充值 OKB。不足的钱包: ${insufficientBuyers.length} 个`);
|
|
806
|
+
}
|
|
807
|
+
console.log('[AA DEX 多跳] ✅ Buyer 钱包 prefund 检查通过');
|
|
760
808
|
}
|
|
761
809
|
else {
|
|
762
810
|
// Paymaster 模式:生成新钱包(不需要预充值,prefund=0)
|
|
@@ -368,12 +368,42 @@ export class AAPortalSwapExecutor {
|
|
|
368
368
|
catch {
|
|
369
369
|
quotedSellOutWei = await this.portalQuery.quoteExactInput(tokenAddress, ZERO_ADDRESS, sellAmountWei);
|
|
370
370
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
371
|
+
// ✅ 关键修复:提前计算 buyerPrefund,用于资金充足性检查
|
|
372
|
+
// 在 capitalMode 下,分发金额 = 买入金额 + buyerPrefund + 利润
|
|
373
|
+
// 必须确保卖出所得 >= 分发金额,否则交易会失败
|
|
374
|
+
const feeDataEarly = await this.aaManager.getFeeData();
|
|
375
|
+
const gasPriceEarly = feeDataEarly.gasPrice ?? feeDataEarly.maxFeePerGas ?? 5000000000n;
|
|
376
|
+
const estimateBuyerPrefundEarly = (deployed) => {
|
|
377
|
+
const callGas = PORTAL_BUY_CALL_GAS_LIMIT;
|
|
378
|
+
const verifyGas = deployed ? VERIFICATION_GAS_LIMIT_NORMAL : VERIFICATION_GAS_LIMIT_DEPLOY;
|
|
379
|
+
const preVerifyGas = PRE_VERIFICATION_GAS;
|
|
380
|
+
const totalGas = callGas + verifyGas + preVerifyGas;
|
|
381
|
+
return (totalGas * gasPriceEarly * PREFUND_BUFFER_PERCENT) / 100n;
|
|
382
|
+
};
|
|
383
|
+
// ✅ 计算所有 buyer 需要的 prefund 总和(仅原生代币模式 + capitalMode 需要)
|
|
384
|
+
const totalBuyerPrefundEarly = (useNativeToken && capitalMode)
|
|
385
|
+
? buyerAis.reduce((sum, ai) => sum + estimateBuyerPrefundEarly(ai.deployed), 0n)
|
|
386
|
+
: 0n;
|
|
387
|
+
// ✅ 计算利润(考虑 buyerPrefund 后的可用利润空间)
|
|
374
388
|
const profitWeiRaw = extractProfit ? calculateProfitWei(quotedSellOutWei, profitBps) : 0n;
|
|
375
|
-
|
|
376
|
-
const
|
|
389
|
+
// 利润上限 = 卖出所得 - 买入金额 - buyerPrefund
|
|
390
|
+
const profitCapWithPrefund = quotedSellOutWei > (totalBuyWei + totalBuyerPrefundEarly)
|
|
391
|
+
? (quotedSellOutWei - totalBuyWei - totalBuyerPrefundEarly)
|
|
392
|
+
: 0n;
|
|
393
|
+
const profitWei = profitWeiRaw > profitCapWithPrefund ? profitCapWithPrefund : profitWeiRaw;
|
|
394
|
+
// ✅ 资金充足性检查:卖出所得 >= 买入金额 + buyerPrefund + 利润
|
|
395
|
+
const totalDistributeNeeded = totalBuyWei + totalBuyerPrefundEarly + profitWei;
|
|
396
|
+
if (quotedSellOutWei > 0n && totalDistributeNeeded > quotedSellOutWei) {
|
|
397
|
+
console.error('[AA Portal 批量换手] ❌ 资金不足:', {
|
|
398
|
+
quotedSellOutWei: ethers.formatEther(quotedSellOutWei),
|
|
399
|
+
totalBuyWei: ethers.formatEther(totalBuyWei),
|
|
400
|
+
totalBuyerPrefund: ethers.formatEther(totalBuyerPrefundEarly),
|
|
401
|
+
profitWei: ethers.formatEther(profitWei),
|
|
402
|
+
totalNeeded: ethers.formatEther(totalDistributeNeeded),
|
|
403
|
+
shortfall: ethers.formatEther(totalDistributeNeeded - quotedSellOutWei),
|
|
404
|
+
});
|
|
405
|
+
throw new Error(`AA 批量换手:资金不足!卖出预估 ${ethers.formatEther(quotedSellOutWei)} OKB,但分发需要 ${ethers.formatEther(totalDistributeNeeded)} OKB(买入 ${ethers.formatEther(totalBuyWei)} + prefund ${ethers.formatEther(totalBuyerPrefundEarly)} + 利润 ${ethers.formatEther(profitWei)}),缺口 ${ethers.formatEther(totalDistributeNeeded - quotedSellOutWei)} OKB`);
|
|
406
|
+
}
|
|
377
407
|
// ✅ 利润在分发阶段通过 AA 内部刮取
|
|
378
408
|
// ✅ 资金分发逻辑(仅 capitalMode=true 时执行,对应 BSC flapQuickBatchSwapMerkle)
|
|
379
409
|
// capitalMode=false 时跳过分发,买方用自己的 OKB(对应 BSC flapBatchSwapMerkle)
|
|
@@ -567,6 +597,24 @@ export class AAPortalSwapExecutor {
|
|
|
567
597
|
allGeneratedHopWallets.push(chainHops);
|
|
568
598
|
}
|
|
569
599
|
console.log(`[AA Portal 多跳] ✅ 使用预充值 hop 钱包: ${totalHopsNeeded} 个`);
|
|
600
|
+
// ✅ 关键修复:检查 buyer 钱包是否有足够的 OKB 支付 prefund
|
|
601
|
+
// ERC-4337 的 handleOps 会先验证所有 UserOps(需要 prefund),然后才执行
|
|
602
|
+
// 所以 buyer 需要在交易前就有足够的 OKB,不能依赖 hop 链在 execution 阶段转入的资金
|
|
603
|
+
const buyerBalances = await Promise.all(buyerSenders.map(s => provider.getBalance(s)));
|
|
604
|
+
const insufficientBuyers = [];
|
|
605
|
+
for (let i = 0; i < buyerSenders.length; i++) {
|
|
606
|
+
const buyerAi = buyerAis[i];
|
|
607
|
+
const buyerPrefundNeeded = estimatePrefund(PORTAL_BUY_CALL_GAS_LIMIT, buyerAi.deployed);
|
|
608
|
+
if (buyerBalances[i] < buyerPrefundNeeded) {
|
|
609
|
+
insufficientBuyers.push(`${buyerSenders[i]} (余额: ${ethers.formatEther(buyerBalances[i])} OKB, 需要: ${ethers.formatEther(buyerPrefundNeeded)} OKB, 缺口: ${ethers.formatEther(buyerPrefundNeeded - buyerBalances[i])} OKB)`);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
if (insufficientBuyers.length > 0) {
|
|
613
|
+
console.error('[AA Portal 多跳] ❌ 以下 buyer 钱包 OKB 余额不足以支付 prefund:', insufficientBuyers);
|
|
614
|
+
throw new Error(`Buyer 钱包 OKB 余额不足!在 ERC-4337 的 handleOps 中,所有 UserOps 在 Validation 阶段就需要支付 prefund,此时 hop 链还没有执行。` +
|
|
615
|
+
`请先给 buyer 钱包充值 OKB。不足的钱包: ${insufficientBuyers.length} 个`);
|
|
616
|
+
}
|
|
617
|
+
console.log('[AA Portal 多跳] ✅ Buyer 钱包 prefund 检查通过');
|
|
570
618
|
}
|
|
571
619
|
else {
|
|
572
620
|
// Paymaster 模式:生成新钱包
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "four-flap-meme-sdk",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.47",
|
|
4
4
|
"description": "SDK for Flap bonding curve and four.meme TokenManager",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -36,4 +36,4 @@
|
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"typescript": "^5.6.3"
|
|
38
38
|
}
|
|
39
|
-
}
|
|
39
|
+
}
|