0%

精通 Uniswap

UniswapDeFi中最著名的协议之一,Uniswap本质是一个自动化做市商(AMM),它舍弃了传统订单薄的撮合方式,采用流动池加恒定乘积公式算法(\(x \times y=k\))为不同加密资产提供即时报价和兑换服务。

什么是Uniswap

关于什么是Uniswap,先看一下Uniswap白皮书中的定义:

Uniswap is a protocol for automated token exchange on Ethereum. It is designed around ease-of-use, gas efficiency, censorship resistance, and zero rent extraction.

Uniswap是一个基于以太坊的自动代币交换协议,它的设计目标是:易用性、gas高利用率、抗审查性和零抽租。

  • ease-of-use(易用性):Token AToken B,在Uniswap也只要发出一笔交易就能完成兑换,在其它交易所中可能需要发两笔交易:第一笔将Token A换成某种媒介货币,如ETH, DAI 等,然后再发第二笔交易换成Token B
  • gas efficiencygas高利用率):在Uniswap上消耗的gas量是以太坊上的几家主流去中化交易所中最低的,也就代表在Uniswap交易要付的矿工费最少。 img
  • censorship resistance(抗审查性):抗审查性体现在Uniswap上架新Token没有门槛,任何人都能在Uniswap上架任何Token。这在去中心交易所中很少见,虽然大多数的去中心化交易所不会像中心化交易所那样向你收取上币费,但还是需要提交上币申请,通过审查后运营团队才会让你的Token可以在他们的交易所上交易。下面是各去中心化交易所上币规则的详情:
  • zero rent extraction(零抽租):在Uniswap协议设计中,开发团队不会从交易中抽取费用,交易中的所有费用都归还给流动性提供者。

自动化做市商(AMM)

传统的交易所有一个订单薄(Order Book),订单薄上记录着买卖方向,数量和出价,交易所负责对买卖双方进行配对,一旦订单薄中最高价格低于或等于最低价格,就会促成交易,同时会产生一个新的成交价,传统交易所有以下特点:

  • 市场上必须要有用户进行挂单,要有一定量的订单(市场流动)。
  • 订单必须重叠才能成交,即买价高于或等于卖价。
  • 需要将资产存储在交易所。

img

在订单薄模型市场中,买家期望用最低的价格买到想要的资产,而卖家则是期望用最高价格卖出同一项资产,如果交易要成立,买卖双方必须要在价格上达成共识,一是买家提高出价,而是卖家降低出价,如果双方都不要改变出价,这时候就要依靠做市商的参与,简单来说,做市商是一个促进交易的实体,它会在买卖两个方向上挂单,让想要交易的参与方只要跟做市商的订单撮合就能完成交易,而不需要等待对手方出现才能交易,极大的提高了市场的流动性。

为什么Uniswap不采用订单薄模型?

Uniswap部署在以太坊上,而以太坊每秒可以出来15笔左右的交易,这对于订单薄交易所来不可行,主要原因是:“订单薄模型依赖一个或多个外部做市商对某项资产一直不断的做市,而以太坊的TPS过低不支持做市商高频的交易,如果缺少了做市商,那么交易所的流动性立刻会降低,对于用户来说这样的交易所体验很差。”

Uniswap采用流动池加恒定乘法公式这种自动化做市商(AMM)模式实现了资产的交换,自动化做市商模式方式不需要买卖双方进行挂单,也不要买卖双方的订单重叠,可以进行自由买卖。

  • 流动池:使用流动池来提供买卖双方交易,做市商只要把资金放入流动池即可
  • 恒定乘法公式:按照流动池中Token的数量,自动计算买卖价格

流动池

流动池就是锁定在智能合约中所有的代币以及资金的总称,流动是资金转为代币,或代币转为资金的意思。

一个完整的流动池分为2个部份,分别表示不同的货币,成为一个交易对,在Uniswap V1中就是ETHERC20代币,在Uniswap V2中是支持不同ERC20代币直接交换,所以在Uniswap V2中的流动池可以允许两边是不相同的ERC20代币,其中ETH会自动转换成以WETH代币。为了简化,直接以ETH-ERC20交易对作为例子。

如下图所示,Uniswap将所有做市商的ETH集合在一起放在流动池左边, 将所有ERC20集合在一起放在流动池的右边。如果有用户要买ERC20代币,就从流动池的右边将ERC20代币转给用户,同时将用户支付的ETH添加的流动池的左边,然后重新计算流动池中的价格,等待下次交易。

img

Uniswap是无法自己变出钱来,因此需要依赖外部资金向合约中提供流动性,向Uniswap流动池中提供流动性的用户被称为流动性提供者,当流动性提供者向Uniswap中注入流动性的时候,Uniswap会铸造出一个流动性代币(LP),铸出LP代币数量是与用户注入的资金所占流动池中的资金比例相关,动性提供者可以选择在任何时间销毁自己持有的流动性代币。为了鼓励用于向Uniswap的流动池中提供更多的流动性,Uniswap会从每笔交易总额中抽取0.3%当成交易手续费,并将手续费全额交给那些将注资金到Uniswap资金池提供流动性的流动性提供者。

恒定乘积公式

假设在Uniswap中存在一个ETH-DAI交易对的流动池,用户在使用DAIETH兑换时需要一个方法来决定交易价格。

Uniswap定价模型非常简洁,它的核心思想是一个恒定乘积公式\(x \times y = k\) 。其中xy分别代表流动池中两种资产的数量,k是两种资产数量的乘积。

\(x \times y = k\)的函数图像如下:

img

假设乘积k是一个固定不变的常量,当用户使用x资产从流动池中兑换y资产时,流动池中x资产的数量会增加,y资产的数量会减少。由于k是恒定的,所以当x增长\(\Delta X\) 时,需要将y减少\(\Delta Y\)才能保持等式的恒定。

\[ (x+\Delta X ) \times (y - \Delta Y) =k \]

这里没有考虑到手续费的问题,如果要计算手续费的话,公式如下:

\[ (x+\Delta X \gamma) \times (y - \Delta Y) =k‘ \]

\[ k' \gt k \]

其中:\(\rho = 0.3\%\)\(\gamma = 1- \rho\)

\(\Delta X \gamma\)表示扣除手续费后加入到流动池中的资产。由于在流动池中增加了手续费所以计算出来的k'会大于k,详细过程会在后面推导。

接下来会有一些数学公式的推导,为了方便理解,我们先对不含手续费的情况进行推导,包含手续费的推导过程放在最后。

不含手续费

交易价格计算

交易价格的计算分成两种: - InputPrice:向流动池中放入\(\Delta X\)Token可以兑换出多少个\(\Delta Y\)Token - OutputPrice:从流动池中取出\(\Delta Y\)Token,需要向流动池中放入多少个\(\Delta X\)Token

\[ x^{'}=x+ \Delta x =(1+ \alpha)x= \frac {1} {1 - \beta} x \]

\[ y^{'}=y- \Delta y = \frac {1} {1+\alpha} y = (1 - \beta)y \]

\[ xy=x'y'=k \]

其中:\(\alpha = \frac {\Delta x} {x}\)\(\beta = \frac {\Delta y} {y}\)

\[ \Delta x= \alpha x \]

\[ \begin{aligned} {x'}&=(1+\alpha)x=\frac {1} {1-\beta} x \\ & \implies 1+\alpha=\frac {1} {1-\beta} \\ & \implies \alpha=\frac {\beta} {1-\beta} \\ \end{aligned} \]

\[ \Delta x = \frac {\beta} {1 - \beta} x \tag{Output price} \]

\[ \Delta y = \frac {\alpha} {1 + \alpha} y \tag{Input price} \]

下面是Input price的函数图像:

img

从上图可以看出向流动池中注入的\(\Delta X\)越多,可以从流动池中取出的\(\Delta Y\)也会越多,但是\(\Delta Y\)只会不断地逼近流动池中现有的\(y\)代币数量,并不会超过,也就是说你永远无法一次性买断流动池中所有的\(y\)。可以看出,恒等乘积公式可以提供无限的流动性,只要你想买就一定可以买到。

交易滑点

交易滑点是指:“在买卖\(Token\)时,实际支付的价格和期望的交易价格之间的差别,称为交易滑点”。

从流动池中购买\(\Delta Y\)Token需要支付\(\Delta X\),所以本次购买的价格为:\(P=\frac {\Delta X} {\Delta Y}\)

\[ P=\frac {\Delta X} {\Delta Y} = \frac {\alpha x} {\frac {\alpha} {1 + \alpha} y}= ({1 + \alpha}){\frac x y} \]

\[ {P'}=\frac x y \]

\[ 滑点=P-P'=(1+\alpha){P'} -{P'}=\alpha {P'} \]

其中:\({P'}=\frac x y\)表示当前流动池中的价格

从公式可以看出交易的滑点是与\(\alpha = \frac {\Delta X} x\)成线性关系。

下图是滑点的函数图像:

img

滑点(偏离幅度)取决于\(\frac {\Delta X} {x}\), 当资金池中\(x\)足够大时,滑点越小,资金池固定时,一个区块时间内净交易量越小,滑点越小,一个区块时间内的净交易量又与两个因素相关,一个是区块确认速度,一个是市场价格波动率,因此Uniswap恒定乘积做市的滑点与下面三个因素高度相关:

  • 资金池的大小
  • 区块确认速度
  • 市场波动率
流动池币价

当从流动池中购买\(\Delta Y\)代币后一定会引起当前流动池中的价格波动:

\[ P=\frac {x'} {y'} = \frac {(1+\alpha)x} {\frac {1} {1+\alpha} y}= {(1+\alpha)(1+\alpha)} \frac x y \]

其中:\(P\)是购买\(\Delta\)代币后流动池中的币价

从公式可以看出流动池中的币价与\(\alpha\)成二次函数关系

下图是价格的函数图像:

img

当流动池中的价格与外部市场价格不一致时就会有套利者出现,套利者监控全球各家交易所的价格,一旦发现两家交易所存在价差,就会同时在两边低买高卖赚取中间差价。由于套利者的存在,才使得Uniswap币价不会与全球市场脱节。

  • Uniswap中的价格高于外部市场时,套利者从外部市场低价买入\(Y\) ,然后高价卖给Uniswap
  • Uniswap中的价格低于外部市场时,套利者从Uniswap低价买入\(Y\),然后高价卖给外部市场
表格

对于不理解上面公式的同学,可以参考以下表格中的数据自己在excel中手动演算一遍,可以更直观的理解Uniswap的工作原理。

购买ETH数量 (ΔY) 单个ETH价格 (DAI) 滑点 购买时消耗的DAI (ΔX) DAI流动量 (x) ETH流动量 (y) 常数 (K) x/y alpha (ΔX/x) beta (ΔY/y)
100000 1000 100000000 100
1 100.1001001 0.10% 100.1001001 100100.1001 999 100000000 100.2003004 0.001001001 0.001
10 101.010101 1.01% 1010.10101 101010.101 990 100000000 102.0304051 0.01010101 0.01
50 105.2631579 5.26% 5263.157895 105263.1579 950 100000000 110.8033241 0.052631579 0.05
100 111.1111111 11.11% 11111.11111 111111.1111 900 100000000 123.4567901 0.111111111 0.1
200 125 25.00% 25000 125000 800 100000000 156.25 0.25 0.2
500 200 100.00% 100000 200000 500 100000000 400 1 0.5
800 500 400.00% 400000 500000 200 100000000 2500 4 0.8
999 100000 99900.00% 99900000 100000000 1 100000000 100000000 999 0.999

加入手续费的恒定乘积公式

以下过程是在计算手续费的情况下,将上面的公式重新推导了一遍。

计算交易价格

\[ x_{\rho}^{'}=x + \Delta x=(1+\alpha)x=\frac {1 + \beta(\frac 1 \gamma -1)} {1-\beta} x \]

\[ y_{\rho} ^{'} = y - \Delta y = \frac {1} {1+\alpha \gamma} y =(1 - \beta) y \]

\[ {k'} \gt x^{'} _{\rho} y^{'} _{\rho}=(1+\beta(\frac {1} {\gamma} -1))xy \gt k \tag{加入手续费后计算出的k'>k} \]

k除了在有交易手续费的情况会变大,还有一个情况也会使k值产生变化,当向流动池中增加流动性的时候k会变大,当从流动池中取回流动资金时k会变小。具体变化比例可以参考Uniswap白皮书,这里就不做推导了。

其中:\(\alpha=\frac {\Delta x} {x}\)\(\beta = \frac {\Delta y} {y}\)\(0 \le \rho \lt 1\)\(\gamma = 1 - \rho\),目前交易费为:\(\rho= 0.3\%\)

\[ \Delta x= \frac {\beta} {1-\beta} \cdot \frac {1} {\gamma} \cdot x \]

\[ \Delta y = \frac {\alpha \gamma} {1+\alpha \gamma} \cdot y \]

交易滑点

\[ P=\frac {\Delta x} {\Delta y} = \frac {\alpha x} {\frac {\alpha \gamma} {1+\alpha \gamma} \cdot y }= \frac {1+\alpha \gamma} {\gamma} \frac x y \]

\[ {P'}=\frac x y \]

\[ 滑点=P-{P'}={ \frac {1+\alpha \gamma} {\gamma} \frac x y} - {\frac x y}= {\frac {1+(\alpha - 1)\gamma} {\gamma}}{\frac x y} \]

流动池的币价

\[ \frac {x^{'} _{\rho}} {y^{'} _ {\rho}} = \frac {(1+\alpha)x } {\frac 1 {1+\alpha \gamma} y} = (1+\alpha)(1+\alpha \gamma) \frac x y \]

流动池收益与风险

Uniswap中流动性提供者的收益主要来自于交易抽成,Uniswap会从每笔交易中抽取0.3%的手续费,并将手续费按流动性提供者所占流动池的比例分配给流动性提供者。

impermanent loss

Uniswap中提供流动性的人会发现一个现象:“目前在流动池中资金的价值比放入流动池之前的资金价值少了,也就是资金缩水了”,这种现象被称为“impermanent loss”,impermanent loss中文翻译成“无常损失”,简单来说impermanent loss是指你将加密货币放入uniswap中赚取的收益与你将加密货币放入钱包中的收益之间的差,公式为:\(L={profit}_{lp}- {profit}_{hodl}\)

hodl指不看币价涨跌长期持有某种加密货币(hold on for dear life)

impermanent loss通常是由于流动池中的价格发生波动引起的,下面看一个例子:

\[ \begin{aligned} e \times t = k \\ p=\frac t e \\ e=\sqrt{\frac k p} \\ t=\sqrt{k \times p} \\ \end{aligned} \]

其中:\(e\)表示流动池中ETH数量,\(T\)表示流动池中DAI数量,\(p\)表示流动池中的价格

开始用户向流动池中注入\(e=100\)\(t=10000\),当前市场的价格:\(p=\frac t e=100\)

\[ k=et=100 * 10000=1000000 \]

假设现在外部市场价格发生了变化,价格变成:\(p'=120\),由于发生价格差,这时套利者开始工作,套利者通过搬砖将流动池中的价格维持与外部是市场一致。这时流动池中最新的\(e\)\(t\)数量为:

\(e’=\sqrt{\frac k p}=\sqrt{\frac {1000000} {120}}=91.28709291752769\)

\(t'=\sqrt{k \times p}=\sqrt{ 1000000 \times 120}=10954.451150103323\)

计算HODL时的资金 :

\(v0=e \times p' + t=100 \times 120 + 10000=22000\)

计算放入流动池后的资金:

\(v1=e' \times p' + t'= 91.28709291752769 * 120 + 10954.451150103323 = 21908.902300206646\)

计算impermanent loss:

\(L=\frac {v1} {v0}=\frac {21908.902300206646} {22000} =0.9958591954639384 \approx 99.59 \%\)

可以看出价格从100变成120后我们的资金只有之前的99.59%,损失了4%左右。只要这时候我们不将资金从流动池中取出,一旦流动池中的币价回到100时,我们是没有损失的,这是为什么叫impermanent loss无常损失的原因。

下图演示impermanant loss的比率与当前价格变化的关系,O列表示资金刚放入流动池的情况,O->H表示价格上涨时impermanent loss的变化,A<-O表示价格下跌时impermanent loss的变化。

A B C D O E F G H
p1/p0 0.00% 25.00% 50.30% 75.61% 100.00% 156.25% 204.08% 400.00% 493.83%
ETH e 3162278 200 141 115 100 80 70 50 45
DAI t 0.316227732 5000 7092.198582 8695.652174 10000 12500 14285.71429 20000 22222.22222
k 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000
p 1E-07 25 50.29928072 75.61436673 100 156.25 204.0816327 400 493.8271605
v0 10000.00001 12500 15029.92807 17561.43667 20000 25625 30408.16327 50000 59382.71605
v1 1 10000 14184 17391 20000 25000 28571 40000 44444
L 0.01% 80.00% 94.37% 99.03% 100.00% 97.56% 93.96% 80.00% 74.84%

下图是根据上面数据画出的函数图像,蓝色的曲线是不包含手续费的,黄色的图像包含手续费,红色的线条是我手动添加上去的为了方便说明。

先看蓝色曲线,当不计算手续费收益的情况下,无论币价上涨或下跌,流动性提供者100%会有损失。

再看黄色的曲线,由于黄色曲线是计算手续费收益的,所以只要币价在一个范围内波动,流动性提供者可以稳赚手续费收益。

img

由此可以得出一个结论要介绍impermanent loss对流动性提供者的影响,可以为两个币价之间波动小的流动池提供流动性。

img

  • mean-reverting pairs:均值回归的交易对,比如稳定币交易对两者波动是最小的,可以最大程度减少impermanent loss
  • correlated pairs:有正相关性的交易对,例如ETH/ZRX,这两个币的波动方向基本上是一致的,同涨同跌,两者之间的相对波动小
  • Uncorrelated pairs:非相关性的交易对,如ETH/DAI,为这种交易对提供流动性,赚取的交易费有可能会覆盖impermanent loss
  • Inverse correlated pairs:负相关的交易对,是最危险的,他们之间波动方向相反,两者之间的相对波动范围最大。

下面是计算impermanent loss的公式

\[ impermanent\_loss=\frac {2 \times \sqrt {price\_ratio}} {1+price\_ratio} -1 \]

其中:\(price\_ratio\)是价格变化比例

以下是不计算手续费情况下推导过程:

\(et={e'}{t'}=k\)

\(\frac e t= P\)\(\frac {e'} {t'}=P'\)\(\frac {e'} e = \sqrt{\frac {P'} P}\)\(\frac {t'} {t}=\sqrt{\frac {P} {P'}}\),$price_ratio = {P} $

\[ \begin{aligned} V_0 &=e {P'} + t \\ &=e \frac {t'} {e'} + t \\ &=\frac {e{t'} + {e'}t} {e'} \end{aligned} \]

\[ \begin{aligned} V_1 &={e'}{P'} + {t'} \\ &={e'}{\frac {t'} {e'} } + {t'} \\ &=2{t'} \end{aligned} \]

\[ \begin{aligned} L &=\frac {V_1 - V_0} {V_0} \\ &=\frac {V_1} {V_0} -1 \\ &=\frac {2{t'}} {\frac {e{t'} + {e'}t} {e'}} -1 \\ &=\frac {2{e'}{t'}} {e{t'}+{e'}t} -1 \\ &=\frac {\frac {2{e'}{t'}} {et'}} {\frac {et'} {et'}+ \frac {e't} {et'}} -1 \\ &=\frac {\frac {2e'} {e}} {1 + \frac {e't} {et'}} -1 \\ &=\frac {2 \sqrt{\frac {P'} {p}}} {1 + \frac {P'} {P}} -1 \\ &=\frac {2 \sqrt{price\_ratio }} {1 + {price\_ratio }}-1 \end{aligned} \]

总结

优点

  • 完全去中心化,不依赖第三方,任何人都可以基于uniswap构建自己的应用
  • 可以自由地创建任何ERC20交易对
  • 与其他去中心化交易所相比gas费用更低
  • 任何人都可以向uniswap流动池中提供流动性,人人都可以是做市商

缺点

  • 需要依赖套利者去平衡uniswap与外部交易所之间的汇率
  • 对大户不友好,进行大额的交易会造成很大的滑点