You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Forge主网分叉测试失败但Anvil本地通过问题求助

问题分析与解决思路

核心原因:主网分叉与本地Mock的WETH合约差异

本地测试用的是自定义Mock WETH,你可以调用mint直接给地址增发WETH;但主网分叉环境连接的是真实主网WETH合约,它没有公开的mint方法——真实WETH只能通过deposit()存入ETH来兑换,或者从其他地址转账获得。你的测试代码里的weth.mint(mintAmount, guardian)在主网分叉环境下完全无效,导致guardian地址的WETH余额为0,调用safeTransferFrom时因余额不足触发EVM错误,且因为是调用主网合约,错误日志没有详细回滚信息。

具体解决步骤

1. 替换主网分叉环境的WETH mint逻辑

把测试里的weth.mint改成主网WETH支持的方式:给guardian地址转入ETH,然后调用WETH的deposit()生成WETH:

function testBecomeGuardianNoUniswap() public {
    // 给guardian转ETH,用来兑换WETH
    vm.deal(guardian, mintAmount);
    vm.startPrank(guardian);
    // 调用主网WETH的deposit,把ETH换成WETH
    weth.deposit{value: mintAmount}();
    weth.approve(address(vaultGuardians), mintAmount);
    address wethVault = vaultGuardians.becomeGuardian(noUniswapAllocationData);
    vm.stopPrank();   
}

2. 增加调试日志,明确错误原因

在测试中加入余额、授权的检查,提前排查问题:

function testBecomeGuardianNoUniswap() public {
    vm.deal(guardian, mintAmount);
    vm.startPrank(guardian);
    weth.deposit{value: mintAmount}();
    // 打印guardian的WETH余额
    console.log("Guardian WETH balance:", weth.balanceOf(guardian));
    weth.approve(address(vaultGuardians), mintAmount);
    // 打印授权额度
    console.log("Approved amount:", weth.allowance(guardian, address(vaultGuardians)));
    address wethVault = vaultGuardians.becomeGuardian(noUniswapAllocationData);
    vm.stopPrank();   
}

运行测试时用-vvvv参数,就能看到日志输出,确认余额和授权是否正常。

3. 验证主网WETH的调用权限

主网WETH的transferFrom是标准ERC20实现,但要注意:

  • 确保guardian的WETH余额 ≥ s_guardianStakePrice
  • 确保授权额度 ≥ s_guardianStakePrice
  • 如果s_guardianStakePrice是动态值,打印出来确认数值是否符合预期

4. 强制捕获主网合约的错误

如果还是看不到详细错误,可以用try/catch包裹调用,打印原始错误数据:

vm.startPrank(guardian);
weth.deposit{value: mintAmount}();
weth.approve(address(vaultGuardians), mintAmount);
try vaultGuardians.becomeGuardian(noUniswapAllocationData) returns (address wethVault) {
    // 成功逻辑
} catch (bytes memory reason) {
    console.logBytes(reason); // 打印原始错误数据
}
vm.stopPrank();

对疑问的解答

  1. 为什么safeTransferFrom在主网分叉无提示失败?
    因为主网分叉调用的是真实合约,safeTransferFrom底层调用主网WETH的transferFrom,如果余额不足,主网WETH会revert但没有自定义错误信息(早期ERC20合约很多用revert字符串而非自定义错误),Foundry在分叉环境下可能不会自动解析这类原始revert信息,导致只显示通用EVM错误。

  2. 是主网分叉与mock的初始化差异吗?
    完全是这个原因:本地Mock WETH是你自己实现的,有mint方法可以直接增发;但主网WETH是真实合约,没有公开的mint权限,你的测试代码在分叉环境下没有正确给测试地址生成WETH,导致后续转账失败。

是否需要补充调试步骤?

非常有必要,建议补充:

  • 测试地址的WETH余额检查
  • 授权额度检查
  • s_guardianStakePrice的数值打印
  • 用try/catch捕获原始错误数据

内容的提问来源于stack exchange,提问作者NOS Magical

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 10:25:19