剖析DeFi交易产品之UniswapV3:集中流动性、协议手续费、价格预言机

剖析DeFi交易产品之UniswapV3:集中流动性、协议手续费、价格预言机

UniswapV3于2021年5月上线,相比UniswapV2,改动很大,也变得复杂很多,最主要的有以下这几点改动:

  • 引入了集中流动性(ConcentratedLiquidity)机制

  • LPToken改为了不可互换的NFT

  • 每个交易对可以有多个不同费率的池子

  • 协议手续费治理更灵活

  • 改进了价格预言机

其中,最核心的改动就是引入了集中流动性机制。所谓集中流动性,主要是说流动性提供者(LP)可以将其提供的流动性”限制“在任意价格区间内来”集中“其流动性。从直观上来说,UniswapV3中,用户添加流动性的时候,需要设置一个价格区间,如下图所示:

默认时这个价格区间是全范围,即**(0,∞)**。LP可以自己修改低价和高价为任意值,即LP可以设置自己要提供的一个价格区间。而设置了有限的价格区间后,那提供的该流动性也只有在该价格区间内才有效。为了更好理解,下面举个例子说明一下。

有两个LP,A和B,分别在不同价格区间提供了流动性,A在区间(1000,2000)内提供了流动性,而B则在区间(2000,3000)内提供了流动性。那当交易价格为1500时,发生的交易只会和A所提供的流动性进行交易,交易手续费也归A所有,而B提供的流动性不参与任何交易,也得不到任何手续费。不过,当价格上涨到2500时,进入到了(2000,3000)的价格区间,这时候发生的交易则只会和B所提供的流动性进行交易,交易手续费也归B所有了,而A的流动性则变成无效了,也得不到手续费了。当价格又跌回到(1000,2000)区间时,A的流动性又再次变为有效,而B的流动性又再次变为无效。

集中流动性机制,会使得大量LP的流动性聚合在包含当前价格的区间内,能有效提高池子的资金利用率。比如下图为USDC/ETH的流动性分布:

大部分流动性集中在了当前价格附近,这也是大部分池子都比较常见的状态。

不过,集中流动性机制,实现起来其复杂度也大幅增加,背后的数学原理也不太容易理解,还引入了其他概念,比如tick。

因为在UniswapV3中,LP提供的流动性是分为多个不同区间的,那为了方便计算不同区间的流动性和手续费分配,UniswapV3就将整个价格范围划分为了多个离散的价格点,这些价格点就称为tick,每个价格点tick都对应于一个实际价格.

该公式表明了,当tick为0时,价格为1;当tick为1时,价格为1.0001;当tick为2时,价格为1.0001^2。也即是说,相邻价格点之间的价差为0.01%。当然,tick也可以为负值,为负值时表明价格p小于1。

UniswapV2添加流动性时,两个代币的价值是相等的。直到你移除流动性时,两个代币的价值依然也是相等的。但在UniswapV3中则不是.

上图中,ETH/USDC当前价格为1806.97,待添加的流动性价格区间为(1699,1900)。然而,可以看到,当要添加1ETH时,对应需要添加的USDC并不是当前价格的数量1806.97,而是达到了2184.99,两个代币的价值是不相等的。另外,添加流动性之后,如果ETH/USDC的价格下跌,你流动性里的ETH会增多,USDC则减少;反之,如果价格上涨,则你流动性里的ETH会减少,USDC会增多。

基于这种特性,还可以实现限价单功能。比如,假设ETH当前价格为2500,用户觉得价格可能会跌到2000以内,那就可以在2000附近设置一个很短的区间,比如设置(1999,2000)。这时候,因为整个价格区间都低于当前价格,用户提供的流动性只需要充值USDC一种资产即可。

这时候,相当于用户挂了一个价格为2000的限价买单。当价格跌下来,进入了(1999,2000)这个价格区间的时候,有人交易时就会将该区间内的USDC换成ETH(实际其实为WETH),直到价格完全穿过价格区间的上限,那池子里的所有USDC都被换成了ETH。这时候,用户撤走流动性,就相当于之前所挂的限价买单成交了。不过,与传统的限价单相比,有两点需要注意:

  • 如果价格不能穿过整个价格区间,那就只有部分USDC会被换成ETH

  • 转换完成后,需将流动性移除,否则一旦价格又回到该价格区间,那池子里的ETH会被交易换回USDC

UniswapV2中的流动性是整个池子共享的,每个人占有多少流动性可以用份额来表示,而份额是可以互换的,所以可以用ERC20Token来作为流动性代币。但UniswapV3中,流动性增加了价格区间的限制之后,就不再是共享的了,每一次添加的流动性都基本是独一无二的,因此,已经不适合继续使用ERC20来作为流动性代币,但使用ERC721却非常合适,每一次添加的流动性也称为一个头寸(position),就用一个单独的NFT来表示。

UniswapV2中,每个交易对有且仅有一个流动性池,且交易手续费率都是统一的千分之三。但UniswapV3可以为同个交易对创建不同费率的池子,即token0、token1加上fee三个字段组成了一个Pool的唯一性。一开始的时候支持了0.05%,0.3%和1%的费率,之后在2021年11月时通过DAO治理又增加支持了0.01%的费率。

UniswapV2中,还有一个协议手续费,和交易手续费一样,也是一个基于全局的费率,如若打开收取协议手续费的话,则可获得交易手续费的1/6。而UniswapV3的协议费率设置更灵活,不再是固定的1/6,而是1/N或0,其中,N是可配置的,范围为4<=N<=10。而且,还可以基于每个池子设置不同的协议费率。比如,可以设置A池为1/6,B池设为1/8,C池则为0。

价格预言机也做了升级,之前讲区块链预言机章节中已经介绍过UniswapV2和UniswapV3的预言机。这里主要再补充一点,V2的方式是直接记录价格的累加值,使用时再除以时间间隔,这是一种算术平均。而V3累加的是log(price,1.0001)也就是价格的幂,使用时再除以时间间隔,这是几何平均。几何平均数相比算术平均数,能更好的反应真实的价格,受短期波动影响更小。另外,使用几何平均,也是因为合约中记录了tick序号,序号是整型,且跟价格相关,所以直接计算序号更加节省gas。

UniswapV3在代码层面的架构和UniswapV2的变化则不大,合约层面,主要还是两个库:

  • v3-core

  • v3-periphery

v3-core的核心合约就两个:

  • UniswapV3Factory:工厂合约

  • UniswapV3Pool:流动性池子合约

v3-periphery的核心合约也是两个:

  • NonfungiblePositionManager:头寸管理合约

  • SwapRouter:兑换路由合约

与UniswapV2不同,不再由Router合约作为添加流动性、移除流动性和兑换交易的全部入口,而是把流动性相关的功能放到了单独的合约NonfungiblePositionManager,而SwapRouter主要只用于交易入口。

后续文章我们会依次讲解下这四个核心合约。

为您推荐