使用calculateComputedFee函数时computedFee数值过小的问题排查
Uniswap V3 手续费计算结果过小的问题排查
核心问题分析
你的计算结果异常偏小,根源在于流动性单位不匹配和流动性计算公式错误,具体如下:
1. 流动性单位完全不匹配
你代码中existingLiquidity使用的是美元计价的流动性数值,但Uniswap V3合约中的liquidity是经过数学缩放的原始数值(与token数量、价格平方根相关),两者无法直接做比例计算,这会导致userTotalLiquidity / (existingLiquidity + userTotalLiquidity)的比例趋近于0,最终手续费结果极小。
2. 流动性计算公式错误
你直接使用X96编码的sqrtRatioAX96/sqrtRatioBX96进行计算,但这些数值是放大了2^96倍的编码值,未解码就参与运算会导致流动性计算结果异常偏小。同时,当前价格在区间内时的流动性计算逻辑也不符合Uniswap V3的规则。
3. Token数量单位错误
token0是ETH(小数位数18),token1是USDC(小数位数6),你代码中amount0和amount1的计算逻辑混淆了token的计价方向:
amount0应该是ETH的数量((depositAmount/2)/ethPrice),而非美元金额amount1应该是USDC的数量(depositAmount/2),而非ETH数量
修正后的代码实现
function calculateComputedFee(){ const feeTier = 0.003; const volumeUSD = 6631238.50; // 注意:此处需替换为从Uniswap V3合约读取的原始liquidity值(非美元计价) // 可通过Etherscan查看合约0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8的liquidity字段 const existingLiquidity = 123456789; const depositAmount = 1000; // 美元 const ethPrice = 1800; // USDC/ETH 价格 const amount0 = (depositAmount / 2) / ethPrice; // 存入的ETH数量 const amount1 = depositAmount / 2; // 存入的USDC数量 // 价格区间(USDC/ETH) const Pa = 1649.0832769175609; const Pb = 1974.6659682730651; const sqrtPa = Math.sqrt(Pa); const sqrtPb = Math.sqrt(Pb); const currentPrice = 1870.5962643293298; // 当前USDC/ETH价格 // 计算用户实际流动性 let userLiquidity; if (currentPrice <= Pa) { // 价格低于区间下限,仅用token0计算流动性 userLiquidity = amount0 * sqrtPb * sqrtPa / (sqrtPb - sqrtPa); } else if (currentPrice >= Pb) { // 价格高于区间上限,仅用token1计算流动性 userLiquidity = amount1 / (sqrtPb - sqrtPa); } else { // 价格在区间内,分别计算两种token对应的流动性并取最小值 const liquidity0 = amount0 * sqrtPb * Math.sqrt(currentPrice) / (sqrtPb - Math.sqrt(currentPrice)); const liquidity1 = amount1 / (Math.sqrt(currentPrice) - sqrtPa); userLiquidity = Math.min(liquidity0, liquidity1); } // 计算手续费 const computedFee = feeTier * volumeUSD * (userLiquidity / (existingLiquidity + userLiquidity)); console.log(computedFee); }
关键注意事项
- 获取正确的existingLiquidity:必须从Uniswap V3合约中读取原始
liquidity值,而非美元计价的流动性。可通过Etherscan或Uniswap SDK获取目标合约的该字段。 - X96编码值处理:如果使用合约返回的
sqrtRatioX96,需先通过sqrtPrice = sqrtRatioX96 / 2^96解码为实际平方根价格,再参与计算。 - Token精度:若处理最小单位(wei),需注意ETH(18位小数)和USDC(6位小数)的精度转换,避免数值溢出或精度丢失。
内容的提问来源于stack exchange,提问作者ethereum
相关产品推荐
相关产品推荐

