1 Uniswap简介
1.1 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(易用性): TokenA换TokenB,在Uniswap也只要发出一笔交易就能完成兑换,在其它交易所中可能需要发两笔交易:第一笔将TokenA换成某种媒介货币,如ETH, DAI 等,然后再发第二笔交易换成TokenB。
-
Gas Efficiency(gas高利用率): 在Uniswap上消耗的gas量是以太坊上的几家主流去中化交易所中最低的,也就代表在Uniswap交易要付的矿工费最少。
-
Censorship Resistance(抗审查性): 抗审查性体现在Uniswap上架新Token没有门槛,任何人都能在Uniswap上架任何Token。这在去中心交易所中很少见,虽然大多数的去中心化交易所不会像中心化交易所那样向你收取上币费,但还是需要提交上币申请,通过审查后运营团队才会让你的Token可以在他们的交易所上交易。
-
zero rent extraction(零抽租): 在Uniswap协议设计中,开发团队不会从交易中抽取费用,交易中的所有费用都归还给流动性提供者。
1.2 Uniswap特点
-
A simple smart contract interface for swapping ERC20 tokens.
Uniswap是一种自动流动性协议,用于基于以太坊的ERC-20代币交换。
-
A formalized model for pooling liquidity reserves.
Uniswap采用了固定的算法,并在以太坊区块链上的不可升级智能合约系统中实施,它取消了对受信任的中介机构的需求,从而优先考虑了权力下放和安全性。
-
An open source frontend interface for traders and liquidity providers.
是一个为交易者和流动性提供者提供的开源的前端接口,基于GPL许可的开源软件。
-
A commitment to free and decentralized asset exchange
致力于免费且分布式的资产交换。每个Uniswap智能合约(或交易对合约)管理由两个ERC-20代币的储备组成的流动代币池。
2 做市
在前面的部分我们知道Uniswap可以实现将一种token换成另外一种token,那uniswap是怎么做到的呢?他和传统的做市商有什么区别呢?
2.1 传统市场上的交易
传统的交易所一般采用的是订单簿来撮合买卖双方,如下图所示:
简单来说就是:买方挂自己的购买数量和价格、卖方挂出自己的卖出数量和价格,交易所对买卖双方进行配对,当买价>=卖价时就促成交易,同时产生一个当前最新价。其特点是:
-
市场上必须要有用户进行挂单,没有订单就没有流动性(市场流动)。
-
订单必须重叠才能成交,即买价高于或等于卖价。
-
需要将资产存储在交易所。
2.2 做市商
传统的交易所(订单薄模型市场)中,买家期望买入某一资产,则卖家必须卖出同一种资产,并且要在价格上达成共识,而买家期望以最低的价格购买,卖家期望以最高的价格卖出,如果两者在价格上无法达成共识,那么将无法达成交易,此时如果想达成交易,要么是买家提价、要么是卖家降价,但当市场上此种资产的流通性较小时,价格达成共识将变得困难,市场流通性变差,此时就需要依靠做市商的参与。简单来说,做市商会在买卖两个方向上挂单,让交易得以达成,避免出现因一方没有挂单而导致流动性降低。资产的流动性对其价值影响极其巨大,如果资产无法在需要的时候变现,那么和白纸无异。在金融市场中,做市商扮演着非常重要的角色,它负责为市场提供充分的流动性,撮合买家和卖家以促成交易。
2017年涌现出的众多DEX都采用传统的订单簿形式(OrderBook)做市商,即由做市商在交易所中上不断创建和调整订单,等待对手吃单,因此也叫被动做市商。
3 Uniswap上的交易
Uniswap是一个运行在以太坊区块链上的流动性协议,支持免信任的代币互换,也即是说,该交易所上的所有交易都是由智能合约自动执行的,用户无需依靠某个中介也无需信任某个第三方。
3.1 提供流动性
在uniswap上,我们也可以查看当前的流动性情况,如下图所示:
我们可以为某一个交易对增加流动性,点击图中「增加流动性」按钮;也可以看某一个交易对流动性的详细信息,如下图所示:
上述的操作可以通过api来实现,Uniswap是一种基于以太坊的协议,旨在促进ETH和ERC20 代币数字资产之间的自动兑换交易。Uniswap完全部署在链上,任何个人用户,只要安装了去中心化钱包软件(当前已经支持的钱包包括MetaMask、WalletConnect、Coinbase Wallet、Fortmatic、Portis),都可以使用这个协议。
3.2 换币
在uniswap上我们可以方便的将我们的ERC20 token换成另外一种ERC20 token,如下所示:
4 uniswap交易做市原理
4.1 整体模型
以Dai-ETH交易对为例,其整体模型如下:
-
任何人可以在uniswap上建立一个双币种之间兑换的池子,由创建者往这个池子里添加这两个币种,添加的数量由第一个创建者决定。池子的创建者也属于流动性提供者。
-
做市商即流动性添加者。以DAI-ETH的池子为例,做市商往池子里添加这两种币种,并获得LP Token(做市凭证)。
-
在做市商提供了流动性以后,用户就可以和这个池子进行交易了,可以选择把DAI换成ETH,也可以把ETH换成DAI。
-
交易的过程中,需要给流动性提供者支付手续费,目前是收取支付币种的0.3%。由于交易用户的手续费直接全部分给做市商,吸引了大资金的玩家进入uniswap提供流动性,大资金的进入会使得用户在交易的时候以更优的价格进行成交,进一步吸引用户进入uniswap进行交易,繁荣了交易的生态。
-
LP token用于跟踪用户资产在总资产池的比率,当用户取消做市时,通过LP token确定赎回资产的份额,同时将LP Token换成DAI和ETH,并同时获得做市期间获得的交易手续费。
4.2 智能合约
Uniswap是通过智能合约来管理两种ERC20代币组成的代币池,每一笔存入、兑换记录都可查可追溯。下图为uniswap网站ETH-DAI兑换的一个截图:
进入以太坊区块查询网站查找区块,其中可以看到这一笔兑换记录(0xeebec7874f46c4452610a11fa6be0264f7f0557f),如下图所示:
4.3 AMM(Automated Market Maker,自动化做市机制)
4.3.1 恒定乘积
uniswap中,代币交易对示例如下图所示:
对uniswap中的任意一个代币交易对,其都遵守:
x*y=k
公式,x、y分别代表交易对的两种代币。协议保证:
当用户要从一个资金池中换出资产时,交易前和交易后池内两种资产的具体数量的乘积相等。
此公式的曲线图如下所示:
从上述图可以看出,由于曲线的斜率是变化的,当交易的数量不同时,价格是不同的。假设交易使得池子里的数量从old position点移动到了new position点,交易的价格等于A tokens spent/B tokens spent( price=△x /△y )。从图可得,若支付2倍的A token,获得的B token小于原来的2倍,根据公式可得价格是变大的。
此机制的核心在于:
报价直接取决于订单的大小
越往曲线右端移动,单位投入获得的收益越少
4.3.2 价格变动推演(不考虑手续费)
接下来以ETH/DAI交易对为例,推演一下在进行代币兑换过程中,两种代币的价格变化。假设做市商已经为这一流动性池注入了10000 DAI(x)和100 ETH(y)的资金,初始时k = 10000 x 100 = 1,000,000。根据公式x*y=k可知,在代币兑换过程中,x、y不断变化,但是k一直保持不变。
4.3.2.1 通过Dai兑换ETH
价格变化如下:
| 兑换 | 兑换数量 | ETH(x)数量 | Dai(Y)数量 | price(ETH/Dai) | 花费ETH | K |
| :——– | :——- | :———– | :———– | :————- | :——- | :—— |
| 初始 | 0 | 100 | 10000 | 100 | 0 | 1000000 |
| 第1次兑换 | 1 | 99 | 10101.01 | 102.030 | 102.030 | 1000000 |
| 第2次兑换 | 4 | 95 | 10526.316 | 110.803 | 443.213 | 1000000 |
| 第3次兑换 | 5 | 90 | 11111.111 | 123.457 | 617.284 | 1000000 |
| 第4次兑换 | 10 | 80 | 12500 | 156.25 | 1562.5 | 1000000 |
| 第5次兑换 | 20 | 60 | 16666.667 | 277.778 | 5555.556 | 1000000 |
| 第6次兑换 | 20 | 40 | 25000 | 625 | 12500 | 1000000 |
| 第7次兑换 | 20 | 20 | 50000 | 2500 | 50000 | 1000000 |
| 第8次兑换 | 10 | 10 | 100000 | 10000 | 100000 | 1000000 |
| 第9次兑换 | 9 | 1 | 1000000 | 1000000 | 9000000 | 1000000 |
显示详细信息
价格变化趋势如下所示:
说明:x轴为ETH数量
4.3.2.2 通过ETH兑换Dai
价格变化如下:
| 兑换 | 兑换数量 | ETH(x)数量 | Dai(Y)数量 | price(ETH/Dai) | 花费ETH | K |
| :——– | :——- | :———– | :———– | :————- | :—— | :—— |
| 初始 | 0 | 100 | 10000 | 0.01 | 0 | 1000000 |
| 第1次兑换 | 100 | 101.01 | 9900 | 0.010 | 1.020 | 1000000 |
| 第2次兑换 | 400 | 105.263 | 9500 | 0.011 | 4.432 | 1000000 |
| 第3次兑换 | 500 | 111.111 | 9000 | 0.012 | 6.173 | 1000000 |
| 第4次兑换 | 1000 | 125 | 8000 | 0.016 | 15.625 | 1000000 |
| 第5次兑换 | 2000 | 166.667 | 6000 | 0.028 | 55.556 | 1000000 |
| 第6次兑换 | 2000 | 250 | 4000 | 0.0625 | 125 | 1000000 |
| 第7次兑换 | 2000 | 500 | 2000 | 0.25 | 500 | 1000000 |
| 第8次兑换 | 1000 | 1000 | 1000 | 1 | 1000 | 1000000 |
| 第9次兑换 | 900 | 10000 | 100 | 100 | 90000 | 1000000 |
显示详细信息
价格变化趋势如下所示:
说明:x轴为Dai数量
4.3.3 价格变动推演(考虑手续费)
为了鼓励用于向Uniswap的流动池中提供更多的流动性,Uniswap会从每笔交易总额中抽取0.3%当成交易手续费,并将手续费全额交给那些将注资金到Uniswap资金池提供流动性的流动性提供者。Uniswap需要手续的地方包括:
-
用ETH兑换ERC20代币,其手续费为ETH的0.3%;
-
ERC20代币兑换ETH,其手续费为ERC20代币的0.3%;
-
Uniswap v1中,ERC20代币兑换ERC20代币,其手续费包括了两部分:一是从ERC20代币兑换为ETH的交易,手续费为ERC20代币的0.3%;从将兑换来的ETH兑换为新ERC20代币,手续费为ETH的0.3%。
注意:Uniswap v1中所有的换币操作都要以ETH为媒介,不过在Uniswap v2中,不依赖ETH就可以换币。
这里还继续使用上面的示例,我们推演一下价格。
4.3.3.1 通过Dai兑换ETH
价格变化如下:
| 第N次兑换 | 兑换数量 | ETH(x)数量 | Dai(Y)数量 | price(Dai/ETH) | 花费Dai | 手续费(Dai) | K(兑换前) | K(兑换后) |
| :——– | :——- | :———– | :———– | :————- | :———– | :—————- | :———- | :—————- |
| 初始 | 0 | 100 | 10000 | 100 | 0 | 0 | 1000000 | 1000000 |
| 第1次兑换 | 1 | 99 | 10101.010 | 102.030 | 102.030 | 31.231 | 1000000.000 | 1000031.231 |
| 第2次兑换 | 4 | 95 | 10526.645 | 110.807 | 443.227 | 147.338 | 1000031.231 | 1000178.568 |
| 第3次兑换 | 5 | 90 | 11113.095 | 123.479 | 617.394 | 228.705 | 1000178.568 | 1000407.274 |
| 第4次兑换 | 10 | 80 | 12505.091 | 156.314 | 1563.136 | 733.019 | 1000407.274 | 1001140.292 |
| 第5次兑换 | 20 | 60 | 16685.672 | 278.095 | 5561.891 | 4640.194 | 1001140.292 | 1005780.486 |
| 第6次兑换 | 20 | 40 | 25144.512 | 628.613 | 12572.256 | 23709.243 | 1005780.486 | 1029489.730 |
| 第7次兑换 | 20 | 20 | 51474.486 | 2573.724 | 51474.486 | 397443.414 | 1029489.730 | 1426933.143 |
| 第8次兑换 | 10 | 10 | 142693.314 | 14269.331 | 142693.314 | 6108414.587 | 1426933.143 | 7535347.730 |
| 第9次兑换 | 9 | 1 | 7535347.730 | 7535347.730 | 67818129.573 | 1533099566240.870 | 7535347.730 | 1533107101588.600 |
显示详细信息
价格变化趋势如下所示:
说明:x轴为ETH数量
4.3.3.2 通过ETH兑换Dai
价格变化如下:
| 兑换 | 兑换数量 | ETH(x)数量 | Dai(Y)数量 | price(Dai/ETH) | 花费Dai | 手续费(Dai) | K(兑换前) | K(兑换后) |
| :——– | :——- | :———– | :———– | :————- | :——– | :———— | :———- | :———- |
| 初始 | 0 | 100 | 10000 | 0.01 | 0 | 0 | 1000000 | 1000000 |
| 第1次兑换 | 100 | 101.010 | 9900 | 0.010 | 1.020 | 0.306 | 1000000.000 | 1000000.306 |
| 第2次兑换 | 400 | 105.263 | 9500 | 0.011 | 4.432 | 5.319 | 1000000.306 | 1000005.625 |
| 第3次兑换 | 500 | 111.112 | 9000 | 0.012 | 6.173 | 9.259 | 1000005.625 | 1000014.884 |
| 第4次兑换 | 1000 | 125.002 | 8000 | 0.016 | 15.625 | 46.876 | 1000014.884 | 1000061.760 |
| 第5次兑换 | 2000 | 166.677 | 6000 | 0.028 | 55.559 | 333.354 | 1000061.760 | 1000395.114 |
| 第6次兑换 | 2000 | 250.099 | 4000 | 0.063 | 125.049 | 750.296 | 1000395.114 | 1001145.410 |
| 第7次兑换 | 2000 | 500.573 | 2000 | 0.250 | 500.573 | 3003.436 | 1001145.410 | 1004148.846 |
| 第8次兑换 | 1000 | 1004.149 | 1000 | 1.004 | 1004.149 | 3012.447 | 1004148.846 | 1007161.293 |
| 第9次兑换 | 900 | 10071.613 | 100 | 100.716 | 90644.516 | 244740.194 | 1007161.293 | 1251901.487 |
显示详细信息
价格变化趋势如下所示:
说明:x轴为ETH数量。这里是两条线,只是蓝色和橙色几乎完全重叠
从上面分析可以看到,大单交易并不是很适合在uniswap上进行,随着一种币种的减少,价格变动剧烈,而大单交易容易滑点从而导致价格变化加剧。
更多信息,参考uniswap-数据推演.xlsx
5 Uniswap V2
Uniswap V1上的每个交易对中都有ETH,如果要将代币兑换成代币B,必须先用代币A买入ETH,然后再用ETH买入代币B,因此,交易者需要支付两笔交易费和gas费,Uniswap V2将不受此限制。具体见下图(这里的图来自有关 Uniswap V2 的一切,因为别人画的比较好,所以就没有自己画)。
-
在Uniswap V2中,直接通过Dai兑换Link币
-
在Uniswap V2中,通过Dai兑换ETH然后兑换Link币。
-
在Uniswap V2中,实现任意币种之间的兑换。
6 流动性资产损失
6.1 示例说明
Uniswap中存在流动性资产损失,下面以ETH(X)-DAI(Y)作为示例进行解释。继续使用上面表格中的数据,假设开始的时候X=100、Y=10000,其中有个流动性提供者往池中注入了1个ETH和100个DAI,占整个流动性池中代币总量的 1%。经过几笔交易之后,价格发生了变化(交易费忽略不计)。第三次兑换后,池子中ETH减少5个,DAI增加23.457个。如下所示:
| 兑换 | 兑换数量 | ETH(x)数量 | Dai(Y)数量 | price(ETH/Dai) | 花费ETH | K |
| :——– | :——- | :———– | :———– | :————- | :—— | :—— |
| 初始 | 0 | 100 | 10000 | 100 | 0 | 1000000 |
| 第1次兑换 | 1 | 99 | 10101.01 | 102.030 | 102.030 | 1000000 |
| 第2次兑换 | 4 | 95 | 10526.316 | 110.803 | 443.213 | 1000000 |
| 第3次兑换 | 5 | 90 | 11111.111 | 123.457 | 617.284 | 1000000 |
流动性提供者投入的代币价值(占总量的1%),即拥有ETH=0.9、DAI=111.111,假设此时提取并这算成DAI,折算后=222.324DAI;对于此时拥有1ETH、100DAI的用户,折算后其拥有223.457DAI,二者对比即少了1.124DAI,这就是Uniswap中的流动性资产损失。
实际中,因为每次兑换都有手续费,手续费的累加将比较客观,所以流动性提供者最终的收益是手续费收益 - 流动性资产损失的结果。
收益分析
流动性提供者实际可获得的收益是用累计的交易费减去由价格差导致的暂时性亏损所得的余额。
如果长期以来价格起伏过大,造成的损失将远远超过交易费带来的收益。
如果Uniswap能够能够吸引到足够多的流动资金,流动性提供者就能从价格波动中获得收益。
6.2 公式解释
这里暂不考虑费用的影响。
6.2.1 恒定乘积公式
恒定乘积公式: X * Y = K;X、Y代表两种代币在池子中的数量,即流动性
uniswap中价格取决于兑换关系,所以有:
X兑换Y的价格: Pxy = X / Y
Y兑换X的价格: Pyx = Y / X
uniswap提供的服务其实就是用X来换Y或者用Y来换X,这里我们假设通过X来换Y,经过一段时间以后X减少了△x、Y增加了△y,同时需要保持恒定乘积,即
恒定乘积公式:(X-△x) * (Y+△y) = K;
假设我们用Pxy表示uniswap池子中X兑换Y的价格,那么有:
结论:被兑换的token越多,uniswap中兑换价格越高。
6.2.2 流动性公式
由以上公式可以得出,在总流动性恒定的情况下,我们可以计算出特定价格下每个流动性池的大小。
X的流动性为:
Y的流动性为:
整理一下上面公式后得到:
X的流动性变化值:
Y的流动性变化值:
结论:uniswap池中token流动性受兑换价格影响。
6.2.3 资产损益公式
假设期初时候X的价格为Px1,Y的价格为Py1,经过一段时间后X的价格为Px2,Y的价格是Py2,那么最开始时存入资产价值为:
期初存入价值:M1 = X * Px1 + Y * Py1
提现时(假设全部提出)存入价值:M2 = (X - △x) * Px2 + (Y + △y) * Py2
价值变化△m = M2 - M1
整理后的公式为:
假设Y是DAI,而DAI是稳定币,那么公式可以调整为:
结论:
- 资产损益受X期初、期末价格以及uniswap中x-y兑换价格影响;
- 如果uniswap池中的x-y兑换价格较大和市场上二者价格偏离,会有套利者进场从而逐步拉平兑换价格,最终价值变化还是收x价格变化影响。
更多信息可以参考:Uniswap 会是下一个聚宝盆吗?、最强Defi协议Uniswap原理分析
7 闲话
Uniswap协议本质是在抢交易所的生意,用户不用依赖任何交易所即可完成代币之间的兑换;在Uniswap上,无需挂买单或卖单,也不用进行繁重的计算。流动性提供者也可以一劳永逸,订单和仓位管理方面的开销也明显减少。
值得注意的一点是:既然可以不依赖交易所就能完成代币兑换,那么必然可以实现发币功能,即,可以简单地认为,即便是没有任何中心化的交易所,也可以发币了。当然uniswap上的发币还是有一些规则和规范的。
对于用户而言,uniswap提供了两种能力:
对于希望通过提供流动性来进行获益的用户而言,用户可以将自己拥有的ERC20存入uniswap的流动性提供池,通过提供流动性而获益。
对于需要流动性的用户而言,用户可以在uniswap上将自己的一种ERC20 token换成另外一种ERC20 token,这个过程中不用有任何人挂卖单,因为另一种token由流动性提供者提供。