10UniswapV3流动性计算

核心摘要 (Key Takeaways)

  • Uniswap V3 的核心创新:通过引入价格区间 p[pa,pb]p \in [p_a, p_b]虚拟流动性 (xvirtualx_{virtual}, yvirtualy_{virtual}) 的概念,实现了集中流动性,允许用户将资金集中在特定价格范围,从而极大地提高了资金效率。
  • V3 核心公式:V3 的流动性计算公式是 V2 中 xy=L2x \cdot y = L^2 的演进,具体形式为 (xreal+Lpb)(yreal+Lpa)=L2(x_{real} + \frac{L}{\sqrt{p_b}}) \cdot (y_{real} + L\sqrt{p_a}) = L^2。这个公式是理解 V3 机制的关键。
  • 资金效率与价格区间的关系:用户设定的价格区间 [pa,pb][p_a, p_b] 越窄(即 pap_a 越大,pbp_b 越小,两者越接近),提供的虚拟流动性就越大。这意味着可以用更少的真实资金(xrealx_{real}, yrealy_{real})达到与 V2 相同的流动性深度(L 值),即资金效率越高。
  • 模拟限价订单:利用价格区间特性,用户可以通过在价格区间的某一端点(如 pap_a)存入单一资产,当市场价格穿过整个区间到达另一端点(pbp_b)时,该资产会被完全兑换成另一种资产,从而实现类似限价订单的效果。

1. Uniswap V3 核心概念回顾

1.1 集中流动性与虚拟流动性

  • Uniswap V2: 流动性平均分布在 $(0, +∞)` 的整个价格曲线上。
  • Uniswap V3: 引入了价格区间 [pa,pb][p_a, p_b] 的概念,允许流动性提供者(LP)将资金集中在他们认为最可能发生交易的价格范围内。
  • 虚拟流动性 (Virtual Liquidity): 为了在有限的价格区间 [pa,pb][p_a, p_b] 内构建出一条标准的 xy=kx \cdot y = k 曲线,V3 引入了虚拟的 xy 资产(xvirtualx_{virtual}yvirtualy_{virtual})。
    • 这些虚拟资产仅用于数学计算,并不需要用户真实提供。
    • 用户实际提供的资产被称为真实流动性 (Real Liquidity)xrealx_{real}yrealy_{real})。
    • 总流动性 = 真实流动性 + 虚拟流动性。
      • 总 X: xtotal=xreal+xvirtualx_{total} = x_{real} + x_{virtual}
      • 总 Y: ytotal=yreal+yvirtualy_{total} = y_{real} + y_{virtual}

2. Uniswap V3 核心公式推导

2.1 基础关系:确定 X, Y, L, P 的关系

  1. 基础恒定乘积公式:

    xy=k=L2 x \cdot y = k = L^2

    其中 LL 代表流动性 (Liquidity)。

  2. 价格定义: 使用 yy 资产来表示 xx 资产的价格 PP

    P=yx P = \frac{y}{x}
  3. 推导 X 和 Y: 联立以上两个公式,可以分别用流动性 LL 和价格 PP 来表示 xxyy 的数量。

    • 推导 X: 从 P=y/xP = y/xy=Pxy = Px。代入基础公式得 x(Px)=L2x \cdot (Px) = L^2,化简后得到: x=LP x = \frac{L}{\sqrt{P}}
    • 推导 Y: 从 P=y/xP = y/xx=y/Px = y/P。代入基础公式得 (y/P)y=L2(y/P) \cdot y = L^2,化简后得到: y=LP y = L \cdot \sqrt{P}

2.2 引入 V3 价格区间与边界条件

img

在 V3 的价格区间 [pa,pb][p_a, p_b] 中存在两个边界:

  • 当价格 PP 上升到区间的上限 pbp_b 时,池中所有的真实 xx 资产(xrealx_{real})都被卖出,此时 xreal=0x_{real} = 0。池中与 xx 相关的流动性完全由虚拟 xxxvirtualx_{virtual})构成。
  • 当价格 PP 下降到区间的下限 pap_a 时,池中所有的真实 yy 资产(yrealy_{real})都被卖出,此时 yreal=0y_{real} = 0。池中与 yy 相关的流动性完全由虚拟 yyyvirtualy_{virtual})构成。

2.3 推导虚拟流动性 (x_{virtual} 和 y_{virtual})

根据上述边界条件和基础关系式:

  1. 计算 xvirtualx_{virtual}: 在价格点 P=pbP = p_b 时,xtotal=xvirtualx_{total} = x_{virtual}。将 P=pbP = p_b 代入 x=L/Px = L / \sqrt{P} 公式中:

    xvirtual=Lpb x_{virtual} = \frac{L}{\sqrt{p_b}}
  2. 计算 yvirtualy_{virtual}: 在价格点 P=paP = p_a 时,ytotal=yvirtualy_{total} = y_{virtual}。将 P=paP = p_a 代入 y=LPy = L \cdot \sqrt{P} 公式中:

    yvirtual=Lpa y_{virtual} = L \cdot \sqrt{p_a}

2.4 得出 Uniswap V3 最终公式

V3 的总流动性也遵循恒定乘积公式,即 (xreal+xvirtual)(yreal+yvirtual)=L2(x_{real} + x_{virtual}) \cdot (y_{real} + y_{virtual}) = L^2。将我们刚刚推导出的 xvirtualx_{virtual}yvirtualy_{virtual} 代入,即可得到 Uniswap V3 白皮书中的核心公式:

(xreal+Lpb)(yreal+Lpa)=L2 (x_{real} + \frac{L}{\sqrt{p_b}}) \cdot (y_{real} + L\sqrt{p_a}) = L^2

这个公式描述了在指定价格区间 [pa,pb][p_a, p_b] 内,用户提供的真实流动性 (xrealx_{real}, yrealy_{real}) 与总流动性 L 之间的关系。

2.5 价格区间与资金效率的动态关系

从虚拟流动性的公式可以看出:

  • 当价格区间下限 pap_a 增大时,yvirtual=Lpay_{virtual} = L \cdot \sqrt{p_a} 会随之增大。
  • 当价格区间上限 pbp_b 减小时,xvirtual=L/pbx_{virtual} = L / \sqrt{p_b} 会随之增大。
  • 结论: 当价格区间 [pa,pb][p_a, p_b] 变得越窄xvirtualx_{virtual}yvirtualy_{virtual} 的值就越大。这意味着系统提供的“虚拟”支持越多,用户需要投入的真实资产 xrealx_{real}yrealy_{real} 就越少,即可支撑起同样大小的流动性 LL,从而实现更高的资金效率。

3. 案例分析与计算

3.1 案例背景

  • 交易对: ETH / DAI

  • 价格区间端点:

    • A点: 2 ETH, 2000 DAI
    • B点: 0.5 ETH, 8000 DAI
  • 当前价格点:

    • P点: 1 ETH, 4000 DAI
  • 计算价格:

    • 价格下限 pa: pa=2000/2=1000 DAI/ETHp_a = 2000 / 2 = 1000 \text{ DAI/ETH}
    • 价格上限 pb: pb=8000/0.5=16000 DAI/ETHp_b = 8000 / 0.5 = 16000 \text{ DAI/ETH}
    • 当前价格 P: P=4000/1=4000 DAI/ETHP = 4000 / 1 = 4000 \text{ DAI/ETH}

3.2 计算虚拟流动性 (x_{virtual} 和 y_{virtual})

  1. 计算流动性 L: 在这条曲线上的任意一点计算 LL 都是相同的。我们使用 P 点的数据。

    L=xy=14000=4000 L = \sqrt{x \cdot y} = \sqrt{1 \cdot 4000} = \sqrt{4000}
  2. 计算 xvirtualx_{virtual}:

    xvirtual=Lpb=400016000=400016000=14=0.5 ETH x_{virtual} = \frac{L}{\sqrt{p_b}} = \frac{\sqrt{4000}}{\sqrt{16000}} = \sqrt{\frac{4000}{16000}} = \sqrt{\frac{1}{4}} = 0.5 \text{ ETH}
  3. 计算 yvirtualy_{virtual}:

    yvirtual=Lpa=40001000=4,000,000=2000 DAI y_{virtual} = L \cdot \sqrt{p_a} = \sqrt{4000} \cdot \sqrt{1000} = \sqrt{4,000,000} = 2000 \text{ DAI}
  4. 此案例的曲线方程:

    (xreal+0.5)(yreal+2000)=4000 (x_{real} + 0.5) \cdot (y_{real} + 2000) = 4000

3.3 理解真实流动性曲线

img

Uniswap V3 白皮书会画两条曲线:

  • 绿色曲线: 代表包含虚拟流动性的总流动性曲线 (xtotalytotal=L2x_{total} \cdot y_{total} = L^2)。这是一条标准的双曲线,不与坐标轴相交。我们所有的计算都基于这条曲线。
  • 黄色曲线: 代表真实流动性曲线 ((xreal+0.5)(yreal+2000)=4000(x_{real} + 0.5) \cdot (y_{real} + 2000) = 4000)。这条曲线是标准双曲线平移后的结果,它会与坐标轴相交,真实地反映了用户提供的 xrealx_{real}yrealy_{real} 之间的关系。

3.4 与 Uniswap V2 对比 (资金效率)

  • Uniswap V3: 在当前价格 P=4000P=4000 时,要达到 L=4000L=\sqrt{4000} 的流动性深度,用户实际需要提供的资产为:

    • xreal=xtotalxvirtual=10.5=0.5 ETHx_{real} = x_{total} - x_{virtual} = 1 - 0.5 = 0.5 \text{ ETH}
    • yreal=ytotalyvirtual=40002000=2000 DAIy_{real} = y_{total} - y_{virtual} = 4000 - 2000 = 2000 \text{ DAI}
  • Uniswap V2: 要达到同样的流动性深度,用户需要提供完整的 1 ETH4000 DAI

  • 结论: 在此案例中,通过将流动性集中在 [1000, 16000] 的价格区间,Uniswap V3 使用了一半的资金就达到了与 V2 相同的流动性深度,资金效率提升了一倍。


4. 模拟限价订单 (Simulating Limit Orders)

利用 V3 的价格区间机制,可以模拟出订单簿交易所的限价单功能。

案例: 在 [1000, 16000] 区间内,将 1.5 ETH 以不低于 4000 DAI/ETH 的均价卖出。

  1. 第一步:在价格下限 pap_a 添加流动性

    • 当价格为 pa=1000p_a = 1000 时,流动性池中只有 ETH。用户只需提供单一资产 ETH。
    • 需要提供的真实 ETH 数量为:xreal=xtotal_at_Axvirtual=20.5=1.5 ETHx_{real} = x_{total\_at\_A} - x_{virtual} = 2 - 0.5 = 1.5 \text{ ETH}
    • 此时 yreal=0y_{real} = 0
  2. 第二步:市场价格波动

    • 市场价格从 1000 DAI/ETH 开始上涨,穿过用户设定的整个价格区间。
  3. 第三步:在价格上限 pbp_b 移除流动性

    • 当价格到达 pb=16000p_b = 16000 时,用户提供的 1.5 ETH 已被完全兑换成 DAI。
    • 此时,用户可以移除的真实 DAI 数量为:yreal=ytotal_at_Byvirtual=80002000=6000 DAIy_{real} = y_{total\_at\_B} - y_{virtual} = 8000 - 2000 = 6000 \text{ DAI}
    • 此时 xreal=0x_{real} = 0
  4. 结果分析

    • 用户投入 1.5 ETH,最终取回 6000 DAI
    • 这相当于以平均 6000/1.5=4000 DAI/ETH6000 / 1.5 = 4000 \text{ DAI/ETH} 的价格成功卖出了自己的 ETH。
    • 效果: 这就模拟了一个在价格从 1000 上涨到 16000 的过程中,逐步卖出 ETH 的限价订单。如果价格区间设置得非常窄(如 [1000, 1010]),成交效果会更接近于一个精确价格的限价单。

5. 练习

题目: 在以上案例中,如果用户在当前价格点(1 ETH, 4000 DAI)真实提供了 1 ETH4000 DAI 的流动性(即 xreal=1x_{real}=1, yreal=4000y_{real}=4000),那么他所提供的总流动性 L 是多少?

解答过程:

  1. 写出核心公式:

    (xreal+Lpb)(yreal+Lpa)=L2 (x_{real} + \frac{L}{\sqrt{p_b}}) \cdot (y_{real} + L\sqrt{p_a}) = L^2
  2. 代入已知数值: xreal=1x_{real} = 1 yreal=4000y_{real} = 4000 pa=1000p_a = 1000 pb=16000p_b = 16000

    (1+L16000)(4000+L1000)=L2 (1 + \frac{L}{\sqrt{16000}}) \cdot (4000 + L\sqrt{1000}) = L^2
  3. 化简并展开方程:

    16000=160010=4010\sqrt{16000} = \sqrt{1600 \cdot 10} = 40\sqrt{10}

    1000=10010=1010\sqrt{1000} = \sqrt{100 \cdot 10} = 10\sqrt{10}

    代入得:

    (1+L4010)(4000+1010L)=L2(1 + \frac{L}{40\sqrt{10}}) \cdot (4000 + 10\sqrt{10}L) = L^2

    展开括号:

    4000+1010L+4000L4010+1010L24010=L24000 + 10\sqrt{10}L + \frac{4000L}{40\sqrt{10}} + \frac{10\sqrt{10}L^2}{40\sqrt{10}} = L^2

    化简各项:

    4000+1010L+100L10+14L2=L24000 + 10\sqrt{10}L + \frac{100L}{\sqrt{10}} + \frac{1}{4}L^2 = L^2

    10010=1001010=1010\frac{100}{\sqrt{10}} = \frac{100\sqrt{10}}{10} = 10\sqrt{10}

    合并同类项:

    4000+2010L+0.25L2=L24000 + 20\sqrt{10}L + 0.25L^2 = L^2
  4. 整理成一元二次方程:

    0.75L22010L4000=0 0.75L^2 - 20\sqrt{10}L - 4000 = 0
  5. 使用求根公式求解 LL:

    L=b±b24ac2aL = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}

    a=0.75a = 0.75

    b=2010b = -20\sqrt{10}

    c=4000c = -4000

    b2=(2010)2=40010=4000b^2 = (-20\sqrt{10})^2 = 400 \cdot 10 = 4000

    4ac=4(0.75)(4000)=3(4000)=12000-4ac = -4 \cdot (0.75) \cdot (-4000) = -3 \cdot (-4000) = 12000

    L=2010+4000+1200020.75L = \frac{20\sqrt{10} + \sqrt{4000 + 12000}}{2 \cdot 0.75}

    (取正根)

    L=2010+160001.5=2010+40101.5L = \frac{20\sqrt{10} + \sqrt{16000}}{1.5} = \frac{20\sqrt{10} + 40\sqrt{10}}{1.5}

    L=60101.5=4010L = \frac{60\sqrt{10}}{1.5} = 40\sqrt{10}

最终结果: 该用户提供的总流动性 LL401040\sqrt{10},约等于 126.49。对应的 kk 值或 L2L^2 值为 16000