读取Uniswap v3池的slot0会同时看到sqrtPriceX96和tick。两者描述同一个价格位置,但精度不同:sqrtPriceX96保留当前价格的定点数,tick是以1.0001为底的对数向下取整。换算前还要先确认token0、token1与各自decimals。
| 输入 | 原始含义 | 常见误区 |
|---|---|---|
| sqrtPriceX96 | sqrt(token1/token0) × 2^96 | 忘记平方或2^96 |
| tick | floor(log₁.₀₀₀₁(price)) | 当作精确当前价 |
| decimals0/1 | 两种代币数量缩放 | 只给一边除10^decimals |
| 报价方向 | token1 per token0 | 需要反向时忘记取倒数 |
从sqrtPriceX96恢复原始比率
先用高精度数计算r = sqrtPriceX96 / 2^96,再平方得到原始整数单位的token1/token0。不要先转JavaScript Number,大值会丢精度。使用BigInt有理数或高精度十进制库,最后一步才做显示舍入。
decimals决定人类可读比例
原始比率比较两种最小单位。转换为完整代币价格时,需要乘以10^(decimals0-decimals1)。若想显示token0价值多少token1,这是正向;想显示token1价值多少token0,则对调整后的结果取倒数。代币符号不能替代地址与顺序。
tick适合定位区间
理论价格为1.0001^tick,但当前真实价格可能位于该tick到下一个tick之间,所以用tick算出的结果与sqrtPriceX96会略有差异。tickSpacing决定可初始化流动性边界,不等于当前价格只能停在这些整数倍。行情展示优先用sqrtPriceX96,区间逻辑再用tick。
换算公式的三个锚点
- sqrtPriceX96以Q64.96格式存储token1/token0价格平方根,原始价格可由(sqrtPriceX96 / 2^96)^2得到。
- tick i对应的离散价格为1.0001^i;当前tick是价格对数的向下取整,因此用sqrtPriceX96计算通常更精确。
- 转换为人类价格还必须按token0和token1的decimals缩放;反向报价取倒数,不能只换单位不换方向。
池内现价不是无限成交价
slot0价格只是池子当前状态,不等于可按该价格无限成交;真实交换会移动价格并产生价格影响。小流动性池还容易被瞬时操纵,不能把单块slot0直接当安全预言机。分析交易时应同时看流动性、观察窗口和成交规模。
链上价格换算自检
- 从池合约读取token0和token1地址
- 分别读取两种代币decimals
- 用高精度计算平方与2^192缩放
- 明确输出报价方向并做倒数校验
- 用tick结果做数量级交叉检查
代币地址先按合约地址核验确认,交易执行和日志可结合事件topics与data,仓位风险可参考Aave清算规则的动态参数思路。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。