Skip to content

(Uniswap)常数乘积公式的另类理解

zhtkeepup edited this page May 15, 2024 · 5 revisions

全角空格:[  ] (读者请忽略本行)

一. Uniswap的常数乘积公式简介

  Uniswap的常数乘积公式,是指:x * y = k,其中 x是资产tokenX的数量,y是资产tokenY的数量,k是一个常数(每个池子仅包含两个资产tokenXtokenY)。
  下图表显示了恒定乘积公式的图形,其中xtokenX的数量,y是池中tokenY的数量,曲线上点的斜率是现货价格。
  备注:上文所指的“常数”,是指每次发生买入或者卖出时,交易的前后该值k保持不变。在添加流动性或者退出流动性时k将发生变化。

xyk

  现在用一个例子来解释。(以下计算不考虑手续费)
  假设某一时刻AVAX 的价格为100 USDC一个, AVAX/USDC 池由 20 个 AVAX 和 2000 个 USDC 组成。因为 20 AVAX 相当于 2000 USDC,所以资产价值的比例是 1:1。那么使用常数乘积公式,我们得到 k = 20 * 2000 = 40000。
  这个数字在兑换期间保持不变,只有在增加更多流动性时才会改变。
  现在假设 Alice 想要售出 5 个 AVAX。她会得到多少USDC作为回报?
  重新计算 y 的公式,我们得到 y = k/x。所以兑换后池中的 USDC 数量为 y = 40000 / (20+5) = 1600 USDC。所以 Alice 用 5 个 AVAX 收到了 400 USDC。
  该池现在包括 25 AVAX 和 1600 USDC。AVAX 的现货价格现在从 100 USDC 变为 1600/25 = 64 (USDC/个)
  该交易对池子内AVAX的价格影响为 (64-100) / 100 = -36%
  而Alic实际的平均售出价格为400 / 5 = 80 (USDC/个)

二. 本人对常数乘机公式的另类业务理解

  以下内容均是基于小学三年级数学知识的个人脑补,未与其他官方材料佐证,仅供学习交流。
  想象一下,你是一个交易对AVAX/USDC的管理员,目前你的库存中拥有20个AVAX和2000个USDC,但是作为管理员,你无法获知外部世界对AVAX与USDC的定价信息。此时,对你来说,AVAX与USDC的价值是相等的,因此存在等式20 * price0 = 2000,此时price0 = 100
  当某一时刻,一个外部用户Alice试图用 5 个 AVAX 与你交易,即该用户向你出售AVAX。整个流程应该是这样的:
  1. Alice给你5个AVAX;
  2. 你计算需要给Alic多少USDC;
  3. 你将相应USDC的数量给到Alice;
  4. OVER.

  这里的步骤b,你应该如何计算呢,因为你无法从其他渠道获取额外信息为AVAX和USDC定价,此时若认为仓库内的两种代币的总价值仍然相等,也不失为一种合理的设定,基于此设定,那么存在等式(20 + 5) * price1 = 2000,此时price1 = 80,则按此价格计算需要给出去的USDC的数量为80 * 5 = 400。计算结果与前面根据常数乘机公式计算的结果相同。

  现在看看基于这个场景,是否能够推出与"常数乘机公式"一样的数学公式x*y=k

  1. 设流动性池子内原先两个代币AVAX、USDC的数量分别为x、y,基于"设定"两种代币的价值相等,则此时存在某个价格price0,满足x * price0 = y;
  2. 当外部用户向池子出售AVAX时,若出售数量为m,基于"设定"两种代币的价值相等,则此时存在新的价格price1,满足( x + m ) * price1 = y;
  3. 新的price1价格值为:price1 = y / ( x + m ) , 基于新价格计算需要支付给用户USDC的数量为y / ( x + m ) * m;
  4. 向用户支付USDC之后,池子内剩余USDC数量为 y - (y / ( x + m ) * m);
  5. 按照常数乘机公式,此时 k = (x + m) * (y - (y / ( x + m ) * m)), 该式子化简步骤如下:
k = (x + m) * (y - (y / ( x + m ) * m))
  = x * (y - (y / ( x + m ) * m)) + m * (y - (y / ( x + m ) * m))
  = x*y - x*(y / ( x + m ) * m) + m*y - m*(y / ( x + m ) * m)
  = x*y - x*y/(x+m)*m + m*y - m*y/(x+m)*m
  = x*y - m*x*y/(x+m) + m*y - m*m*y/(x+m)
  = x*y + m*y - (m*x*y+m*m*y)/(x+m)
  = x*y + m*y - m*y*(x+m)/(x+m)
  = x*y + m*y - m*y
  = x*y

  当将出售AVAX换成购买AVAX时,结果一样,只是m值是一个负数。基于该场景流程,交易前后k的值没有发生变化。
  由此可见,基于下面的"设定"与uniswap的常数乘积公式完全契合:
  当需要[流动池]来计算其中一种代币应该增加或减少的数量时,此时按照“两种代币的价值相等”的原则进行计算即可。
  另:添加流动性池子时,首次添加,池子是空的,由添加人随意设定比例;后续添加时,两种代币的数量比例应该与池子内已有的比例保持一致。