Uniswap V3 第1章 简介:集中流动性与 V2 的根本区别

介绍 Uniswap V3 的核心创新——集中流动性,讲清它与 V2 的根本区别、tick 与价格区间的概念,以及合约架构。

5 分钟阅读
Uniswap V3 第1章 简介:集中流动性与 V2 的根本区别

Uniswap V3 第 1 章:简介——集中流动性(Concentrated Liquidity)

Uniswap V3 最核心的创新只有一个词:集中流动性(concentrated liquidity)。理解了它,V3 的一切(tick、sqrtPriceX96、NFT 头寸、费用追踪)都顺理成章。这一章用通俗的语言讲清它解决什么问题、和 V2 的根本区别,以及合约架构概览。


目录


1. V2 的痛点:资金利用率太低

回忆 V2 的恒定乘积 x·y=k:流动性均匀分布在 0 到 ∞ 的所有价格上

问题来了:对一个稳定币对(比如 USDC/DAI),价格几乎永远在 0.99~1.01 之间波动。但 V2 把你的钱也铺在了”1 USDC = 5 DAI”或”1 USDC = 0.2 DAI”这种永远不会发生的价格上。

结果:你的绝大部分资金都是闲置的,只有极小一部分真正在当前价格附近提供深度。资本效率极低。


2. V3 的答案:把流动性集中到价格区间

V3 让 LP 自己选择一个价格区间 [Pa, Pb],只在这个区间内提供流动性。

  • 你认为 ETH 会在 2800~3200 美元之间波动?就把流动性全集中在这个区间。
  • 在这个区间内,你的钱提供的深度远超 V2 里同样金额铺满全价格的深度。
  • 代价:如果价格走出你的区间,你的头寸会变成单一资产,且不再赚手续费(直到价格回来)。

这就像 V2 是”撒胡椒面”(铺满全场),V3 是”精准下注”(集中在你看好的区间)。


3. 案例:同样的钱,V3 深度高几十倍

假设你有 10,000 美元做 ETH/USDC 的 LP,当前 ETH=3000。

  • V2:钱铺在 0~∞,当前价附近实际可用的深度很薄。
  • V3,区间 [2700, 3300](±10%):同样 10,000 美元,全部集中在这个窄区间,当前价附近的深度可能是 V2 的 几十倍

资本效率提升的倍数大致与”区间收窄的程度”成正比。区间越窄,同样的钱深度越高、手续费收入越多——但价格走出区间的风险也越大。这是 V3 LP 的核心权衡:收益 vs 区间风险

极端情况:把区间设到极窄(接近一个点),就像在做”限价单”——这也是 V3 能模拟挂单的原因。


4. tick:价格的离散刻度

V3 不允许任意实数价格,而是把价格离散成一个个 tick(刻度)。定义:

价格 P(i) = 1.0001^i      (i 就是 tick 序号,可正可负)
  • 相邻两个 tick 的价格差正好 0.01%(1.0001 倍)。
  • tick 是整数,价格区间的端点 Pa、Pb 必须落在 tick 上。
  • tick = 0 对应价格 1;tick = 1 对应 1.0001;tick = -1 对应 1/1.0001。

为什么用 1.0001^i?因为它让”价格的对数”变成等间距的整数,便于在链上高效地索引、跨越和计算流动性区间(后面 tick bitmap 会用到)。


5. V2 vs V3 对照

维度Uniswap V2Uniswap V3
流动性分布全价格 0~∞ 均匀LP 自选区间 [Pa,Pb] 集中
资本效率高(窄区间可达几十~几千倍)
同对池子数唯一费率档位多个(0.01%/0.05%/0.3%/1%)
LP 凭证同质化 ERC20(LP token)非同质化 NFT(每个头寸独立)
价格表示reserve 比例tick + sqrtPriceX96
价格走出区间不存在该概念头寸变单一资产、停止赚费
手续费自动复利进池单独累计,需手动 collect

6. 头寸变成 NFT

V2 里所有 LP 的份额是同质的(都是同一种 LP token)。但 V3 里每个人的区间 [Pa,Pb] 不同,无法用同质化代币表示

所以 V3 把每个流动性头寸做成一个 NFT(通过 NonfungiblePositionManager):

  • 每个 NFT 记录:区间 [tickLower, tickUpper]、流动性 L、未领取的手续费。
  • 你可以增加/减少流动性、领取手续费、转让整个头寸(转 NFT)。

7. 合约架构概览

合约作用
UniswapV3Factorycore按 (tokenA, tokenB, fee) 创建池子;管理费率档位与 tickSpacing
UniswapV3Poolcore池子本体:swap、mint/burn/collect、tick 与费用追踪、价格预言机
NonfungiblePositionManagerperiphery把头寸包装成 NFT,面向 LP 的主要入口
SwapRouter02periphery面向交易者:单池/多池、定输入/定输出兑换
Quoterperiphery链下报价(模拟 swap)

和 V2 一样是 core(安全、最小)+ periphery(方便、面向用户) 的分层,但 V3 的 core 复杂得多(要管理 tick、区间、费用)。


8. 本章小结

  1. V2 把流动性铺满全价格 → 资本效率低;V3 让 LP 自选区间集中流动性 → 效率高几十倍以上。
  2. 代价:价格走出区间则头寸变单一资产、停止赚费——收益与区间风险的权衡。
  3. tick:价格离散为 P(i)=1.0001^i,相邻 tick 差 0.01%,便于链上索引。
  4. 同一对代币按费率档位(0.01/0.05/0.3/1%)有多个池子。
  5. 每个头寸是一个 NFT(区间不同无法同质化),由 NonfungiblePositionManager 管理。
  6. 架构:Factory / Pool(core)+ PositionManager / SwapRouter / Quoter(periphery)。

9. 动手练习

目标:直观感受 tick 与价格的换算。

练习:tick ↔ price 换算

写一个脚本或 Foundry 测试:

  1. 实现 price = 1.0001^tick,分别算 tick = 0, 1, -1, 10000, -10000 对应的价格。
  2. 反过来:给定价格 P,求 tick = log(P) / log(1.0001),向下取整。
  3. 验证:tick=10000 对应价格 ≈ 1.0001^10000 ≈ 2.718(接近 e,因为 1.0001^10000 ≈ e^(10000·0.0001) = e^1)。
  4. (进阶)链上读一个真实 V3 池的 slot0().tick,用上面公式换算成价格,和市场价对比(注意 token0/token1 顺序和精度,下一章细讲)。
interface IUniswapV3Pool {
    function slot0() external view returns (
        uint160 sqrtPriceX96, int24 tick, uint16, uint16, uint16, uint8, bool
    );
}

运行

forge test --evm-version cancun --fork-url $FORK_URL \
  --match-path test/UniswapV3Intro.t.sol -vvv

下一章(第 2 章 现货价)讲 V3 独特的价格存储方式:slot0sqrtPriceX96tick 三者怎么互相换算,以及为什么存”价格的平方根”。

💬 评论