基于Hardhat在Uniswap V3中铸造流动性头寸的实现问题
Uniswap V3 铸造流动性头寸的代币转账问题解决方案
你的问题核心是:Uniswap V3 Pool合约的mint方法不会自动处理代币转账,必须先完成代币授权,让Pool合约有权限从你的账户划转所需代币。下面给你两种可行方案:
方案一:直接操作Pool合约(手动处理授权)
要成功调用Pool的mint方法,必须先给Pool合约授权两种代币的划转权限,具体步骤如下:
给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));调用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
相关产品推荐
相关产品推荐

