Rinkeby测试网UniswapV2克隆Router合约调用Gas估算执行回退问题
报错信息
Gas estimation error - execution reverted,原始错误详情:
{ "originalError": { "code": 3, "data": "0xfb7f5079", "message": "execution reverted" } }
错误选择器
0xfb7f5079和合约内定义的SafeTransferFailed()自定义错误完全匹配,所有报错函数都涉及代币转账逻辑,问题100%出在资产转移相关链路。
根因排查
按触发概率从高到低排序:
- 缺失前置授权:调用Router的addLiquidity、swap、removeLiquidity函数前,没有给Router地址授予对应资产的转账权限。
transferFrom是第三方代转操作,必须由资产持有者提前执行approve(Router地址, 转账金额)授权,否则代币合约会直接拒绝转账,触发SafeTransferFailed报错。 - Pair合约swap调用签名不匹配:标准UniswapV2 Pair的swap函数签名为
swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data),当前代码中调用swap仅传了3个参数,缺失最后一个bytes类型参数,会导致调用时参数错位,执行回退。 - pairFor地址计算错误:KswapLibrary中计算Pair地址用的init code hash和Factory合约实际部署Pair的字节码哈希不匹配,导致代币被转到不存在的错误地址,后续调用Pair合约方法时失败。
- ERC20兼容性问题:如果测试用的是带转账扣税、不返回bool值的非标准ERC20代币,当前_safeTransferFrom的判断逻辑可能误判转账失败,或者实际到账金额和计算值不符,触发后续逻辑回退。
修复方案
- 补全前置授权逻辑:所有涉及Router代转资产的操作前,必须先完成对应资产的授权:
- 加流动性/兑换:授权Router操作两种ERC20代币的转账权限
- 移除流动性:授权Router操作LP代币的转账权限
授权交易确认上链后,再调用Router的对应功能函数。
- 修正swap函数调用:给IKswapPair接口的swap方法补上第四个bytes参数,同时修改_swap内的调用逻辑,传入空字节即可:
// 接口定义修正 function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; // _swap函数内调用修正 IKswapPair( KswapLibrary.pairFor(address(factory), input, output) ).swap(amount0Out, amount1Out, to, new bytes(0)); - 校验Pair地址计算逻辑:从Factory合约中读取已部署的Pair地址,和KswapLibrary.pairFor计算出的地址做比对,如果不一致,替换Library中pairFor使用的init code hash为本地编译Pair合约生成的字节码哈希,不要直接使用Uniswap官方的默认哈希值。
- 测试阶段优先用标准ERC20代币(比如自己部署的无手续费、标准返回值的测试ERC20)做功能验证,排除代币兼容性问题后再接入主流非标准代币。
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

