SkyOne Profile JPG

AMM演变

Reservoir Part1 Part2 Part3

Image

Part1


Uniswap

最基础的即是 Uniswap, UniswapV2 的核心在于公式

xy=k x*y=k

这个恒等公式, 其中 k 为常数, x 和 y 分别为两种 Token 的数量 相应的函数曲线如下, 注意 这条曲线永远不会出现 x=0 或者 y=0 的情况.🍎

举个例子, x 为 AVAX, y 为 USDC, 假设最开始的有一个人甲来添加流动性, 目前市场价格为 100USDC=1AVAX, 因此, 他将 20AVAX 和 2000USDC 放到池子里, 那么此时 k=40000, 这时候乙来想要将手里的 5AVAX 兑换成 USDC, 那么就要经过甲设定的这个池子, 由于乘积一定是恒等式, 因此 👇🏻

  1. yi=k/xiy_{i}=k/x_{i},
  2. xi=25x_{i}=25,
  3. yi=40000/25=1600y_{i}=40000/25=1600,
  4. 由于 y 的数量由 2000 变成了 1600, 因此乙用 5AVAX 拿走了 400USDC,
  5. 这个时候池子里由最开始的 20AVAX+2000USDC 变成了 25AVAX+1600USDC, 则代表 AVAX 的价格由原来的 100 跌到了 64, 那么由乙做的这笔 tx 对于整个池子的价格影响[Price Impact] 则是 (64100)/100=36%(64-100)/100=-36\% . 价格影响是 恒定乘积做市商 的缺点之一,
  6. 为了避免出现巨大的 Price Impact , 则需要确保池子足够深, 可以让用户来兑付, 如果池子里有 200 万 USDC 和 2 万 AVAX, 则用户乙最终会收到 499.875USDC 造成的影响忽略不计,
  7. 这样做的好处则是简单明了, 并且给了任何人都可以为市场提供流动性, 而这一举动 在过去只能是大型金融机构来做.

Balancer

当我们需要多种资产在一个池子里的时候, 我们可能就会用到 Balancer, 其核心公式为:

xwxywyzwz=kx^{w_x}y^{w_y}z^{w_z}=k

除此之外, Balancer 允许我们以不同比例向池子里添加配对资产, 比如我们可以不必 50:50 添加流动性, 可以以 80:20 的比例来添加, 这样做的好处 👇🏻

  • 你更看好某种资产, 并希望它在你的投资组合中占据更多的份额

  • 更高的权重所对应的资产会承受更小的无常损失

这里重点讲一下 Balancer 不同权重的 双代币配比的知识, 首先明确知识点, 其次举例证明 🍌

  1. 知识点

    • 更高的权重配比, 代表着 更低的无常损失
    • 更高的权重配比, 在代币价值升值过程中, 所拿到的利润更大
    • 相反的 风险在于 更低的权重配比则是更高的无常损失 依旧 更低的权重配比则是代币上涨过程中利润更小
  2. 举例说明

    • 假设, 当前两种代币 分别为 SOL[xx] 和 USDC[yy], 当前 SOL 的价格是 10U
    • 甲想要创造一个 SOL:USDC = 80:20 的池子, 所以 甲创建了一个池子, 里面有 8 个 SOL 和 20 个 USDC, 成本是 100U
    • 假设当前 SOL 价格涨了, 涨到了 20U, 那么当前池子有 6.9 个 SOL 和 34.5 个 USDC, 两种 Token 数量计算过程如下 👇🏻
      1. wx=0.8,wy=0.2w_{x}=0.8, w_{y}=0.2, 计算最初的 k 值 : 80.8200.2=k=9.6098^{0.8}*20^{0.2}=k=9.609
      2. 1SOL = 20U = 20USDC, 所以当前价格下 x20:y1=80:20x*20:y*1=80:20 , 则推出 y=5xy=5x
      3. 根据 k 不变, 则有 x0.8y0.2=x0.8(5x)0.2=k=9.609x^{0.8}*y^{0.2}=x^{0.8}*(5x)^{0.2}=k=9.609, 因此 x 的值为 6.9 相应 y 则是 34.5
    • 验证知识点
      1. 一直持有 SOL8 个 和 USDC20 个 当价格涨上来之后, 价值是 100U --> 180U
      2. 如果以 80:20 添加/建池子去了, 那么 100U --> 172.5U[6.9*20 + 34.5*1], 则无常损失是 7.5U,池子价值 172.5U
      3. 如果以 50:50 添加/建池子, 那么 100U --> 这里如何计算的可以看下面计算过程
        1. 100U 拿来建 50:50 的池子, 那么一定是 5 个 SOL : 50 个 USDC, 此时 k=15.81
        2. 当 SOL 由 10U --> 20U 的时候, 池子里有 3.54 个 SOL 和 69 个 USDC 总价值为 138U
        3. 无常损失 由 150U --> 128U, 无常损失是 22U., 池子价值 128U
  3. 这里先说一个现象 🔴

    1. 50:50 的池子 用的表达式 是 x0.5y0.5=kx^{0.5}*y^{0.5}=k, 所以 k=15.81
    2. 之所以用 0.5 次幂 是因为上面的一大溜计算都是 [保持比例相应 并且 两者相加为 1] 的原则, 所以上面是 0.8 次幂和 0.2 次幂
    3. 其实用 x1y1=kx^1*y^1=k, 算出来的结果是一样的, 只不过中间值 k 不同而已
    4. 当然, 上面关于 0.8 次幂和 0.2 次幂 也可以相应的换成 1.6 次幂和 0.4 次幂
    5. 结果一样的, 只是计算方式不同
  4. 一个关于计算当前池子价值的小技巧, 公式如下

    ΔPoolUSD=i(ΔPUSDi)wi\Delta Pool_{USD}=∏_{i}(\Delta P_{USD}^i)^{w_i}

    同样以上面的例子 SOL 10U --> 20U, 翻了一倍,

    ΔPUSDSOL=2\Delta P_{USD}^{SOL}=2, 相应的 wi=0.8w_i=0.8 , 所以池子的变化是 20.8=1.7412^{0.8}= 1.741,

    即池子价值变为原来的 1.741 倍,


Curve

上面介绍的 Balancer 和 Uni 都是恒定乘积, 致命的缺点之一则是价格影响, Curve 则是用的恒定加和, 可以有效解决这个问题, Curve 的核心公式很复杂, 但是可以提炼成如下形式

A(x+y)+xy=kA*(x+y)+xy=k

其中 A 是一个放大系数, 取决于池子内的资金情况, 如果池子内变得非常不平衡, A 就会减小, 以最小化(x+y), 那这样的话, 就会非常像 Uni 这样的恒定乘积做市商, 相反的, 如果池子内的资金情况很平衡, 则 A 会变大, 以最大化(x+y) 池子则会变成 恒定加和做市商

表现则像中间的这条蓝色曲线, 在中间部分的时候, 是恒定加和做市商, 当池子内变得不均衡的时候, 则是像 Uni 一样的恒定乘积做市商


Bancor

Bancor 的特点在于它提供了 100%的无常损失保护, 听起来很棒, 但是这部分的损失 其实是给到了 BNT Token 的持有者来承担


Part2


Uniswap V3

UniswapV2 版本允许任何人都可以提供市场流动性, 足够简单明了, 相应的缺点则是无常损失, 价格影响以及资金利用效率, 因此 新一代 AMM 随之诞生

V3 的核心观念在于集中流动性, 即你注入的流动性比 V2 可以更有效的使用率, 以 USDC/USDT 池子为例, 价格应该在 1 附近浮动, 因此将流动性聚集在这里是很棒的, 在 V2 中, 你只能在(0,+)(0,+∞)添加流动性, 这意味着, 你提供的流动性不管在价格 1 还是在 500 的时候 起到的作用并没有什么差异, 而两者之间的价格能达到 500 的情况十分罕见, 所以 这是对于资金效率巨大的浪费. 如果你把相同数量的流动性都放在[0.95, 1.05]不是更好吗. V3 则是允许这样做, 可以让市场提供流动性的人 来 自己选择 想要提供流动性的价格范围.

在 V2 中 永远不会出现池子里只有一种 Token 的情况, 即 X 轴或者 Y 轴都不可能出现为 0 的情况. 因此 可以参考下图:

这里仍然满足 xy=kx*y=k的公式, 只不过变成了 (xr+L/Pb0.5)(yr+LPa0.5)=L2(x_r+L/P_b^{0.5})(y-r+LP_a^{0.5})=L^2, 这个公式 则有可能出现 x 或者 y 为 0 的情况, 这意味着 如果 价格一旦超出了 [a,b] 的这个区间, 那么池子内只会留下一种资产, 比如 Alice 提供 AVAX/USDC 流动性, 价格区间则是 [95,105]

  • 价格低于 95 的时候, 池子里面全是 AVAX
  • 价格在 95 到 105 之间的时候, 池子里则有两种资产
  • 价格在 105 之上的时候, 池子里面全是 USDC

目前来看, UniV3 听起来非常棒, 但是人们为什么非常讨厌它呢, V2 的成功在于人们在添加流动性的时候非常简单, 并且池子中的流动性都是相同的, 所以可以用 LP Token 表示, 同样可以轻松的进行收益计算, 非常适合懒惰的投资者. 而在 V3 中, 没有两个流动性是相同的, 所以只能用 LP NFT 来表示, 而 NFT 会让收益计算变得比较复杂.

除此之外, V3 会要求你不断重新调整提供流动性的范围, 以确当前市场价格在你提供的流动性的范围内.


Curve V2

CurveV2 让 Curve 首次涉足广义 AMM in 关于, 其新版本承诺多种不相关资产的低滑点交易.

目前 Curve 上有三个 V2 的池子, 它的工作方式类似于 CurveV1, 但是在价格锚定方面进行了更新, 即使用指数移动平均线的内部价格预言机引用的当前价格为目标

V2 的美妙之处在于不想 UniV3 那样手动调节价格范围, 而是矿池会自动重新平衡预言机价格周围的流动性

举个例子, 比如 V2 池子里是 BTC/USDT, 当前价格是 $30000, 那么池子中的绝大部分流动性会聚集在这里, 只有一小部分会分布在更大的价格范围内. 如果价格到了 $40000, 那么资金池会自动重新平衡, 流动性将会发生变化, 因此大部分流动性重新聚集在 $40000 的焦点这里. 因此, 池子里的每个流动性头寸都是相同的, 并且可以用 LP Token 来表示, UniV2 的优点又回来了.

然而, 不会有东西是完美无缺的, 如果我们查看数据, 会发现与 UniV3 相比, 交易量非常非常低. 数据如下: 👇🏻

  • CurveV2 的 Tricypto Pool(BTC, ETH, USDT)
    • TVL = $480M
    • Daily volume = $107M
    • Vol / TVL = 22%
  • UniV3 的 USDC/ETh 0.05% Pool
    • TVL = $328M
    • Daily Volume = $693M
    • Vol / TVL = 211%

就兑换率而言, CurveV2 几乎低了 10 倍, 因此 我怀疑可能是以下的几点造成

  1. 不友好的用户交互界面
  2. CurveV2 的定位并不是通用的 Dex 来宣发
  3. 无法容纳长尾资产[即不利于垃圾币交易]

CurveV2 的优点

  • 同质化的流动性
  • 资金效率的提高
  • 单一资产的质押

CurveV2 的缺点

  • 无法提供长尾资产流动性

TWAMM

全称叫做 Time-Weighted Average Market Maker , 由 Paradigm 的这篇文章提出, 其核心思想在于将大的订单随着时间拆解成小订单, 这样做的结果是有利于更好的按照当前的市场执行成交, 因为在每一笔小的订单完成之后, 如果有足够的价差, 则会有套利者扳平价格

这就是鲸鱼样做的事情, 如果 Michael Saylor 决定购买一亿美金的 ETH 的时候, 他会随着时间的推移通过购买更小的块来成交, 效果如下图所示, 最理想的环境则是 Infinite Pieces per order

然而, 由于链上的所有交易都是公开的, 即使是子订单也容易受到抢先交易的影响, 例如 Alice 和 Bob 都想购买 AVAX, 谁在后面谁吃亏 因为前面的购买者会推高购买价格. 为了解决这一问题, 买入和卖出组合在一起.

那关于三明治攻击, 对交易会产生影响吗? 从技术上讲, 任何公共交易会比较容易受到三明治攻击, 但是随着 TWAMM 订单在块与块之间执行, 使得三明治交易变得比较艰难, 因为攻击者需要确保它是上一个块的最后一个交易者和下一个块的第一个交易者

想象一种情况, AVAX 目前是 100U 池子里面有 1mAVAX 和 100mUSDC, Alice 想要将手中的 100mUSDC 换出去, 而 Bob 想要将手中的 1mAVAX 换出去.

如果 Alice 先执行, 那么 Alice 会获得 0.5m 的 AVAX, Bob 获得 133m 的 USDC, Bob 获利更大

如果 Bob 先执行, Bob 获得 50m 的 USDC, Alice 获得 1.33m 的 AVAX, Alice 获利更大

很明显, 在传统 UniV2 中, 谁在后面执行交易, 谁的获利更大

但是在 TWAMM 中, 则会变成 Alice 和 Bob 直接进行交易, 即 Alice 用 100mUSDC 获得了 1mAVAX, 而 Bob 则是用 1mAVAX 获得了 100m 的 USDC

❤️ 优点

  • 允许更大金额的交易, 并且和传统金融很像

💔 缺点

  • 还是会收到三明治攻击
  • 更大的 gas 花费
  • 本身并不是 AMM, 而是构建在其他 AMM 之上的

RMM

全称为 Replicating Market Marker, 其核心在于投资组合和目标收益相匹配的做市商. 由于解释起来太过麻烦, 因此用Primitive Finance为例, 在 Primitive 中, 流动性提供者赚取的费用, 和有担保看涨期权的收益相匹配.


有担保看涨期权

这里简单介绍一下期权的基本知识, 看涨期权[Call] 会赋予持有人权利但不是义务 在到期时以设定价格购买某种资产, 相应的, 看跌期权[Put]会赋予持有人权利但不是义务 在到期时以某种价格售卖某种资产. 举个例子, 目前 6.22 号, AVAX 的价格是 100, Alice 从 Bob 手中, 购买了价格为 110 的看涨期权, 行权日是 7.1 号,.

  • 如果 AVAX 涨到了 120, 在 7.1 号, 那么 Alice 可以从 Bob 手中, 以 110 的价位购买 AVAX, 然后把它卖掉.
  • 如果 AVAX 只涨到了 105, 那么 Alice 可以选择不用管她的看涨期权, 她只是损失掉了期权购买的费用.

在传统交易世界中, 期权是合法执行的合同, 即 Bob 向 Alice 出售这张 110 的期权的时候, 他不必手头上要有足量的 AVAX, 但是在 AVAX 升到 120 的情况下 Bob 需要手头上有足量的 AVAX 能够卖给 Alice, 因此他会被迫在 AVAX120 的时候大量买入, 才能以 110 的价格卖个 Alice, 这就叫做 裸 call

在有担保看涨期权的情况下, Bob 则是必须手头上要有足量的 AVAX 才能向 Alice 出售这张期权, 由于我们没有办法像现实世界一样执行合同条例, 因此这就相当于存进抵押品

因此, 为什么要作为期权的卖方呢?

假设 AVAX 当前价格为 100, Bob 是一个长期多头, 但他认为 7.1 号之前不会涨到 150, 因此 他可以以 150 的价格出售其 AVAX 的看涨期权, 并且只要 AVAX 在 7.1 号之前低于 150 美元, 他就可以从期权费用中获利, 即使 AVAX 涨到 140 , 他仍然可以从这里面获利. 即任何上涨对他来说都是有利可图的, 直到价格超过了 150 美元.


期权定价

在到期之前, 期权的价值通常高于其收益, 比如 明天到期的 100 美元的 AVAX 看跌期权[Put]

  • 如果当前 AVAX 的价格是 100, 则收益为 0
  • 但是明天 AVAX 的价格可能下跌, 这种情况下, 期权的收益则超过 0
  • 考虑到这种情况, 看跌期权的价格必须必须大于 0

一种基本且广泛使用的期权定价模型是Black-Scholes模型, 它根据以下内容计算看涨/看跌期权的价格

  1. 行权价
  2. 当前现货价格
  3. 波动性
  4. 到期时间
  5. 无风险利率

下图表示了 3000 美元行使价 ETH 看跌期权下的 Black-Scholes 价格(蓝色)正常以价差定价的期权价格 的比较

个人理解可能有误, 这里的原文是 The graph below shows the Black-Scholes price of a $3000 strike ETH put compared to the payoff at various spot ETH prices one day before expiry.


再看 Primitive

就像我们之前说的, 在这里提供流动性就相当于是在写一个有担保的看涨期权, 即你需要像购买期权一样输入到期日和行使价等参数

本质上, 你是在卖出看涨期权, 其中期权费是累积的交易费, 在交易方面, 要知道 Primitive 的核心共识并不是xy=kx*y=k的公式, 它使用的是下图中的公式

上面所展示的这条曲线会动态调整

如果时间是唯一变量, 曲线会变平, 要知道, 可以用等于执行价格的固定价格进行交易, 本质上则像 UniV3 一样聚集流动性, 但是围绕在执行价格上下.

假如你提供 AVAX/USDC 流动性, 以行权价为 100U, 行权日期为明天,

  • 如果当前价格 90U, 则套利者会在别处购买 AVAX, 然后售卖到这个池子中, 池子将完全由 AVAX 组成
  • 如果当前价格 100U, 则不会变动
  • 如果价格为 110U, 则套利者会从这里购买 AVAX, 卖到别的地方, 池子里完全是 USDC

❤️ 优点

  1. 流动性被集中起来了(只不过随着时间改变)
  2. 只有当价格超过行权价的时候, 才会有无常损失
  3. 允许你对流动性进行定向押注

💔 缺点

  1. 添加流动性的时候 极其复杂

Part3


Part3 更多的是 结合上面所述的 AMM, 来描述 一个完美的 AMM 是什么样的.

在市场中, 不同的角色有着不同的目的性, 流动性提供者想要更高的年化, 而项目方则不想, 因为这样会导致通货膨胀和代币倾销, 损害代币持有者的利益, 因此 一个好的 AMM 应该可以权衡利弊.

各个角色的需求如下 👇

  • 交易者
    • 交易的 0 滑差
    • 可以在上面交易很多种代币
  • 流动性提供者
    • 更高的年化
    • 没有无常损失
    • 单币质押
    • 被动化的流动性管理
    • 被保障的资金安全
  • 协议拥有者
    • 不依赖于代币排放
    • 包含大量种类的代币
    • 无许可地创建流动性池子
    • 安全性能高 以及 对外部各方的依赖低

好的 AMM 的必要点 👇

  1. 交易的 0 滑差
  2. 安全性
  3. 被动流动性管理
  4. 种类多样的代币交易

前两点无需解释, 第三点则是因为 AMM 比之前基于订单薄的 Dex 更受欢迎的原因, 其更符合散户投资者. 最后一点有些微妙, 因为主流的代币几乎占到了所有 Dex 交易量的 80%以上, 所以, 真的有必要涵盖大量的无用代币吗? 作者的观念是 Yes, 这就是为什么 Uni 能够超越 Balancer 和 Bancor 的原因, 因为它更能捕捉长尾资产


  • 至于上面说的更高的年化, 冲突点在于流动性提供者和协议拥有者, 那么最好的折衷方案则是提供与代币排放无关的收益(比如, 仅取决于交易费用)

  • 是否允许单币质押的讨论, 其实也是一个矛盾点, 大多数提供单币质押的协议都要求协议在为流动性选择白名单资产时非常勤奋, 因为一种不良资产可能会影响池中的其他资产. 但这一点就与无许可创建流动性池子矛盾

  • 更低的外部依赖, 利用 chainlink 预言机来投喂价格是很多项目方常用的手法, 但是要知道, chainlink 的价格是滞后的, 当时间和价格很正常时, chainlink 非常棒, 但是当某个代币的价格在某个时间段内的变化非常明显时, chainlink 则无法及时捕捉到代币价格, 这就是当 Luna 崩盘时, Venus 和 Blizz Finance 如何被人利用的. 另外要知道的一点是, chainlink 是从 dex 来获取数据的. 此外 chainlink 价格投喂 仅仅适用于选定的代币, 这又阻挡了大量种类的代币.


  • 结论, 一个完美的 DEX 理应有如下特点
    • 交易的 0 滑差
    • 多种类可交易的 Token
    • 流动性安全保障
    • 不依赖于外部
    • 不依赖于代币排放
    • 无许可创建流动性池子
    • 被动地流动性管理