第二讲:恒定乘积公式 x·y = k 的深度拆解
各位同学,今天我们来啃一块硬骨头——恒定乘积公式。说实话,这个公式看起来就一行字:x * y = k,但里面藏着的门道,够我们聊一整节课。
我记得刚入行DeFi时,觉得这公式太简单了,不就是反比例函数吗?直到我在一个项目中亲手写AMM合约,才发现——嗯,纸上得来终觉浅。滑点怎么算?深度怎么衡量?这些全藏在这个公式里。
一、公式的数学推导:从交易到等式
先看最基础的定义。一个流动性池里,有两种代币:Token A 和 Token B。假设当前池子里有 x 个 A,y 个 B。那么恒定乘积公式说:
x * y = k
k 是一个常数。只要没有人添加或移除流动性,k 就不变。
现在,我用 Δx 个 A 代币换出 Δy 个 B 代币。交易完成后,池子里变成 (x + Δx) 个 A 和 (y - Δy) 个 B。公式依然成立:
(x + Δx) * (y - Δy) = k
把两个等式联立:
x * y = (x + Δx) * (y - Δy)
展开右边:
x * y = x * y - x * Δy + Δx * y - Δx * Δy
两边消去 x * y:
0 = - x * Δy + Δx * y - Δx * Δy
移项:
x * Δy = Δx * y - Δx * Δy
提取 Δy:
Δy * (x + Δx) = Δx * y
最终得到:
Δy = (Δx * y) / (x + Δx)
这就是你拿 Δx 个 A 代币,能换出多少 B 代币的精确公式。
核心结论:你得到的代币数量,不仅取决于你投入了多少,还取决于池子的当前深度(x 和 y)。
二、曲线特性分析:为什么是双曲线?
把公式 x * y = k 画在坐标系里,是一条双曲线。这条曲线有几个关键特性:
- 永远不碰坐标轴:x 和 y 都不能为 0。一旦某个代币被换光,池子就崩了。我在审计一个项目时,就发现有人利用闪电贷试图把池子掏空——幸好合约有保护机制。
- 价格是曲线的斜率:当前价格 P = y / x。为什么?因为瞬时价格就是 dy/dx = -y/x(负号表示方向)。
- 越靠近原点,滑点越大:当池子深度变浅时,同样的交易量会造成更大的价格冲击。
我个人习惯把这条曲线想象成一根橡皮筋。你往一个方向拉得越狠,另一端的反弹力就越大。这就是AMM的自动定价机制——不需要订单簿,全靠数学。
三、滑点与深度:一对冤家
滑点,说白了就是你实际成交的价格,和你预期价格之间的差距。为什么会这样?因为你的交易改变了池子的比例。
举个例子:
假设一个 ETH/USDC 池子,有 100 ETH 和 300,000 USDC。当前价格是 3,000 USDC/ETH。
你想买 1 个 ETH。用公式算一下:
Δy = (Δx * y) / (x + Δx)
Δy = (1 * 300,000) / (100 + 1) = 300,000 / 101 ≈ 2,970.3 USDC
你实际支付了 2,970.3 USDC,而不是预期的 3,000 USDC。滑点就是 (3,000 - 2,970.3) / 3,000 ≈ 0.99%。
如果你买 10 个 ETH 呢?
Δy = (10 * 300,000) / (100 + 10) = 3,000,000 / 110 ≈ 27,272.7 USDC
预期价格是 30,000 USDC,实际支付 27,272.7 USDC。滑点变成了 9.09%。
避坑指南:我曾经在测试网上跑一个套利机器人,因为没算滑点,直接按预期价格下单,结果成交价差了 15%,导致整个策略亏损。从那以后,我所有交易都强制加滑点保护。
深度和滑点的关系,可以用一个表格直观展示:
| 池子深度(ETH) | 交易量(ETH) | 滑点 |
|---|---|---|
| 100 | 1 | 0.99% |
| 100 | 10 | 9.09% |
| 1,000 | 1 | 0.10% |
| 1,000 | 10 | 0.99% |
| 10,000 | 1 | 0.01% |
看到了吗?同样的交易量,池子越深,滑点越小。这就是为什么大池子更受大额交易者欢迎。
四、用 SVG 画一张知识结构图
下面这张图,把恒定乘积公式的核心逻辑串起来了:
五、实战中的注意事项
讲到这里,我想分享几个实际开发中踩过的坑:
- 精度问题:Solidity 没有浮点数,所有计算都要用定点数。我习惯用
PRBMath库来处理乘除,避免溢出。 - k 值更新:每次交易后,k 值理论上不变。但如果你加了手续费,k 值会缓慢增长——这就是流动性提供者的收益来源。
- 大额交易预警:当交易量超过池子深度的 10% 时,滑点会急剧上升。我个人建议前端直接提示用户「这笔交易滑点超过 5%,是否继续?」
警告:千万不要在合约里直接用 x * y == k 来验证交易!因为浮点误差会导致验证失败。正确的做法是检查 x * y >= k(考虑手续费后的 k 值)。
好了,这一讲的内容就到这里。恒定乘积公式虽然简单,但它是整个 AMM 世界的基石。你把它吃透了,后面学加权乘积、动态费率都会轻松很多。
公众号:蓝海资料掘金营,微信deep3321