如何从Solidity合约调用UniswapV2 Router的addLiquidityETH?代码报错求助
问题分析与修正代码
原代码的核心问题
- 接口不匹配:
addLiquidityETH是Uniswap V2 Router02的专属函数,原代码导入的IUniswapV2Router01接口中不存在该函数,直接调用会触发函数不存在的错误。 - 未验证授权结果:部分ERC20代币会返回布尔值表示授权是否成功,忽略该返回值可能导致授权失败后仍执行后续逻辑,最终因权限不足报错。
- 缺少余额校验:合约必须预先持有足够的目标代币,否则Uniswap Router无法从合约中转出代币,操作必然失败。
修正后的完整代码
pragma solidity ^0.8.0; import "./IUniswapV2Router02.sol"; import "./IERC20.sol"; contract MyContract { IUniswapV2Router02 public immutable uniswapRouter; address public immutable tokenAddress; constructor(address _router, address _tokenAddress) { uniswapRouter = IUniswapV2Router02(_router); tokenAddress = _tokenAddress; } function addLiquidityETH( uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity) { IERC20 token = IERC20(tokenAddress); // 校验合约代币余额是否充足 require(token.balanceOf(address(this)) >= amountTokenDesired, "Insufficient token balance"); // 授权Router并验证操作成功 bool approveSuccess = token.approve(address(uniswapRouter), amountTokenDesired); require(approveSuccess, "Token approval failed"); // 调用Uniswap的流动性添加函数,返回实际添加的代币、ETH数量及流动性份额 (amountToken, amountETH, liquidity) = uniswapRouter.addLiquidityETH{value: msg.value}( tokenAddress, amountTokenDesired, amountTokenMin, amountETHMin, msg.sender, // 将流动性发送给调用者,可根据需求改为address(this) deadline ); // 清理多余授权(可选,优化安全性与gas使用) uint remainingAllowance = token.allowance(address(this), address(uniswapRouter)); if (remainingAllowance > 0) { token.approve(address(uniswapRouter), 0); } } }
关键修正说明
- 接口替换:改用
IUniswapV2Router02接口,确保能正确调用addLiquidityETH函数。 - 余额校验:添加
require语句提前拦截余额不足的情况,避免无效执行。 - 授权验证:捕获并验证
approve的返回值,确保授权操作生效。 - 流动性接收地址:默认将流动性发送给调用者(
msg.sender),更符合实际使用场景,若需留存至合约可自行修改。 - 多余授权清理:可选步骤,撤销未使用的授权额度,减少安全风险并节省后续操作的gas。
内容的提问来源于stack exchange,提问作者Infected Mice
相关产品推荐
相关产品推荐

