• uniswap_v3


    v2 版本:x * y = k

    v3 版本:

     1. 介绍

    UniswapV3与其早期版本⼀样,基于相同的恒定乘积算法,但提供了⼏个重要的新特性:

    (1)聚焦流动性(ConcentratedLiquidity):做市商(LPs)有能⼒通过将流动性“限定”在任意价格范围内来聚焦流动性(早期版本提供的是()的所有价格范围。)。这提⾼了流动池的资⾦效率,允许做市商接近其钟意的资产曲线,同时能与流动池中其它⼈提供的流动性

    有效集成。在第2章对本特性作了描述,第6章阐述了如何实现聚焦流动性。

    (2)灵活的⼿续费:⼿续费不再仅限于0.3%。每个交易对的费率在初始化时设置(每个交易对可以有多种费率)(3.1⼩节)。初期⽀持的费率有0.05%,0.30%,和1%。UNI治理可以增加新的费率设置。

    (3)协议费治理:UNI治理在协议费占⼿续费⽐例的设置⽅⾯,拥有更多的灵活性(6.2.2⼩节)。

    (4)增强的价格预⾔机:UniswapV3为⽤户提供⼀种查询最近价格累计值的⽅法,避免在度量TWAP时,需要精确指定开始和结束时间来获取累计值(5.1⼩节)。

    (5)流动性预⾔机:合约提供⼀种时间加权平均的流动性预⾔机(5.3⼩节)。UniswapV2核⼼合约设计成不能升级,所以UniswapV3完全由⼀套新合约实现。UniswapV3核⼼合约也不能升级,除了治理可以调整部分参数(⻅第4章)。

    2  聚焦流动性(ConcentratedLiquidity)

    UniswapV3的核⼼理念是聚焦流动性:在指定价格区间内提供流动性。

    其中和是两种代币X和Y的数量,是常量。换⾔之,早期版本的设计是在的整个价格范围内提供流动性。这利于实现,并且允许有效地汇聚流动性,但意味着流动池中⼤部分资产永远不会被利⽤。

    考虑到这⼀点,允许做市商在⼀个⽐⼩的价格区间内聚焦他们的流动性,是合情合理的。我们将聚焦到有限价格区间的流动性称作:⼀个头⼨(aposition)。⼀个头⼨只需要在它的价格区间内维持⾜够资⾦以⽀持交易,因此在保持恒定乘积算法不变的情况下,可以在该价格区提供更⼤的资⾦量(我们称之为:虚拟资产)。

    流动性含义(Liquidity - L)

    乘积固定的交易模型,满足资金池中的两种代币金额满足:xy = K。如果设定 K=L^2 的话,xy = L^2。L 就是我们说的流动性。

    由乘积固定的交易模型得出如下的公式:

     在已知 L 和 sqrt(P) 的情况下,也能推导出资金需求量 x 和 y。

     

     通过公式 6.6,在流动性不变的情况下(不添加删除流动性),流动性可以看成是单位「价格波动」的 y 资金量的变化。「价格波动」打上引号是因为事实上是 sqrt(P) 的变化。

     这个是 Uniswap V3 核心公式(6.7),用相对值(资金和价格相对值)来计算流动性。所谓的流动性,就是单位「价格变化」的资金量。在一定的交易量的情况下,如果流动性好,价格变化就小,流动性不够的话,价格波动就大。

     特别注意的是,一个区间上的流动性和 V2 的普适的流动性不同。一个区间上的流动性,重点在「区间上」。不同区间的流动性没有可比性。V2 的流动性和区间上的流动性的区别如下图:

     V2 的流动性是「普适」的,在所有价格点上流动性相同。V3 的流动性是由一系列不同区间上的流动性组成。相对来说,在当前价格左右的流动性比较高。流动性提供者 LP 只有提供了可供交易的流动性才能获取交易费。为了获取更多的交易费,为了提高资金的利用率,流动性提供者会将资金提供在合理的价格波动范围内。也就是说,在某个区间 swap 交易产生的手续费,只有该区间流动性提供者才能获取手续费。为了计算每个区间获取的手续费,引入了 Tick 的概念和计算方法。

    Tick

    在区间上提供流动性,带来很多复杂的情况:区间和区间的重叠覆盖。因为不同区间的流动性没有可比性,某个交易费并不能混入到流动资金中,等删除流动性时候一并提取。为了解决这个问题,Uniswap V3 引入了 Tick 的概念。交易费用实时结算并单独记录,并不混入流动资金中。虽然整个区间和区间的流动性没有可比性,但是,在具体的某个价格点上(一个价格片上),流动性是可比较的。Uniswap V3 将整个价格范围 (负无穷到正无穷) 分成一个个的 Tick (价格点):

     后一个价格点的价格是前一个价格点价格基础上浮动万分之一。

    每个 Tick 也有一个唯一的序号。

    区间(Position)可以由两个 Tick 表示。

    逻辑上交易手续费可以一个个的 Tick 计算,并在每一个 Tick 上根据流动性的占比进行交易分配。

    先看看一个 Tick 范围的 swap 的计算。

    Tick 内的 SWAP

    假设有一个很小的量的 y,需要 swap 为 x。通过 6.13 的公式,可以计算出因为 y 的变化导致的价格变化。

     再利用 6.15 的公式可以算出换取的 x 的量。

    Uniswap V3 针对同样的交易对设置了不同的交易费:0.05%,0.3% 以及 1% (还可以添加其他费率)。

    如果是从 Y 换取 X,则在换取之前先扣除手续费再进行上述的交换。

    在同一交易池中只支持一种费率。

    也就是说,在一个交易池中支持不同的价格区间但是都是同样的费率。如果需要添加同样交易对的不同交易费的交易池,必须创建新的交易池。

     接下来,深入讲解一下 添加 / 删除流动性以及交易费用的计算逻辑。

    添加 / 删除流动性

    V3 的添加 / 删除流动性是当前价格情况下在某个区间添加或者删除流动性。

    所有的流动性添加 / 删除流动性采用如下的公式:

     注意,价格变化并不是指区间的大小,而是在某个区间上提供流动性,相对当前价格,「需要相应资金变化」对应的价格变化。

    分为三种情况,想要添加的流动性区间和当前价格的关系。

    • 当前价格处于流动性价格区间 (il <= ic < iu)

     因为价格在区间范围内,

    如果价格滑动到 il,则需要提供 y 资金。

    如果价格滑动到 iu,则需要提供相应的 x 资金。

    所以,

    对于 delta_Y 来说的,价格变化为 sqrt(P) - sqrt(p(il));

    对于 delta_X 来说,价格变化为 1/sqrt(P) - 1/sqrt(p(iu))。

    • 当前价格低于流动性价格区间

     因为当前价格远低于 il,即使从当前价格向 iu 滑动,也只需要 x 的资金,不需要 y 的资金。

    所以,在这种情况下,delta_Y = 0。

    因为从 il 滑向 iu 需要整个区间的 x 的资金,对于 delta_X 来说,价格变化为 1/sqrt(il) - 1/sqrt(p(iu))。

    • 当前价格高于流动性价格区间

    和第一种情况类似,不重复分析了。

    Swap 交易费用

    Uniswap 最复杂的逻辑是计算交易费用并分配。在添加和删除流动性之前需要将相应的交易费用提取。

    Tick 上的总流动性

    在某个 Tick 上可以存在多个区间。在计算交易费用时,需要平摊这些费用给所有在这个 Tick 上多个区间的总的流动性。在每个区间的边界的 Tick 上记录下 delta_L (所有以这个 Tick 为边界的区间的流动性总和)。

    存在一个全局状态:liquidity,保存当前价格对应 Tick 的流动性总和。当价格波动,穿过某个 Tick 时,会进行流动性的增加或者减少(取决于价格波动方向)。

    举例来说,价格从左到右穿过区间,

    当穿过区间的第一个 Tick 时,流动性需要增加,

    穿出最后一个 Tick 时,流动性需要减少,

    中间的 Tick 都没有流动性的增加和减少(delta_L 为 0)。

    区间(Position)上的交易费用率

    计算一个区间上的交易费用率,采用总的费用率减去区间外的费用率的方法。

    在一个区间的边界 Tick 上记录 feeGrowthOutside。

    所谓的 feeGrowthOutside,就是「另外」一个方向上总的费用率。

    另外的一个方向是相对穿过当前 Tick 的方向而言。

    当价格从左到右穿过一个 Tick,feeGrowthOutside 指的是 Tick 左边所有区间的费用率。

    简单的说,就是价格要去方向的相反方向所有区间的费用率。

    feeGrowthOutside 用 fo 表示。

    因为 fo 是一个 Tick 的两个方向的总的费用率,两个方向的费用率的总和肯定是等于 fg (全局的费用率)。

    所以当穿过一个 Tick 时,这个 Tick 上的 fo 要进行翻转:

    当一个区间创建时,区间边界上 Tick 的 fo 需要初始化:

     如果当前的价格大于 Tick 的价格时,因为即使当前价格在设置的区间内,但是之前费用也不会分到。

    所以,可以简单的假想为所有的费用发生在 Tick 价格之下,也就是 fo=fg。

    如果 Tick 的价格大于当前价格,价格还没有穿过 Tick,因为假设了之前所有发生的费用发生在 Tick 价格之下,Tick 之上是没有费用的,所以 fo=0。

    在理解了这些逻辑的基础上,在 swap 的过程中,随着价格的波动,一个区间上,超过最高 Tick 的费用率以及低于最低 Tick 的费用率可以用如下的方式计算:

     以低于最低 Tick 的费用率的计算为例,如果 ic>=i (当前的价格是高于最低 Tick 的),低于 Tick 的所有的费用率就是 fo (定义如此)。如果 ic

     获取的费用率的基础上,用费用率乘以区间的流动性可以计算出该区间收取的费用。

    总结

    Uniswap V3 版本核心思想是流动性集中。流动性提供者可以在某个区间提供流动性,提高资金使用率。在某个区间获取的交易费,由所有在该区间的流动性提供者均分。Uniswap V3 设计了区间粒度-Tick,并且推导了流动性添加 / 删除以及费用计算的过程。在之基础上,Uniswap V3 也更新了价格预言机的实现。

    看的脑壳疼,md

    https://www.jinse.com/news/blockchain/1057182.html

  • 相关阅读:
    如何理解python中的if __name__=='main'的作用
    如何在阿里云上部署war包到tomcat服务器
    如何在windows上部署war包到tomcat服务器
    解决:mysql5.7 timestamp默认值0000-00-00 00:00:00 报错
    python3中的unicode_escape
    python中的excel操作
    python的logging模块
    python中的SMTP发送邮件
    python中的字符串
    一道问题引出的python中可变数据类型与不可变数据类型
  • 原文地址:https://www.cnblogs.com/30go/p/16034719.html
Copyright © 2020-2023  润新知