-
Notifications
You must be signed in to change notification settings - Fork 1
(Uniswap)常数乘积公式的另类理解
全角空格:[ ] (读者请忽略本行)
Uniswap的常数乘积公式,是指:x * y = k
,其中 x
是资产tokenX
的数量,y
是资产tokenY
的数量,k
是一个常数(每个池子仅包含两个资产tokenX
和tokenY
)。
下图表显示了恒定乘积公式的图形,其中x
是tokenX
的数量,y
是池中tokenY
的数量,曲线上点的斜率是现货价格。
备注:上文所指的“常数”,是指每次发生买入或者卖出时,交易的前后该值k
保持不变。在添加流动性或者退出流动性时k
将发生变化。
现在用一个例子来解释。(以下计算不考虑手续费)
假设某一时刻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
:
- 设流动性池子内原先两个代币AVAX、USDC的数量分别为x、y,基于"设定"两种代币的价值相等,则此时存在某个价格price0,满足
x * price0 = y
; - 当外部用户向池子出售AVAX时,若出售数量为m,基于"设定"两种代币的价值相等,则此时存在新的价格price1,满足
( x + m ) * price1 = y
; - 新的price1价格值为:
price1 = y / ( x + m )
, 基于新价格计算需要支付给用户USDC的数量为y / ( x + m ) * m
; - 向用户支付USDC之后,池子内剩余USDC数量为
y - (y / ( x + m ) * m)
; - 按照常数乘机公式,此时
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的常数乘积公式完全契合:
当需要[流动池]来计算其中一种代币应该增加或减少的数量时,此时按照“两种代币的价值相等”的原则进行计算即可。
另:添加流动性池子时,首次添加,池子是空的,由添加人随意设定比例;后续添加时,两种代币的数量比例应该与池子内已有的比例保持一致。
welcome!
- solidity智能合约开发
- 学习学习