Hardhat中调用UniswapV2 ETH相关兑换函数报错求助
Hardhat + Ethers 5.7.2 调用UniswapV2 Router ETH相关Swap函数报错排查与解决
核心问题定位
仅涉及ETH作为输入/输出的swapExactETHForTokens/swapExactTokensForETH函数报错,但ERC20代币间兑换(如swapExactTokensForTokens)正常,说明Uniswap Router基础调用逻辑无问题,错误集中在ETH的特殊处理逻辑上。
常见错误原因及解决方案
1. 调用swapExactETHForTokens时未附带ETH金额
swapExactETHForTokens是payable函数,调用时必须通过value参数传入对应ETH数量。Ethers 5.x中需在调用的overrides选项里明确指定:
错误示例:
// 未传入ETH金额,导致交易失败 await router.swapExactETHForTokens( amountOutMin, [WETH.address, token.address], recipient, deadline );
正确写法:
const ethAmount = ethers.utils.parseEther("0.1"); await router.swapExactETHForTokens( amountOutMin, [WETH.address, token.address], recipient, deadline, { value: ethAmount } // 必须指定value参数传递ETH );
2. swapExactTokensForETH路径错误或未完成代币授权
- UniswapV2用WETH替代原生ETH处理兑换,路径最后一位必须是WETH地址,不能用ETH零地址(
ethers.constants.AddressZero) - 调用前需确保已授权Router使用待兑换的ERC20代币
错误示例:
// 路径末尾用了ETH零地址,且未做代币授权 await router.swapExactTokensForETH( amountIn, amountOutMin, [token.address, ethers.constants.AddressZero], recipient, deadline );
正确写法:
// 先授权Router操作代币 await token.approve(router.address, amountIn); // 路径末尾使用WETH地址 await router.swapExactTokensForETH( amountIn, amountOutMin, [token.address, WETH.address], recipient, deadline );
3. 测试环境中WETH合约未正确部署/关联
UniswapV2 Router依赖WETH合约,若测试环境未部署WETH,或Router初始化时传入的WETH地址错误,会导致ETH相关兑换失败。
检查Router部署代码:
// 部署Router时必须传入正确的Factory和WETH地址 UniswapV2Router02 router = new UniswapV2Router02(factoryAddress, wethAddress);
在Hardhat测试脚本中,需确保WETH合约已提前部署,且地址正确传入Router实例。
4. 自定义合约内调用时未处理payable权限
如果是在你的自定义合约中调用Router的ETH相关函数,合约调用函数必须标记为payable,并将接收的ETH传递给Router:
错误示例:
// 函数未标记payable,无法接收ETH;调用Router时未传递value function swapETHForToken(uint amountOutMin, address token) external { address[] memory path = new address[](2); path[0] = WETH; path[1] = token; router.swapExactETHForTokens(amountOutMin, path, msg.sender, block.timestamp + 300); }
正确示例:
function swapETHForToken(uint amountOutMin, address token) external payable { address[] memory path = new address[](2); path[0] = WETH; path[1] = token; // 将接收的ETH传递给Router router.swapExactETHForTokens{value: msg.value}(amountOutMin, path, msg.sender, block.timestamp + 300); }
5. Gas限制不足
ETH相关兑换可能需要更多Gas,若默认Gas Limit不足会导致交易失败,可手动指定:
await router.swapExactETHForTokens( amountOutMin, path, recipient, deadline, { value: ethAmount, gasLimit: 300000 } // 手动设置Gas Limit );
错误日志排查方向
若以上方案未解决问题,提取错误日志关键词定位:
Insufficient ETH:检查调用时value参数是否正确,或调用方是否有足够ETHInvalid path:检查兑换路径是否正确,特别是WETH地址是否无误TransferHelper: TRANSFER_FROM_FAILED:检查ERC20代币授权金额是否足够
内容的提问来源于stack exchange,提问作者Eight
相关产品推荐
相关产品推荐

