# Uniswap vs. Curve 做市曲线分析

By [June](https://paragraph.com/@june-3) · 2022-03-09

---

此文从无常损失和滑点两个方面，分析 Uniswap 和 Curve （主流自动做市商） 稳定币做市曲线。

定义
--

滑点有2种定义。本文采用第一种定义方法，反映交易者成交的真实平均损失。

1.  （成交平均价格-初始价格）/ 初始价格
    
2.  （成交后价格-初始价格）/ 初始价格
    

无常损失定义：

1.  有两种选项
    
    1.  参加流动性挖矿 ==> w10（参与挖矿的资产市值）
        
    2.  持有资产，不参加流动性挖矿 ==> W11（不参与挖矿的资产市值）
        
2.  无常损失 = (w10 - w11) / w11
    

结论 -- 稳定币对交易
------------

选择什么样的做市曲线，这是一个滑点（交易者）和无常损失（流动性提供者）的权衡利弊。就稳定币而言，我们追求更低的滑点，且绝大多数情况下价格会在1附近波动。Uniswap v3 和 Curve 曲线会是更好的选择，因为他们相当于加个杠杆的uniswap v1/v2 曲线，同样的成交量可以带来更低的滑点。而Uniswap v3 和 Curve 曲线可以通过调整参数（价格区间和A值）达到相似的效果。就现在市场而言（P=\[0.9986, 1.0014\], A=5000），Curve 能够在价格在1附近提供更好的滑点，而无常损失和Uniswap v3 基本一致。假设稳定币价格不会脱钩，Curve 会是更好的选择。

### 滑点

假设我们从价格为1的点开始做交易

1.  相同的成交量，Curve上的滑点低于Uniswap v1/v2。如果我们单次交易池子里一个币对的99.9999%存量，Curve上的滑点也低于Uniswap v1/v2。对交易者来说，Curve 确实会带来更好的用户体验。
    
2.  Uniswap v3 采用了设置区间的方式来放大流动性。在区间范围内，Uniswap v3上的滑点始终低于Uniswap v1/v2。但只要超出区间，Uniswap v3交易对就失去了流动性，无法交易。
    
3.  Uniswap v3的价格区间的宽窄就类似于Curve曲线中A值带来的杠杆。Uniswap v3所对应的滑点和我们想要的成交数量和资产效率乘数是线性相关的。Curve曲线会随着A值的变大，滑点由线性变得更弯曲。不同的价格区间和不同的A值会带来不同的滑点：
    
    1.  Uniswap v3: \[0.8, 1.25\]; Curve A =2 （图1）==> Uniswap v3 滑点低
        
    2.  Uniswap v3: \[0.8, 1.25\]; Curve A =8 （图2）==> 成交量比较小，Curve 滑点低；成交量比较大，Uniswap v3 滑点低
        
    3.  Uniswap v3: \[0.8, 1.25\]; Curve A =50 （图3）==> 成交量比较小，Curve 滑点低；成交量比较大，Uniswap v3 滑点低
        
    4.  Uniswap v3: \[0.9986, 1.0014\]; Curve A = 5000【现在市场情况】 （图4）==> 成交量比较小，Curve 滑点低；成交量比较大，Uniswap v3 滑点低。绝大多数情况，同样成交量，Curve 滑点更低。
        
4.  就现在市场而言 （图4），成交量较小时，Curve 滑点 < Uniswap v3 < Uniswap v1/v2。如果出现出现巨额成交量（超90%）或者池子内一个币的数量偏移90%以上或者严重脱钩（稳定币价格远离1），Uniswap v3 滑点 < Curve < Uniswap v1/v2
    

![图1： Uniswap v3: [0.8, 1.25]; Curve A =2](https://storage.googleapis.com/papyrus_images/261f210a8b7551980f28abafff761e986f1f71c5b0dd1be46ff9381d65f5a54c.png)

图1： Uniswap v3: \[0.8, 1.25\]; Curve A =2

![图2： Uniswap v3: [0.8, 1.25]; Curve A =8](https://storage.googleapis.com/papyrus_images/fdf59d4e4a4660f13ac1b0293742a384aa5b8c01f01de6d5263776deb284a3af.png)

图2： Uniswap v3: \[0.8, 1.25\]; Curve A =8

![图3： Uniswap v3: [0.8, 1.25]; Curve A =50](https://storage.googleapis.com/papyrus_images/41956322425ba3e2a176f86078cf95dd3a6f8fd82c33e8b78a7c59937adbf84d.png)

图3： Uniswap v3: \[0.8, 1.25\]; Curve A =50

![图4：Uniswap v3: [0.9986, 1.0014]; Curve A =5000](https://storage.googleapis.com/papyrus_images/2255c23fe99efb4414e24ec60bbfbb3c2e906343a8960cceb5d90b813f032a37.png)

图4：Uniswap v3: \[0.9986, 1.0014\]; Curve A =5000

### 无常损失

此处做了两个重要假设：

1.  池子里只有两个币对（A, B）
    
2.  A和B的初始数量为1:1
    

结论

1.  同样成交量下，Curve滑点比uniswap v1/v2更低，但是在同样价格变化下，Curve无常损失更大。随着A值增大，Curve滑点越来越低，无常损失也越来越大（图5）。
    
2.  为达到和uniswap一样的价格，Curve池需要更多的成交量。假设P0=1
    
    1.  A = 1时，一次性交易池内99%的一个币，价格变化99.3%
        
    2.  A = 100时，一次性交易池内99%的一个币，价格变化84.8%
        
    3.  A = 1000时，一次性交易池内99%的一个币，价格变化38%
        
    4.  \==> 因为需要更多的成交量，Curve 很难出现和Uniswap同样的价格。但是假设没有无风险套利机会，Curve 和Uniswap V1/v2 上 是同样的价格，Curve 无常损失更大。
        
3.  同样成交量下，Uniswap v3滑点比uniswap v1/v2更低，但是同样价格变化下，Uniswap v3无常损失更大。随着价格区间变小，Uniswap v3滑点越来越低，无常损失也越来越大（图6）。
    
4.  同样是加了杠杆的Uniswap v1/v2仓位， Uniswap v3和Curve 有什么区别呢？
    
    1.  固定Uniswap v3价格区间为\[0.8, 1.25\], 我们变化 Curve 的A值，我们可以看到，Uniswap v3 的无常损失曲线是在Curve\[A =10\] 和Curve\[A =100\] 之间的。也就是说，通过变化A值，Uniswap v3 和 Curve 的无常损失可以达到类似效果。（图7）
        
    2.  Uniswap v3: \[0.9986, 1.0014\]; Curve A = 5000【现在市场情况】。就现在市场而言，同样价格变化，Curve 和 Uniswap v3 的无常损失基本一致。（图8）
        

![图5](https://storage.googleapis.com/papyrus_images/cae88c488ff45d657201cf84aa79afffb19b42a0786a315761ff0de7e806a0d1.png)

图5

![图6](https://storage.googleapis.com/papyrus_images/811caae1b99fcb3f237e3b6b8fcae931775a3b94acf6e4f32406646d209a5dc9.png)

图6

![图7](https://storage.googleapis.com/papyrus_images/44cec100c2f63e1267796750528ed4682c9c537e054821bde305e784e35d0083.png)

图7

![图8](https://storage.googleapis.com/papyrus_images/f68d0267d9710a128d9896edcc21d08b5a877d267d8b06827ab2547fe72d8778.png)

图8

Python implementation：

[https://github.com/June911/AMM\_models/blob/main/IM\_loss.ipynb](https://github.com/June911/AMM_models/blob/main/IM_loss.ipynb)

Excel implementation：

[https://docs.google.com/spreadsheets/d/1LmWwYa\_5OEpGfPKl2IBxMavFlXFAsKBQ8327gtQpnv0/edit?usp=sharing](https://docs.google.com/spreadsheets/d/1LmWwYa_5OEpGfPKl2IBxMavFlXFAsKBQ8327gtQpnv0/edit?usp=sharing)

* * *

> 以下是公式推导

Uniswap v1/v2
-------------

### 做市曲线 -- 恒定乘积做市

    x * y = k = L^2
    

其中x，y分别代表代币x和y的数量。因为k>0，可以把它定义为L^2

### 价格 （以y为基本单位，x的价格）

    y = L^2 / x ==> dy = - L^2 / x^2 dx ==>  
    P = - dy / dx = - (- L^2 / x^2 dx) / dx = L^2 / x^2 = y / x
     
    x = L / sqrt(P)
    y = L * sqrt(P)
    

![价格为边际数量变化之商](https://storage.googleapis.com/papyrus_images/05d188aa6b0ea21391c279136d80231d341b70cb23dc22d1c85ba2ab62123d5c.png)

价格为边际数量变化之商

### 成交价格

假设流动池里的币对从(x1,y1) 变化到(x2,y2)，而价格从p1变化到p2

![](https://storage.googleapis.com/papyrus_images/a628f19cd27ec977949b02aacd04e6cb75b22192081e71559b07f89d9e3ba7da.png)

### 滑点

![](https://storage.googleapis.com/papyrus_images/21b7bf2b9ceb393020a895124ced8a78894f4406bd856625db8a1637ef7de802.png)

### 无常损失

    w10: wealth at time t1 if participate as UNISWAP LP at time t0 
    w11: wealth at time t1 if hold half asset x and half asset y at time t0
    p(t1): price for x at time t1 
    p(t0): price for x at time t0
    
    Assume r = p(t1) / p(t0)
    
    !!! all the wealth are denominated in y. 
    
    w10 = p(t1) * x1 + y1 
        = p(t1) * L / sqrt(p(t1)) + y1
        = L * sqrt(p(t1)) + y1
        = 2 * L * sqrt(p(t1))
    
    w11 = p(t1) * x0 + y0 【the quantities remain the same】
        = p(t1) * L / sqrt(p(t0)) + y0
        = r * P(t0) * L / sqrt(p(t0)) + y0 
        = r * sqrt(p(t0)) * L + sqrt(p(t0)) * L
        = (1 + r) * sqrt(p(t0)) * L
     
    IL = w10 / w11 - 1   
       = 2 * L * sqrt(p(t1)) / ((1 + r) * sqrt(p(t0)) * L) - 1
       = 2 * sqrt(p(t1)) / ((1 + r) * sqrt(p(t0))) - 1 
       = 2 * sqrt(r) / (1 + r) - 1 
    

Uniswap v3
----------

### 做市曲线 -- 恒定乘积做市

![](https://storage.googleapis.com/papyrus_images/be0d662d20da2c15fb86704b9a15f7d0c860c24fe0a97629f44044c8eeab2b25.png)

    what's new:
    Pa: low range for x
    Pb: up range for x
    Pc: current price for x 
    Pa < Pc < Pb 
    
    x_v: virtual reserve for x 
    y_v: virtual reserve for y 
    L: virtual liquidity 
    
    (x + L / sqrt(Pb)) * （y + L * sqrt(Pa)） = L^2 
    
    x_v * y_v =  L^2 
    x_v = x + L / sqrt(Pb)
    y_v = y + L * sqrt(Pa)
    
    Pc = - dy / dx = y_v / x_v     
    x_v = L / sqrt(Pc)
    y_v = L * sqrt(Pc)
    
    x = x_v -  L / sqrt(Pb)
      = L / sqrt(Pc) - L / sqrt(Pb)
    
    y = y_v - L * sqrt(Pa)
      = L * sqrt(Pc) - L * sqrt(Pa)
    

### 无常损失

    w10: wealth at time t1 if participate as UNISWAP LP at time t0 
    w11: wealth at time t1 if hold half asset x and half asset y at time t0
    
    Assume r = p(x1) / p(x0)
    

![](https://storage.googleapis.com/papyrus_images/f86d9173b80b017d02a02ad85e9fea322f9914fbf943c01e01aa319fddc93370.png)

![](https://storage.googleapis.com/papyrus_images/184e2a8976c28761deb3ffdb777faf27f3a8828de350679801a2a956d9e38d8d.png)

![](https://storage.googleapis.com/papyrus_images/f3f2d8dc37e6566ae51ab2973a34e6994b0e5a81c7004efd5da45b9cf0e37ab3.png)

### 资本效率乘数

![w_v2 = w_v3](https://storage.googleapis.com/papyrus_images/b761d8cfa1c6798c58f57b45e5e99c70cbc946a0c3ce04c4f5ba7ead50a18ef5.png)

w\_v2 = w\_v3

![](https://storage.googleapis.com/papyrus_images/38f0c57659d9ce30b72bafd626bb3fe9d0e6b4395e050ae670049bed59cf9035.png)

### 单区间滑点

假设V3只有一个流动区间

1.  V2滑点 = 资本效率乘数 \* V3滑点
    
2.  区间越小， V3滑点越小
    

![](https://storage.googleapis.com/papyrus_images/0350a6194291800ad98f1020b0b99d19656898a15cf0aec9d508c9ee9783beff.png)

实际上，Uniswap v3 是无数个流动性区间累加起来的。每个tick之间对应其单独的流动性，只有这个tick对应的流动性被耗尽，才会进入下一个区间继续寻找流动性。

Curve v1
--------

Curve 是 恒定乘积做市 和 恒定和做市的结合。当 A 取值接近于0时，Curve 曲线 = Uniswap v1/v2 曲线；当 A 取值接近于无穷时，Curve 曲线 = 恒定和做市曲线。A 越大，Curve 曲线越向恒定和做市曲线倾斜。

### 做市曲线 -- 恒定乘积和恒定和结合做市

![](https://storage.googleapis.com/papyrus_images/593642e0a99062d60ff57b5a1738ebb15c711f16471b7b4f71ae6f6355f3a176.png)

A ==> 扩增参数（amplification parameter）

D ==> 不变量参数 (StableSwap invariant)

![](https://storage.googleapis.com/papyrus_images/6292e65cc5575e9080eaf090b4c1fad10c11e51e52ab8cf65de912d0c5684c62.png)

其中，Ann = An^n

### 如何计算置换的量

假设我们手上有 xi，想去池子换成 xj (=y)。

![](https://storage.googleapis.com/papyrus_images/bdf21b153b61332468ccaac33210aa97e8438fe54cdf1f1ca6f577ae16ceaf56.png)

通过上图的变化，再加上一些简化，我们就可以得到

![](https://storage.googleapis.com/papyrus_images/0d439b28c5ed3a35c1c15b24d0c47da73ddee720ee6fc2a8f776590430448c13.png)

这个问题就变为，在满足f(y)=0的情况下，求解y。当n=2的时候，此方程有闭式解。当n>3的时候，Curve.fi 用的[牛顿迭代法](https://github.com/curvefi/curve-contract/blob/master/contracts/pools/usdt/StableSwapUSDT.vy)。

![牛顿迭代法 （Newton Raphson Method）](https://storage.googleapis.com/papyrus_images/1ac7eeca2bc594021e0c55a440629992d258841730409ee29d433222cd4c46a6.png)

牛顿迭代法 （Newton Raphson Method）

由于f’(y) = 2y + (b-D)，我们就可以得出下图的迭代公式了

![Curve Stable Swap - 牛顿迭代法](https://storage.googleapis.com/papyrus_images/8f03d37dd71c2645b8526e5f0442625484cbc1ba600346596c6405fde43d0711.png)

Curve Stable Swap - 牛顿迭代法

### 如何计算D

和计算置换量类似的方法，我们假设x,y不变，对做市曲线求解D。

![](https://storage.googleapis.com/papyrus_images/ac2b4464b3ad9e7d43998d7a4315cd839ecac49e3fc25c8936be0b8b00ccb3e3.png)

这里的S = sum(xi)。

![求导](https://storage.googleapis.com/papyrus_images/9df79d35214d25c1fcd8719556bea9a2c4c4f971c69f56a97f0e1c0999ede554.png)

求导

其中 Dp 如下图

![Dp](https://storage.googleapis.com/papyrus_images/1f0ae4cd792f5328c5a27fdc0a115c4d517b6ac7fcf57054d948188e76b6b6a8.png)

Dp

同样用牛顿迭代法，求解D

![Curve Stable Swap - 牛顿迭代法](https://storage.googleapis.com/papyrus_images/35f15f6f76d41872d1678626d60a07af6d48acf2912f58e977c5ad697ffd2d77.png)

Curve Stable Swap - 牛顿迭代法

现在假设n=2（池子里只有两个币对），x和y

### 做市曲线 （n = 2, x1 = x, x2 = y）

![n = 2, x1 = x, x2 = y](https://storage.googleapis.com/papyrus_images/d45dc08d77bc0908c8a46245e8731132bd6c2f2f520a8a4f75c4c00efc1ef57d.png)

n = 2, x1 = x, x2 = y

### 如何计算D

已知x,y求D，这是一个三元方程， 可以通过[卡尔达诺公式](https://baike.baidu.com/item/%E5%8D%A1%E5%B0%94%E8%BE%BE%E8%AF%BA%E5%85%AC%E5%BC%8F/18880906?fr=aladdin)（Cardano Formula）求解

![](https://storage.googleapis.com/papyrus_images/73d72f2ab6edd5e1a4188bfc2ece7f1f59f7d6272e980de757278e95a94114e3.png)

其中

![](https://storage.googleapis.com/papyrus_images/b1393219ea797589cf7ccb85b5d3ed01dee476fbba1cf89873270e98db03e216.png)

值得注意的是，假设不添加或删除流动性，D是恒定的。x的变化只会带来y的变化。

### 如何计算置换的量

已知n=2，n^n =4, 带入之前的置换公式，可以得到

![](https://storage.googleapis.com/papyrus_images/2f8999d0fefe068973623dcfe561659de82ed75b34cbffb244176f257745267c.png)

同理，对于y来说，这是一个一元二次方程，可以用求根公式求解。

![](https://storage.googleapis.com/papyrus_images/fb3ce3563767e490333e052d5153778d149755603115e611ca7f3e061467249e.png)

其中a, b, c 分别为：

![](https://storage.googleapis.com/papyrus_images/dee317e9f5c8a9ae995ace7d7f1b51363aafa8fd07344afef0b77342fd3ba06e.png)

### 置换后价格

我们知道

![](https://storage.googleapis.com/papyrus_images/8af08173cc140ea03c8bb0d8e7a930b89e3f6c4320a75232159041374b6ed232.png)

对等式两边求导得到

![](https://storage.googleapis.com/papyrus_images/1755a18a766ddb0d65079fb2ab62a2d9ac89c96c0dba3662be8c631f234c3d58.png)

即可得到y’的公式

![](https://storage.googleapis.com/papyrus_images/af965ac7ab117dd05fbc5011259134ecde82758da6f1f780c575d6365a5cef53.png)

我们知道价格等于边际变化量之比，即p\_x = -y’ = -dy / dx。通过上述公式，我们就可以得到置换后价格。

### 滑点

已知 p\_x = - y’ = g(x,y)，对任意(x,y)，我们都可以求到其对应的价格。也可以求到平均价格。再利用滑点定义【（成交平均价格-初始价格）/ 初始价格】，即可以求出滑点。

### 无常损失

已知做市曲线f(x,y) = 0 和 p\_x = - y’ = g(x,y)，两个方程求解两个未知数（x,y），我们就可以求到 x,y 分别关于 D和 p\_x 的函数。然后再通过无常损失定义【(w10 - w11) / w11】，即可以求出无常损失。

首先找到 y = f(p,x)，如下图。

![](https://storage.googleapis.com/papyrus_images/8b17b3517e6fd43b41f61281fa77d82006061c44e392b59a2761746aad9b3df4.png)

然后我们还知道 y = f(x)，所以通过y = f(x) = f(p,x)，我们就可以求解 x = f(p) 。这是一个一元四次方程，不太容易解出来，就没继续了。

* * *

\*\*此处考虑另外一种方法画出无常损失曲线。\*\*首先我们假设池子里的初始币对（x,y）数量为1:1，那么对于每个给定的y的数量变化，我都可以得到对应x的数量变化，从而计算得到变化后的价格。已知了初始价格，初始数量，新价格和新数量，我们就可以通过无常损失定义，计算出其无常损失了。为了画出，我们就需要一个y的数量变化的列表【dy= \[-99, -98, -97, ……, 99\]】，然后计算出当前价格，再计算出无常损失。我们就可以得到一个当前价格和无常损失的一一对应关系列表。即可以画出价格对应的无常损失的曲线。

详细python实现见此：[python](https://github.com/June911/AMM_models/blob/main/IM_loss.ipynb)

详细excel实现见此：[excel](https://docs.google.com/spreadsheets/d/1LmWwYa_5OEpGfPKl2IBxMavFlXFAsKBQ8327gtQpnv0/edit?usp=sharing)

！！！在推导Uniswap无常损失时，我们是没有限制初始币对数量的。它的机制，在任何时刻，两个币对的价值都是1:1。所以不管当前池子里数量是什么，我们都可以通过公式直接得出无常损失。而在推导Curve无常损失时，我们假设了初始币对数量为1:1。我们通过初始币对数量求到D=x+y=2x=2y（如果不添加或删除流动性，D不变），再通过成交量就可以求到无常损失。 如果初始币对数量不是1:1，那么同样的价格变化（与1:1的初始状态相比），对应的无常损失会不一样。

公式
--

[https://www.overleaf.com/read/zgcffvfngxcp](https://www.overleaf.com/read/zgcffvfngxcp)

参考目录
----

[https://dev.balancer.fi/resources/pool-math/stable-math](https://dev.balancer.fi/resources/pool-math/stable-math)

[https://atulagarwal.dev/posts/curveamm/stableswap/#mjx-eqn%3Aeqn%3Astableswap](https://atulagarwal.dev/posts/curveamm/stableswap/#mjx-eqn%3Aeqn%3Astableswap)

[https://alvarofeito.com/articles/curve/](https://alvarofeito.com/articles/curve/)

[https://pandichef.medium.com/the-slippage-ratio-a-new-metric-to-understand-curve-fis-amm-protocol-fddf0ba4d6c8](https://pandichef.medium.com/the-slippage-ratio-a-new-metric-to-understand-curve-fis-amm-protocol-fddf0ba4d6c8)

[https://github.com/curvefi/curve-contract/blob/master/contracts/pools/usdt/StableSwapUSDT.vy](https://github.com/curvefi/curve-contract/blob/master/contracts/pools/usdt/StableSwapUSDT.vy)

[https://uniswap.org/whitepaper.pdf](https://uniswap.org/whitepaper.pdf)

[https://uniswap.org/whitepaper-v3.pdf](https://uniswap.org/whitepaper-v3.pdf)

[https://curve.fi/files/stableswap-paper.pdf](https://curve.fi/files/stableswap-paper.pdf)

[https://medium.com/auditless/impermanent-loss-in-uniswap-v3-6c7161d3b445](https://medium.com/auditless/impermanent-loss-in-uniswap-v3-6c7161d3b445)

---

*Originally published on [June](https://paragraph.com/@june-3/uniswap-vs-curve)*
