我们的目标是推导基于区间真实储备的恒定乘积公式,其形式如下:
L2=(xr+puL)(yr+Lpl)
并以此为基础,还原我们在上一章中得出的一些公式。
本章为选读内容。与前几章相比,它没有引入任何本质上的新概念,而是提供了一个通过价格和流动性推导真实储备的不同视角。跳过本章不会对阅读本书其余部分产生任何影响。
Uniswap 是一个恒定乘积自动做市商 (Constant Product Automated Market Maker)。在 Uniswap v2 中,如果忽略手续费,池中的代币兑换 (swap) 遵循公式 xy=k 中常数 k 保持不变的规则,其中 x 和 y 代表池中代币 X 和代币 Y 的储备量。从这个意义上说,可以说是公式 xy=k 定义了池中的代币兑换行为。
Uniswap v3 也是一个恒定乘积 AMM,主要区别在于池子不具有恒定的流动性,而是由多个曲线片段 (curve segments) 组成,每个片段都有特定的流动性 L。

在每个片段中,代币兑换的行为与 Uniswap v2 相同,在忽略手续费的情况下,只要兑换没有跨越该片段的边界,就必须保持公式 L2=xy 中的值 L 恒定。
因此,控制片段内代币兑换的公式仍然是 L2=xy。然而,与 Uniswap v2 不同的是,x 和 y 并不是该片段的真实储备,而是其虚拟储备 (virtual reserves),即如果该片段延伸为一条无限曲线时所具有的储备量(参见关于真实储备和虚拟储备的章节)。
人们可能会问,一个片段的恒定乘积公式 L2=xy 能否用该片段的真实储备而不是虚拟储备来表达。答案是肯定的。事实上,这个公式可以在 Uniswap v3 白皮书的第 2 页找到,如下所示(这里的 x 和 y 表示真实储备,在我们的符号体系中表示为 xr 和 yr)。这与我们在引言中展示的公式是同一个。

上述公式确立了流动性、片段边界和真实储备之间的关系。在我们的符号体系中,该公式应写为:
L2=(xr+puL)(yr+Lpl)
其中 pl 是 lower tick 处的价格,pu 是 upper tick 处的价格,而 L 是流动性。
对于一个给定的片段,这些值是固定的,而真实储备是变化的。这与 Uniswap v2 类似,在 k=xy 中流动性 k 是固定的,而储备 x 和 y 可以改变。在以上两种情况中,公式都约束了可能的储备值——如果一种代币的储备增加,另一种代币的储备就必须减少,从而保持流动性恒定。
通过下方的交互式工具可以更好地对这个概念进行可视化。你可以选择 upper tick、lower tick、片段的流动性以及当前价格。随着价格的变动,真实储备 xr 和 yr 会发生变化,但它们的变化方式会使流动性 L 保持恒定。换句话说,真实储备之间的比例并不是任意的,而是完全由流动性和 tick 边界所决定的。
v2 和 v3 之间的一个主要区别在于,在 v3 中,其中一种代币的储备可以降至零,而另一种代币的储备不需要趋向于无穷大。在某个片段中耗尽一种代币的真实储备是很正常的现象,此时价格将移动到下一个片段。
值得注意的是,恒定乘积公式并没有出现在代码库中。在 Uniswap v2 中,协议可以在代币兑换中简单地强制执行恒定乘积公式。然而在 v3 中,由于价格在一次兑换过程中可能会穿过多段曲线片段,因此情况要复杂得多。
尽管如此,恒定乘积公式仍可用于推导基于片段边界、流动性和当前价格的真实储备表达式。我们已经在上一章通过其他方法推导出了这些公式,正因如此,本章是选读内容。
不过,如果读者希望了解恒定乘积公式的由来,以及如何使用它来计算一个片段的真实储备,那么这正是本章的目的,欢迎继续阅读。
关联片段中的真实储备与虚拟储备
片段的恒定乘积公式与 Uniswap v2 中相同,
但现在的 x 和 y 代表的是虚拟储备。
如果我们能找到一种将虚拟储备与真实储备关联起来的方法,我们就可以推导出真实储备的恒定乘积公式。
请看下面的图示,其中 pl 是 lower tick 处的价格,pu 是 upper tick 处的价格。

在上面的图像中,我们有:
- (x,y) 是当前价格下的虚拟储备,
- yl 是价格为 pl 时代币 Y 的虚拟储备——即如果该片段是无限曲线且价格处于 pl 时,该片段所拥有的代币 Y 的数量。然而,相对于它的字面含义,我们对其在几何学上的意义更感兴趣,
- xu 是价格为 pu 时代币 X 的虚拟储备,
- (xr,yr) 是该片段的真实储备。
那么虚拟储备与真实储备之间的关系可表示为:
yx=yl+yr=xu+xr
我们可以在 L2=xy 中应用这些关系,通过代入 x 和 y,得到:
L2=(xu+xr)(yl+yr)
在一个片段内,xr 和 yr 在代币兑换期间可能会发生变化,但 xu 和 yl 仅取决于片段边界,因此对于该片段来说它们是常数。因此,只要能够求得 xu 和 yl,我们就找到了所需的公式。在上一章中我们推导出了获取 xu 和 yl 的公式,而在下一节中,我们将使用这些公式推导真实储备的恒定乘积公式。
真实储备的恒定乘积公式
在关于真实储备和虚拟储备的章节中,我们学习了如何通过价格和流动性求出片段的虚拟储备:x=L/p 和 y=Lp。我们可以使用这些公式计算 xu 和 yl,如下所示:
xuyl=puL=Lpl
使用这些值,我们可以将恒定乘积公式
L2=(xr+xu)(yr+yl)
写为:
L2=(xr+puL)(yr+Lpl)
该公式适用于流动性为 L、lower tick 为 pl 且 upper tick 为 pu 的片段。
现在,我们有了一个关联流动性、真实储备和片段边界的恒定乘积公式,且该公式不再涉及任何虚拟储备。
请注意,根据真实储备计算片段的流动性并不直观,因为上述公式在等式两边都包含参数 L;这是一个关于 L 的一元二次方程。
在实际应用中,我们无需担心这个问题,因为协议不使用上述公式来计算流动性。相反,协议存储了关于流动性的信息,并根据给定的流动性,计算两个价格之间代币 X 和 Y 的真实储备。
因此,我们关心的是找到一个公式,以便根据片段的流动性、边界和当前价格来计算 xr 和 yr。
在上一章中,我们已经在不涉及恒定乘积公式的情况下推导出了这些公式——正如引言中所述,恒定乘积公式对此并非必不可少。
出于教学目的,我们将使用恒定乘积公式重新推导上一章的公式。核心观点在于,尽管恒定乘积公式没有用在代码库中,但根据当前价格、流动性和片段边界计算真实储备的公式确实在代码库中得到了使用,而这些公式又可以通过恒定乘积公式推导出来。
为了演示这一点,我们将针对三种可能的情况进行推导:
- 当当前价格等于或低于 lower tick 时,片段中仅有代币 X 的真实储备;
- 当当前价格等于或高于 upper tick 时,片段中仅有代币 Y 的真实储备;
- 当当前价格位于片段区间内时,片段中同时具有代币 X 和代币 Y 的真实储备。
让我们从当前价格等于或低于 lower tick 的情况开始
1. 片段中仅有代币 X
在片段中只有代币 X 的场景下,yr 等于零,我们可以从恒定乘积公式中推导出 xr,如下所示:
L2L2plLxr=(xr+puL)(0+Lpl)=(xr+puL)Lpl=(xr+puL)=plL−puL等式两边同时除以 Lpl将 puL 移到等式另一边
请注意,这与我们在上一章推导的公式完全相同。
现在让我们考虑片段中仅包含代币 Y 的情况——即当前价格等于或高于 upper tick 时。
2. 片段中仅有代币 Y
在片段中只有代币 Y 的场景下,xr 等于零,我们可以从恒定乘积公式中推导出 yr,如下所示:
L2L2Lpuyr=(0+puL)(yr+Lpl)=puL(yr+Lpl)=yr+Lpl=Lpu−Lpl等式两边同时乘以 Lpu将 Lpl 移到等式另一边
请注意,这同样与我们在上一章推导的公式完全相同。
现在我们转向最后一种情况,即价格位于 lower tick 和 upper tick 之间。
3. 片段中同时存在两种代币
当价格位于 lower tick 和 upper tick 之间时,该片段中将同时具有代币 X 和代币 Y。
恒定乘积公式
L2=(xr+puL)(yr+Lpl)
并不包含当前价格,我们也无法仅凭它来计算 xr 和 yr。请注意,我们有两个未知数(xr 和 yr),但只有一个方程式。为了解决这个问题,我们需要另一个方程。
我们知道,虚拟储备计算价格的公式是 p=y/x。因此,如果转换为真实储备,我们有:
p=xy=xr+puLyr+Lpl
现在我们有了两个方程(恒定乘积公式和价格公式)和两个未知数(xr 和 yr)。我们可以将价格公式进行重排:
pyr+Lpl=xr+puLyr+Lpl=p(xr+puL)
左侧的项刚好存在于恒定乘积公式中,因此我们能够将其代入其中。
L2L2L2LpLxr=(xr+puL)(yr+Lpl)=(xr+puL)p(xr+puL)=(xr+puL)2p=(xr+puL)p=xr+puL=pL−puL替换了 (yr+Lpl)求平方根等式两边同时除以 p
现在我们得出了 xr,可以将这个表达式应用到恒定乘积公式中以求得 yr:
L2L2L2L2Lpyr=(xr+puL)(yr+Lpl)=(pL−puL+puL)(yr+Lpl)=(pL−puL+puL)(yr+Lpl)=(pL)(yr+Lpl)=yr+Lpl=Lp−Lpl代入 xr等式两边同时乘以 Lp
xr 和 yr 的公式与我们在上一章推导得出的完全相同。
总结
在 lower tick pl 和 upper tick pu 之间,流动性为 L 的片段的恒定乘积公式如下:
L2=(xr+puL)(yr+Lpl)
其中 xr 和 yr 代表代币 X 和代币 Y 的真实储备。