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

如何从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);
        }
    }
}

关键修正说明

  1. 接口替换:改用IUniswapV2Router02接口,确保能正确调用addLiquidityETH函数。
  2. 余额校验:添加require语句提前拦截余额不足的情况,避免无效执行。
  3. 授权验证:捕获并验证approve的返回值,确保授权操作生效。
  4. 流动性接收地址:默认将流动性发送给调用者(msg.sender),更符合实际使用场景,若需留存至合约可自行修改。
  5. 多余授权清理:可选步骤,撤销未使用的授权额度,减少安全风险并节省后续操作的gas。

内容的提问来源于stack exchange,提问作者Infected Mice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:17:38