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

基于Hardhat在Uniswap V3中铸造流动性头寸的实现问题

Uniswap V3 铸造流动性头寸的代币转账问题解决方案

你的问题核心是:Uniswap V3 Pool合约的mint方法不会自动处理代币转账,必须先完成代币授权,让Pool合约有权限从你的账户划转所需代币。下面给你两种可行方案:

方案一:直接操作Pool合约(手动处理授权)

要成功调用Pool的mint方法,必须先给Pool合约授权两种代币的划转权限,具体步骤如下:

  1. 给Pool合约授权ERC20代币
    先获取两种代币的ERC20合约实例,调用approve方法授权Pool合约可以划转的金额(金额需大于等于你要添加的流动性对应的代币数量):

    // 获取代币合约实例
    const tokenA = await ethers.getContractAt("ERC20", "0x40a42Baf86Fc821f972Ad2aC878729063CeEF403");
    const tokenB = await ethers.getContractAt("ERC20", "0x4bf010f1b9beDA5450a8dD702ED602A104ff65EE");
    const poolAddress = await factory.getPool(tokenA.address, tokenB.address, 500);
    
    // 授权代币A给Pool合约(示例授权100个代币,根据实际需求调整)
    await tokenA.connect(signer).approve(poolAddress, ethers.utils.parseUnits("100", 18));
    // 授权代币B给Pool合约
    await tokenB.connect(signer).approve(poolAddress, ethers.utils.parseUnits("100", 18));
    
  2. 调用Pool的mint方法
    授权完成后,再执行你之前的mint代码即可,此时Pool合约会通过transferFrom自动从你的账户划转所需代币,完成流动性铸造:

    await pool.connect(signer).mint(signer.address, -20, 20, 10000000, []);
    

    注意:确保你传入的流动性金额(10000000)对应的代币数量不超过授权金额,否则会因代币不足失败。

方案二:更优方案——使用Uniswap V3 Router合约

直接操作Pool合约需要手动计算代币数量、处理授权,容易出错。推荐使用Uniswap V3 Router合约(如UniswapV3Router02),它会封装所有复杂逻辑,包括授权、转账、滑点控制等,只需调用一次mint即可完成:

// 获取Router合约实例(主网地址为0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45,测试网地址需自行确认)
const router = await ethers.getContractAt("UniswapV3Router02", routerAddress);

// 组装mint参数
const mintParams = {
  token0: "0x40a42Baf86Fc821f972Ad2aC878729063CeEF403",
  token1: "0x4bf010f1b9beDA5450a8dD702ED602A104ff65EE",
  fee: 500,
  tickLower: -20,
  tickUpper: 20,
  amount0Desired: ethers.utils.parseUnits("100", 18), // 你愿意提供的tokenA数量
  amount1Desired: ethers.utils.parseUnits("100", 18), // 你愿意提供的tokenB数量
  amount0Min: ethers.utils.parseUnits("95", 18), // 滑点控制:允许的最小tokenA数量(建议设为期望数量的95%)
  amount1Min: ethers.utils.parseUnits("95", 18), // 滑点控制:允许的最小tokenB数量
  recipient: signer.address,
  deadline: Math.floor(Date.now() / 1000) + 60 * 10 // 交易截止时间(10分钟后过期)
};

// 调用Router的mint方法,自动处理授权和转账
await router.connect(signer).mint(mintParams, { gasLimit: 3000000 });

使用Router无需提前给Pool授权,它会自动完成授权逻辑,同时还能通过amount0Min和amount1Min控制滑点,避免因价格波动导致损失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:30:53