理解 AMM 中的恒定乘积公式(别被 k 欺骗)
发布: (2025年12月23日 GMT+8 18:43)
4 分钟阅读
原文: Dev.to
Source: Dev.to
核心概念:x * y = k 实际意味着什么?
在恒定乘积 AMM 中:
x * y = k
- x = 代币 A 的储备量
- y = 代币 B 的储备量
- k = 一个常数
在一次兑换(swap)过程中,k 必须保持不变。储备量会变化,但储备量的乘积保持相同——这就是整个定价机制。
初始状态
uint256 reserveA = 1000;
uint256 reserveB = 1000;
计算 k:
uint256 k = reserveA * reserveB; // 1_000_000
这个 k 定义了池子必须保持的曲线。
用户将代币 A 兑换为代币 B
用户进行兑换:
uint256 amountAIn = 100;
步骤 1:使用当前不变量
uint256 k = reserveA * reserveB; // 1,000,000
这就是此次兑换唯一有效的 k。
步骤 2:加入进入的代币
uint256 newReserveA = reserveA + amountAIn; // 1,100
我们现在知道了新的 A 储备量,但还不知道新的 B 储备量。
步骤 3:求解新的 B 储备量
为了保持不变量:
uint256 newReserveB = k / newReserveA; // ≈ 909.09
步骤 4:计算用户将收到的数量
uint256 amountBOut = reserveB - newReserveB; // ≈ 90.91
用户收到约 90.91 个代币 B,池子仍然位于同一条曲线上。
验证不变量
1100 * 909.09 ≈ 1,000,000
不变量成立。
常见错误:重新计算 k
很多人本能地会这样做:
uint256 newK = newReserveA * reserveB; // 1,100 * 1,000 = 1,100,000
uint256 newReserveB = newK / newReserveA; // = 1,000
uint256 amountBOut = reserveB - newReserveB; // = 0
用户什么也得不到,因为这种逻辑把池子移动到了一个新曲线,违反了基本的不变量。
真正的兑换公式
兑换过程中实际的 AMM 方程是:
(reserveA + amountIn) * (reserveB - amountOut) = reserveA * reserveB
求解 amountOut:
uint256 amountOut = reserveB - (reserveA * reserveB) / (reserveA + amountIn);
这正是 Uniswap‑style 合约实现的——没有魔法,只有代数。
为什么必须使用旧的 k
- k 代表曲线。
- 兑换使池子沿同一条曲线移动。
- 添加流动性会创建新曲线。
- 兑换不会创建新曲线。
如果在兑换过程中重新计算 k,就等于跳到另一条曲线,定价瞬间失效。
有助于理解的思维模型
- 把 k 想成一条铁轨。
- 流动性提供者铺设新轨道(新 k)。
- 交易者沿着已有的轨道移动。
- 你永远不会在兑换过程中重新绘制轨道。
要点总结
- 在兑换过程中不重新计算 k。
- 不变量定义了定价曲线。
- 兑换必须在同一条曲线上开始并结束。
- 使用“新 k”会破坏 AMM 逻辑。
如果以后再次觉得这不直观,只需记住:
兑换是沿曲线移动池子——而不是重新绘制曲线。
