在 Uniswap V3 协议纵览中,我们从宏观上理解了 V3 的核心思想,包括:
- 流动性不再分布在整个价格区间 (0,∞)
- 而是集中在一个有限区间 [plower,pupper] 内
- 并通过引入 virtual liquidity,使局部曲线仍然满足恒定乘积关系
(xR+xV)(yR+yV)=L2
然而,这个表达仍然是静态的。在真实的交易过程中,价格会不断变化,而流动性如何影响价格?资产数量如何随价格变化? 这些问题,都需要更精细的数学描述。
本章从 Liquidity 的角度出发,系统回答以下几个关键问题:
1. 不同价格位置下的资产状态
当价格 P 位于不同区间时:
- P<plower:只持有 token0
- plower<P<pupper:双边资产
- P>pupper:只持有 token1
我们将推导在不同状态下:
xR(P),yR(P)
2. 全局流动性与区间流动性
- global liquidity(当前价格处的有效流动性)
- liquidity net(跨 tick 的变化量)
理解为什么流动性是“分段变化”的。
3. 虚拟储备与真实储备
- 如何计算 xV,yV(虚拟资产)
- 如何计算 xR,yR(真实资产)
- 它们在不同价格区间中的含义
4. 流动性 L 的计算
- 如何根据 token 数量计算 L
- 如何根据 L 反推出 token 数量
- L 与价格的关系
通过这一章,我们将建立一个完整的认知在 Uniswap V3 中,价格的变化,本质上是由 liquidity 驱动的。 后续在分析 tick、swap、手续费计算等机制时, 这些公式将作为基础反复使用。
1. 不同价格位置下的资产状态
在 Uniswap V3 中,LP 提供的流动性只在区间 [plower,pupper] 内生效。 随着价格 P 的变化,LP 持有的资产结构会发生变化。

1.1 当 P>pupper(价格高于区间)

此时,价格已经完全穿过 LP 区间。
可以观察到:
- 所有流动性都表现为 token1(Y)
- token0(X)为 0
即:
xR=0,yR>0
LP 的 token0 已经全部被卖出,换成了 token1
1.2 当 P<plower(价格低于区间)

此时,价格离开 LP 的做市区间。
可以观察到:
- 所有流动性都表现为 token0(X)
- token1(Y)为 0
即:
xR>0,yR=0
从曲线上看,此时状态点停留在区间的左边界。LP 提供的是“等待被买入的 token0”
1.3 当 plower<P<pupper(价格在区间内)

此时,流动性处于 active 状态。
随着价格移动:
- token0(X)逐渐减少
- token1(Y)逐渐增加
即:
xR>0,yR>0
并且满足:
(xR+xV)(yR+yV)=L2
可以将流动性状态总结为三段:
⎩⎨⎧P<plowerplower<P<pupperP>pupper⇒(xR>0,yR=0)⇒(xR>0,yR>0)⇒(xR=0,yR>0)
流动性并不是“同时提供两种资产”,而是随着价格变化,在 token0 与 token1 之间不断转换。价格的移动,本质上是 LP 资产在 X 与 Y 之间的再分配过程。
2. 全局流动性与区间流动性
在 Uniswap V3 中,每一个 LP position 都只在区间 [plower,pupper] 内提供流动性。 然而,Pool 并不会逐个 position 去计算当前流动性,而是维护一个全局状态:
L=current active liquidity

在每一个 price(实际应该用 tick 表示,这里用 price 为了方便理解) 上,协议并不会存储完整的流动性分布,而是记录一个关键变量 liquidityNet。它表示当价格穿过该 price(tick) 时,全局流动性的净变化量。
当价格 P 发生变化时,Pool 会根据价格移动方向,对流动性进行更新:
2.1 当价格向右(上涨):

- p0
liquidity 为初始值, L=0
- p1 当 price 进入区间 [plower,pupper] 开始添加
liquidityNet,L+ΔL=0+ΔL=ΔL
- p2 当 price 继续上涨,向右移动到中间,当前
liquidity 仍然为区间内储存的 ΔL
- p3 当 price 上涨到 pupper 边界,已经离开区间。
liquidity 减少区间内的流动性,L=0
2.2 当价格向左(下降):

- p4
liquidity 为初始值, L=0
- p3 当 price 进入区间 [plower,pupper] 开始添加
liquidityNet,L+ΔL=0−(−ΔL)=ΔL
- p2 当 price 继续下降,向左移动到中间,当前
liquidity 仍然为区间内储存的 ΔL
- p0 当 price 下降到 plower 边界,已经离开区间。
liquidity 减少区间内的流动性,L=0
2.3 区间流动性的叠加

如果将多个 LP position 放在同一个价格轴上,可以得到如图所示的流动性分布。
当多个 position 叠加时:
-
在同一个价格区间内,流动性会累加
-
在边界处,流动性会发生跳变
-
p0: liquidity 为初始值,L=0
-
p1: 价格上涨,进入第一个流动性区间,开始添加 liquidityNet,L+100=100
-
p2: 继续移动,进入第二个区间,L+150=250
-
p3: 离开第二个区间,L−150=100
-
p4: 离开第一个区间,L−100=0
-
p5: 离开所有区间,liquidity = 0
因此,流动性是由一组分布在 price(tick) 上的 liquidityNet 决定。当价格 P 发生变化时,Pool 的行为可以抽象为在 tick 轴上沿价格方向进行一次扫描,并逐个应用 liquidityNet。
因此,全局流动性可以表示为:
L(P)=ticks crossed∑liquidityNet
3. 虚拟储备与真实储备
3.1 虚拟储备
在 V3 中区间流动性不再是全局分布,而是集中在有限区间内。但这段曲线本身并不是独立存在的,而是嵌入在一条更完整的 AMM 曲线之中。为了仍然维持连续且一致的价格函数,V3 引入了 virtual liquidity。其本质是在 x 和 y 方向引入偏移量x_virtual, y_virtual,将当前的真实状态 (x, y) 嵌入到一个更大的坐标系中,从而使该状态仍然落在一条完整的 AMM 曲线上。

在图片中我们可以看到:
因此,当 price 在区间内时,X 的真实储备是大于 0,且小于 x0 (若大于 x0 ,则是另外一个区间)
同理,Y 的真实储备也是大于 0,且小于 y0 (若大于 y0, 则是另外一个区间)
需要注意的是,xV 和 yV 并不是任意引入的偏移量。它们之所以能够被唯一确定,是因为它们本身仍然属于完整恒定乘积曲线上的坐标量,为了使当前真实状态 (xR,yR) 仍然落在一条完整的恒定乘积曲线上,我们要求:
(xR+xV)(yR+yV)=L2
其中,xV,yV 是需要求解的虚拟储备。
第一步:写出完整曲线上的坐标关系
对于完整曲线:
价格定义为:
联立可得:
X=PL,Y=LP
化简过程:
PL2=XYXY=X2=>X=PL
L2P=XY⋅XY=Y2=>Y=LP
这意味着,在价格为 P 时,完整曲线上的横纵坐标分别可以表示为以上公式。
第二步:利用边界条件求 xV (后续都用 PB 表示 P upper,PA 表示 Plower)
当价格达到上界 Pupper 时,该 position 已经完全转化为 token1,因此:
此时,完整曲线上的横坐标仅由虚拟部分构成,所以:
xV(yR+yV)=L2
xV=yR+yVL2
xV=LPBL2
xV=PBL
第三步:利用边界条件求 yV
当价格达到下界 Plower 时,该 position 已经完全转化为 token0,因此:
此时,完整曲线上的纵坐标仅由虚拟部分构成,所以:
(xR+xV)yV=L2
yV=xR+xVL2
yV=PALL2
yV=LPA
第四步:将 xV,yV 代入主方程,可得:
(xR+PBL)(yR+LPA)=L2
这就是 Uniswap V3 中 real reserves 与 virtual reserves 的核心关系式。
3.2 真实储备
在上一节中,我们通过引入虚拟储备,将当前状态 (xR,yR) 嵌入到完整曲线:
(xR+xV)(yR+yV)=L2
并求得:
xV=PBL,yV=LPA

当价格在区间内移动时:
- 价格上升(Plower→Pupper):
token0 被不断卖出
token1 不断增加
- 最终变为纯 y0(即 x0=0)
(0+PBL)(y0+LPA)=L2
化简:
PBL(y0+LPA)=L2
y0+LPA=LPB
最终得到:
y0=LP−LPA
- 价格下降(Pupper→Plower):
token1 被不断卖出
token0 不断增加
- 最终变为纯 x0(即 y0=0)
(x0+PBL)(0+LPA)=L2
化简:
(x0+PBL)PA=L2
x0+PBL=PAL
最终得到:
x0=PL−PBL
所以 x0 和 y0 是在区间两端,该 position 的“极限资产状态”。更重要的是,它们提供了将当前状态 (xR,yR) 与价格区间联系起来的边界条件。
总结
- virtual reserves:用于构造完整曲线
- real reserves:是当前价格下实际持有的资产
两者关系:
real=global curve−virtual offset
这也是 Uniswap V3 将“局部流动性”嵌入“全局 AMM”的核心方式。
4. 流动性 L 的计算
在上一节中,我们已经得到真实储备:
xR=PL−PBL,yR=LP−LPA
这说明在 Uniswap V3 中,token 数量并不是直接存储的,而是由 L 和价格共同决定。
因此,我们可以做两件事:
- 已知 token 数量,反推 L
- 已知 L,计算 token 数量
这两者本质上是同一组公式的不同变形。
4.1 由 Token 数量计算 Liquidity
已知用户希望在区间 [Plower,Pupper] 提供:
当前价格为 Pc
Case 1:Pc<PA(价格低于区间)
此时 position 完全是 token0:
L=x⋅PB−PAPA⋅PB
Case 2:PA≤Pc<PB(价格在区间内)
此时同时持有 token0 和 token1。
分别用两种 token 推导 liquidity:
L0=x⋅PB−PcPc⋅PB
L1=Pc−PAy
最终取较小值(确保两种 token 都能满足):
L=min(L0,L1)
Case 3:Pc≥PB(价格高于区间)
此时 position 完全是 token1:
L=PB−PAy
4.2 由 Liquidity 计算 Token 数量
已知:
-
L
-
PA,PB
- 当前价格 Pc
先计算:
Pc,PA,PB
Case 1:Pc<PA
全部为 token0:
amount0=L⋅(PA1−PB1)
amount1=0
Case 2:PA≤Pc<PB
同时持有两种 token:
amount0=L⋅(Pc1−PB1)
amount1=L⋅(Pc−PA)
Case 3:Pc≥PB
全部为 token1:
amount0=0
amount1=L⋅(PB−PA)
正如本节开头所说,在前文中我们已经得到:
xR=PL−PBL,yR=LP−LPA
可以看到:
- amount0 本质就是 xR
- amount1 本质就是 yR
Token 数量公式就是真实储备公式在不同价格区间的展开。
- virtual reserves:定义完整曲线的位置
- real reserves:定义当前持有的 token
- liquidity L:定义曲线的“尺度”
三者关系:
(xR+xV)(yR+yV)=L2
而 token 计算公式,只是这个关系在不同价格区间下的具体表现形式。
5. 流动性变化与 Token 的关系(ΔL)
-
L0=Liquiditybefore
-
L1=Liquidityafter
-
ΔL=L1−L0
Case 1: P≤PA

此时 position 完全由 token0 构成,当增加 token0(Δx)时,对应的流动性变化为:
L0=PA1−PB1x
L1=PA1−PB1x+Δx
ΔL=L1−L0=PA1−PB1Δx
在价格低于区间时:
- 只需要 token0 提供流动性
- 流动性的变化完全由 Δx 决定
Case 2:PB≤P)

此时 position 完全由 token1 构成。
L0=PB−PAy
L1=PB−PAy+Δy
ΔL=L1−L0=PB−PAΔy
在价格高于区间时:
- 只需要 token1 提供流动性
- 流动性的变化完全由 Δy 决定
Case 3:PA<P<PB

此时 token0 和 token1 都参与:
L0=P1−PB1x=P−PAy
L1=P1−PB1x+Δx=P−PAy+Δy
ΔL=L1−L0=P1−PB1Δx=P−PAΔy
通过以上三种情况可以看到:
- token0 对应的是 反价格空间(1/P)的线性变化
- token1 对应的是 价格空间(P)的线性变化
而 liquidity L,本质上是连接这两个空间的“统一度量”。