← 博客

恒定乘积 AMM 的价格冲击推导(示例)

从 x·y = k 出发,推出一笔交易的成交量、成交价和价格冲击,顺便展示公式、代码块和表格的排版。

约 2 分钟
  • DeFi
  • AMM
  • 示例

这是一篇示例文章,用来检查排版:公式、代码、表格、引用都放了一遍。内容本身是 Uniswap v2 一类恒定乘积做市商的基础推导,可以当作真正的第一篇长文的起点,也可以直接删掉。

恒定乘积模型

池子里有两种代币,储备量分别是 xx 和 yy。每次交易后,两者的乘积保持不变:

x⋅y=kx \cdot y = k

用户向池子存入 Δx\Delta x 个 X 代币,池子按公式给出 Δy\Delta y 个 Y 代币,要求交易后乘积仍为 kk:

(x+Δx)(y−Δy)=xy(x + \Delta x)(y - \Delta y) = xy

解出 Δy\Delta y:

Δy=y Δxx+Δx\Delta y = \frac{y \,\Delta x}{x + \Delta x}

加入手续费

设手续费率为 ff(Uniswap v2 是 0.3%0.3\%),只有扣费之后的部分 Δx′=(1−f)Δx\Delta x' = (1-f)\Delta x 参与定价:

Δy=y (1−f)Δxx+(1−f)Δx\Delta y = \frac{y \,(1-f)\Delta x}{x + (1-f)\Delta x}

手续费留在池子里,所以交易后的乘积 kk 会略微变大,这部分增长就是流动性提供者的收益来源。

价格冲击

交易前的边际价格是 p0=y/xp_0 = y/x。这笔交易的平均成交价是 Δy/Δx′\Delta y / \Delta x',两者的差距就是价格冲击:

impact=1−Δy/Δx′p0=Δx′x+Δx′\text{impact} = 1 - \frac{\Delta y/\Delta x'}{p_0} = \frac{\Delta x'}{x + \Delta x'}

冲击只取决于这笔交易占池子储备的比例。交易量相对池子越大,滑点越大。

数值例子

取 x=y=1000x = y = 1000,f=0.3%f = 0.3\%:

输入 Δx\Delta x输出 Δy\Delta y价格冲击
10.99600.100%
109.87160.987%
10090.66119.066%
500332.666033.267%

价格冲击随输入规模变化的曲线 图:输入 0 到 500 对应的价格冲击,标出的点是上表的四组数值。

代码

下面是同样的计算,可以直接运行:

def swap(x: float, y: float, dx: float, fee: float = 0.003):
    """返回 (输出数量, 价格冲击)。"""
    dx_eff = dx * (1 - fee)
    dy = y * dx_eff / (x + dx_eff)
    impact = dx_eff / (x + dx_eff)
    return dy, impact


dy, impact = swap(1000, 1000, 100)
print(f"out={dy:.4f}, impact={impact:.3%}")
# out=90.6611, impact=9.066%

下一步

这个模型里价格只在池子内部由交易推动,所以和外部市场出现价差时,套利者会把它拉回去。这个过程和 MEV、交易排序直接相关,可以作为下一篇的主题。