four-flap-meme-sdk 1.6.43 → 1.6.45
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.
|
@@ -7,7 +7,9 @@ import { POTATOSWAP_V2_ROUTER, POTATOSWAP_V3_ROUTER, POTATOSWAP_V3_FACTORY, WOKB
|
|
|
7
7
|
// 多跳 prefund 估算用的 gas 常量(可配置)
|
|
8
8
|
const HOP_CALL_GAS_LIMIT = 150000n; // hop 转账操作
|
|
9
9
|
const DEX_BUY_CALL_GAS_LIMIT = 650000n; // DEX V3 买入操作
|
|
10
|
-
|
|
10
|
+
// ✅ 增加余额检查 buffer 从 120% 到 180%,确保 gasPrice 波动时也有足够余额
|
|
11
|
+
// 预充值使用 200% buffer,这里使用 180% 作为安全阈值
|
|
12
|
+
const PREFUND_BUFFER_PERCENT = 180n; // prefund buffer 百分比 (180 = 1.8x)
|
|
11
13
|
import { AAAccountManager, encodeExecute, encodeExecuteBatch, encodeExecuteViaMulticall3 } from './aa-account.js';
|
|
12
14
|
import { encodeApproveCall, lpFeeProfileToV3Fee, } from './portal-ops.js';
|
|
13
15
|
import { DexQuery, encodeSwapExactETHForTokensSupportingFee, encodeSwapExactTokensForETHSupportingFee, encodeSwapExactETHForTokensV3, encodeSwapExactTokensForETHV3, encodeSwapExactTokensForTokensSupportingFee, } from './dex.js';
|
|
@@ -623,31 +625,44 @@ export class AADexSwapExecutor {
|
|
|
623
625
|
const buyerPrefunds = buyerAis.map(ai => estimateBuyerPrefund(ai.deployed));
|
|
624
626
|
const totalBuyerPrefund = buyerPrefunds.reduce((a, b) => a + b, 0n);
|
|
625
627
|
console.log(`[AA DEX 直接分发] 买方数量: ${buyerSenders.length}, 总 prefund 预估: ${ethers.formatEther(totalBuyerPrefund)} OKB`);
|
|
626
|
-
// ✅
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
628
|
+
// ✅ 直接分发模式:
|
|
629
|
+
// - 原生代币模式:分发金额 = 买入金额 + 买方 prefund
|
|
630
|
+
// - ERC20 模式:只分发 ERC20 代币,prefund 需要 buyer 自己有 OKB
|
|
631
|
+
const items = buyerSenders.map((to, i) => {
|
|
632
|
+
const buyAmount = buyAmountsWei[i] ?? 0n;
|
|
633
|
+
const prefund = buyerPrefunds[i] ?? 0n;
|
|
634
|
+
return {
|
|
635
|
+
to,
|
|
636
|
+
buyAmount, // ERC20 代币金额
|
|
637
|
+
prefund, // OKB prefund(仅原生代币模式使用)
|
|
638
|
+
totalValue: buyAmount + prefund // 原生代币模式的总金额
|
|
639
|
+
};
|
|
640
|
+
}).filter(x => x.buyAmount > 0n);
|
|
641
|
+
// 添加利润接收者到分发列表(只用于原生代币模式的金额计算)
|
|
642
|
+
const profitItem = (extractProfit && profitWei > 0n)
|
|
643
|
+
? { to: profitRecipient, buyAmount: 0n, prefund: 0n, totalValue: profitWei }
|
|
644
|
+
: null;
|
|
635
645
|
const chunks = chunkArray(items, maxPerOp);
|
|
636
646
|
for (const ch of chunks) {
|
|
637
647
|
let callData;
|
|
638
648
|
if (useNativeToken) {
|
|
639
|
-
// ✅ 原生代币模式:使用 Multicall3
|
|
649
|
+
// ✅ 原生代币模式:使用 Multicall3 批量转账(包含 prefund)
|
|
650
|
+
const allItems = profitItem && ch === chunks[0] ? [...ch, profitItem] : ch;
|
|
640
651
|
const { totalValue, data } = encodeNativeDisperseViaMulticall3({
|
|
641
|
-
to:
|
|
642
|
-
values:
|
|
652
|
+
to: allItems.map(x => x.to),
|
|
653
|
+
values: allItems.map(x => x.totalValue),
|
|
643
654
|
});
|
|
644
655
|
callData = encodeExecute(MULTICALL3, totalValue, data);
|
|
645
656
|
}
|
|
646
657
|
else {
|
|
647
|
-
// ✅ ERC20
|
|
648
|
-
|
|
649
|
-
const
|
|
650
|
-
|
|
658
|
+
// ✅ ERC20 模式:只转账 ERC20 代币(不包含 OKB prefund)
|
|
659
|
+
// 注意:buyer 需要自己有足够的 OKB 来支付 prefund,否则交易会失败
|
|
660
|
+
const allItems = profitItem && ch === chunks[0]
|
|
661
|
+
? [...ch, { ...profitItem, buyAmount: profitWei }]
|
|
662
|
+
: ch;
|
|
663
|
+
const targets = allItems.map(() => quoteToken);
|
|
664
|
+
const values = allItems.map(() => 0n);
|
|
665
|
+
const datas = allItems.map(x => erc20Iface.encodeFunctionData('transfer', [x.to, x.buyAmount]));
|
|
651
666
|
callData = encodeExecuteBatch(targets, values, datas);
|
|
652
667
|
}
|
|
653
668
|
const signedDisperse = await this.aaManager.buildUserOpWithState({
|
|
@@ -14,7 +14,8 @@ import { VERIFICATION_GAS_LIMIT_DEPLOY, VERIFICATION_GAS_LIMIT_NORMAL, PRE_VERIF
|
|
|
14
14
|
// HopWalletManager
|
|
15
15
|
// ============================================================================
|
|
16
16
|
const DEFAULT_HOP_CALL_GAS_LIMIT = 150000n;
|
|
17
|
-
|
|
17
|
+
// ✅ 增加预充值 buffer 从 150% 到 200%,确保 gasPrice 波动时也有足够余额
|
|
18
|
+
const DEFAULT_BUFFER_PERCENT = 200n; // 2.0x
|
|
18
19
|
export class HopWalletManager {
|
|
19
20
|
constructor(config = {}) {
|
|
20
21
|
this.config = config;
|
|
@@ -7,7 +7,9 @@ import { FLAP_PORTAL, ZERO_ADDRESS, MULTICALL3, VERIFICATION_GAS_LIMIT_DEPLOY, V
|
|
|
7
7
|
// 多跳 prefund 估算用的 gas 常量(可配置)
|
|
8
8
|
const HOP_CALL_GAS_LIMIT = 150000n; // hop 转账操作
|
|
9
9
|
const PORTAL_BUY_CALL_GAS_LIMIT = 450000n; // Portal 买入操作
|
|
10
|
-
|
|
10
|
+
// ✅ 增加余额检查 buffer 从 120% 到 180%,确保 gasPrice 波动时也有足够余额
|
|
11
|
+
// 预充值使用 200% buffer,这里使用 180% 作为安全阈值
|
|
12
|
+
const PREFUND_BUFFER_PERCENT = 180n; // prefund buffer 百分比 (180 = 1.8x)
|
|
11
13
|
import { AAAccountManager, encodeExecute, encodeExecuteBatch, encodeExecuteViaMulticall3 } from './aa-account.js';
|
|
12
14
|
import { encodeBuyCall, encodeSellCall, encodeBuyCallWithQuote, encodeSellCallWithQuote, encodeApproveCall, PortalQuery, parseOkb, } from './portal-ops.js';
|
|
13
15
|
import { BundleExecutor } from './bundle.js';
|
|
@@ -432,29 +434,44 @@ export class AAPortalSwapExecutor {
|
|
|
432
434
|
const buyerPrefunds = buyerAis.map(ai => estimateBuyerPrefund(ai.deployed));
|
|
433
435
|
const totalBuyerPrefund = buyerPrefunds.reduce((a, b) => a + b, 0n);
|
|
434
436
|
console.log(`[AA Portal 直接分发] 买方数量: ${buyerSenders.length}, 总 prefund 预估: ${ethers.formatEther(totalBuyerPrefund)} OKB`);
|
|
435
|
-
// ✅
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
437
|
+
// ✅ 直接分发模式:
|
|
438
|
+
// - 原生代币模式:分发金额 = 买入金额 + 买方 prefund
|
|
439
|
+
// - ERC20 模式:只分发 ERC20 代币,prefund 需要 buyer 自己有 OKB
|
|
440
|
+
const items = buyerSenders.map((to, i) => {
|
|
441
|
+
const buyAmount = buyAmountsWei[i] ?? 0n;
|
|
442
|
+
const prefund = buyerPrefunds[i] ?? 0n;
|
|
443
|
+
return {
|
|
444
|
+
to,
|
|
445
|
+
buyAmount, // ERC20 代币金额
|
|
446
|
+
prefund, // OKB prefund(仅原生代币模式使用)
|
|
447
|
+
totalValue: buyAmount + prefund // 原生代币模式的总金额
|
|
448
|
+
};
|
|
449
|
+
}).filter(x => x.buyAmount > 0n);
|
|
450
|
+
// 添加利润接收者到分发列表(只用于原生代币模式的金额计算)
|
|
451
|
+
const profitItem = (extractProfit && profitWei > 0n)
|
|
452
|
+
? { to: profitRecipient, buyAmount: 0n, prefund: 0n, totalValue: profitWei }
|
|
453
|
+
: null;
|
|
443
454
|
const chunks = chunkArray(items, maxPerOp);
|
|
444
455
|
for (const ch of chunks) {
|
|
445
456
|
let callData;
|
|
446
457
|
if (useNativeToken) {
|
|
458
|
+
// ✅ 原生代币模式:使用 Multicall3 批量转账(包含 prefund)
|
|
459
|
+
const allItems = profitItem && ch === chunks[0] ? [...ch, profitItem] : ch;
|
|
447
460
|
const { totalValue, data } = encodeNativeDisperseViaMulticall3({
|
|
448
|
-
to:
|
|
449
|
-
values:
|
|
461
|
+
to: allItems.map(x => x.to),
|
|
462
|
+
values: allItems.map(x => x.totalValue),
|
|
450
463
|
});
|
|
451
464
|
callData = encodeExecute(MULTICALL3, totalValue, data);
|
|
452
465
|
}
|
|
453
466
|
else {
|
|
454
|
-
// ERC20
|
|
455
|
-
|
|
456
|
-
const
|
|
457
|
-
|
|
467
|
+
// ✅ ERC20 模式:只转账 ERC20 代币(不包含 OKB prefund)
|
|
468
|
+
// 注意:buyer 需要自己有足够的 OKB 来支付 prefund,否则交易会失败
|
|
469
|
+
const allItems = profitItem && ch === chunks[0]
|
|
470
|
+
? [...ch, { ...profitItem, buyAmount: profitWei }]
|
|
471
|
+
: ch;
|
|
472
|
+
const targets = allItems.map(() => quoteToken);
|
|
473
|
+
const values = allItems.map(() => 0n);
|
|
474
|
+
const datas = allItems.map(x => erc20Iface.encodeFunctionData('transfer', [x.to, x.buyAmount]));
|
|
458
475
|
callData = encodeExecuteBatch(targets, values, datas);
|
|
459
476
|
}
|
|
460
477
|
const signedDisperse = await this.aaManager.buildUserOpWithState({
|