Uniswap V3 Polygon链增流动性报错:missing revert data(ethers 6.12.0)
解决Uniswap V3 Polygon流动性计算报错及功能实现
错误根源
- 调用了V3不存在的
quote方法:quote是Uniswap V2的专属方法,V3采用集中流动性模型,需基于sqrtPriceX96和tick范围计算代币数量,而非V2的恒定乘积公式。 - Pool ID与Position Token ID混淆:你使用的
1597116是Uniswap的池ID,不是INonfungiblePositionManager合约中对应你持仓的NFT代币ID,无效ID触发合约回滚。 - Promise.all解构错误:原代码对异步调用结果的解构完全不符合实际返回结构,导致数据类型不匹配。
- 错误获取储备金:V3 Pool合约没有直接返回
token0Reserve/token1Reserve的接口,需通过价格和流动性参数间接计算。
修复步骤
1. 获取正确的Position Token ID
登录Uniswap网页端,进入你的WBTC/MATIC仓位页面,找到对应NFT的Token ID,替换代码中的tokenId变量。
2. 使用V3专属计算逻辑
利用V3合约的getLiquidityForAmount0和calculateAmountsForLiquidity方法,基于现有仓位的tick范围和当前池价格,精准计算对应代币数量。
3. 修正合约调用与数据解析
完整修复代码
const { ethers, JsonRpcProvider } = require('ethers'); const infuraKey = '你的Infura密钥'; const privateKey = '你的钱包私钥'; const INFURA_URL = `https://polygon-mainnet.infura.io/v3/${infuraKey}`; // 导入Uniswap V3合约ABI const { abi: IUniswapV3PoolABI } = require('@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json'); const { abi: INonfungiblePositionManagerABI } = require('@uniswap/v3-periphery/artifacts/contracts/interfaces/INonfungiblePositionManager.sol/INonfungiblePositionManager.json'); const provider = new JsonRpcProvider(INFURA_URL); const wallet = new ethers.Wallet(privateKey, provider); // WBTC/MATIC 0.05%手续费池地址 const poolAddress = '0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6'; const positionManagerAddress = '0xC36442b4a4522E871399CD717aBDD847Ab11FE88'; const poolContract = new ethers.Contract(poolAddress, IUniswapV3PoolABI, provider); const positionManagerContract = new ethers.Contract(positionManagerAddress, INonfungiblePositionManagerABI, wallet); async function main() { console.log("ethers.version: ", ethers.version); // 替换为你自己的仓位NFT Token ID const tokenId = 123456; // 示例ID,替换为实际值 // 要添加的WBTC数量(WBTC为8位小数) const wbtcAmountToAdd = ethers.parseUnits('0.0002', 8); // 获取仓位信息和池当前状态 const [position, slot0] = await Promise.all([ positionManagerContract.positions(tokenId), poolContract.slot0() ]); const { tickLower, tickUpper } = position; const { sqrtPriceX96 } = slot0; // 计算添加指定WBTC对应的流动性增量 const liquidityDelta = await poolContract.getLiquidityForAmount0( ethers.toBigInt(tickLower), ethers.toBigInt(tickUpper), wbtcAmountToAdd ); // 根据流动性增量计算所需WMATIC数量 const [_, amount1] = await positionManagerContract.calculateAmountsForLiquidity( sqrtPriceX96, ethers.toBigInt(tickLower), ethers.toBigInt(tickUpper), liquidityDelta ); console.log(`添加 ${ethers.formatUnits(wbtcAmountToAdd, 8)} WBTC 流动性,需要 ${ethers.formatUnits(amount1, 18)} WMATIC(可直接存入MATIC,合约自动转换)`); } main().catch((error) => { console.error(error); process.exit(1); });
注意事项
- WMATIC与MATIC:池内使用WMATIC,但存入时可直接用MATIC,PositionManager合约会自动完成兑换。
- Gas费:确保钱包有足够MATIC支付Gas费用。
- Tick范围:计算基于你现有仓位的tick区间,若创建新仓位需自行指定
tickLower和tickUpper参数。
内容的提问来源于stack exchange,提问作者user3206978
相关产品推荐
相关产品推荐

