Curve Cryptoswap 第 8 章(附录):用隐函数求导算 AMM 现货价(dy/dx)
前面几章我们一直说”现货价 spot price”,比如重锚要用的
last_prices就是池子的现货价,由数学库的get_p算出。但get_p凭什么能算出现货价?这一章用一个统一的数学技巧——隐函数求导(implicit differentiation)——把恒定和、恒定乘积、Curve V1、Curve V2 的现货价一次性推出来。看完你会明白:所有 AMM 的”价格”本质都是同一个东西——不变量曲线在当前点的切线斜率。
目录
- 1. 现货价到底是什么
- 2. 为什么需要隐函数求导
- 3. 隐函数求导的核心公式
- 4. 例 1:恒定和 AMM
- 5. 例 2:恒定乘积 AMM(Uniswap)
- 6. 案例:用具体数字验证恒定乘积现货价
- 7. 例 3:Curve V1(Stableswap)
- 8. 例 4:Curve V2(Cryptoswap)与 get_p
- 9. 现货价 vs 成交价:别混淆
- 10. 本章小结
- 11. 动手练习
1. 现货价到底是什么
现货价(spot price) 是”无穷小交易”的价格——你买入一丁点点 y,需要付出多少 x。数学上就是:
现货价 = -dy/dx (在当前余额点处)
几何意义:把 AMM 的不变量画成一条曲线(x 轴是币 X 的数量,y 轴是币 Y 的数量),现货价就是曲线在当前点的切线斜率(取负)。
- 交易就是沿着这条曲线移动。
- 移动一点点,y 减少 dy、x 增加 dx,比值 dy/dx 就是此刻的边际价格。
所以”算现货价”= “算不变量曲线在当前点的斜率”。
2. 为什么需要隐函数求导
AMM 的不变量通常写成 F(x, y) = 常数 的形式,比如:
- 恒定和:
x + y = D - 恒定乘积:
x · y = L² - Curve V1/V2:更复杂的混合式
这些式子里,y 没有被单独解出来写成 y = f(x) 的显式形式(Curve 的式子甚至根本解不出漂亮的显式 y)。但我们仍想求 dy/dx。
隐函数求导正是为这种”y 藏在方程里、没法显式解出”的情况设计的:它不要求你先解出 y,就能直接求出 dy/dx。
3. 隐函数求导的核心公式
设不变量是 F(x, y) = 0(把常数移到左边)。对方程两边关于 x 求导,注意 y 是 x 的隐函数,用链式法则:
∂F/∂x + ∂F/∂y · dy/dx = 0
解出:
∂F/∂x
dy/dx = − ───────
∂F/∂y
于是现货价:
现货价 = −dy/dx = (∂F/∂x) / (∂F/∂y)
一句话总结这套方法:对不变量分别求 x 的偏导和 y 的偏导,两者相除,就是现货价。 下面把四种 AMM 套进这个公式。
4. 例 1:恒定和 AMM
不变量:F(x, y) = x + y − D = 0
求偏导:
∂F/∂x = 1
∂F/∂y = 1
现货价:
−dy/dx = (∂F/∂x)/(∂F/∂y) = 1/1 = 1
结论:恒定和的现货价永远 = 1,与余额无关。 这正是第 2 章说的”恒定和零滑点、价格被钉死在 1”——数学上就是这条直线的斜率恒为 -1。
5. 例 2:恒定乘积 AMM(Uniswap)
不变量:F(x, y) = x · y − L² = 0
求偏导:
∂F/∂x = y
∂F/∂y = x
现货价:
−dy/dx = (∂F/∂x)/(∂F/∂y) = y / x
结论:恒定乘积的现货价 = y/x(池子里 Y 的量 ÷ X 的量)。
这非常符合直觉:
- 如果池子里 Y 很多、X 很少(y/x 大),说明 Y 相对便宜、X 相对贵,用 X 买 Y 的价格(每个 X 能换的 Y)就高。
- 交易会改变 x、y,从而改变 y/x → 这就是滑点的来源。
6. 案例:用具体数字验证恒定乘积现货价
设 Uniswap 池子 x = 100 ETH,y = 300,000 USDC,则 L² = 100·300,000 = 30,000,000。
现货价(用 ETH 计价,即 1 ETH = ? USDC):
现货价 = y / x = 300,000 / 100 = 3,000 USDC/ETH ✅
验证滑点:现在买 1 个 ETH(x 减少到 99),由 x·y = 30,000,000 求新 y:
新 y = 30,000,000 / 99 = 303,030.3 USDC
你要付的 USDC = 303,030.3 - 300,000 = 3,030.3 USDC
注意:你买 1 个 ETH 实际付了 3,030.3 USDC,比现货价 3,000 略高——这 30.3 USDC 就是滑点(因为这不是”无穷小”交易)。如果只买 0.001 个 ETH,平均价就会非常接近现货价 3,000。
这印证了第 9 节要讲的关键区分:现货价(边际、无穷小)≠ 成交价(有限金额的平均价)。
7. 例 3:Curve V1(Stableswap)
Curve V1 的不变量(两币简化)大致是:
F(x, y) = A·n^n·(x + y) + D = A·D·n^n + D^(n+1)/(n^n·x·y)
(不必纠结具体形式,重点是它同时含有 x+y(和项)和 x·y(积项)。)
套同样的方法对 x、y 求偏导再相除,会得到一个介于 1(恒定和) 和 y/x(恒定乘积) 之间的现货价表达式:
- 当池子平衡(x≈y)且 A 很大 → 现货价 ≈ 1(像恒定和,低滑点)。
- 当池子严重失衡 → 现货价 → y/x(像恒定乘积,避免被掏空)。
这正是第 2 章讲的”两条曲线缝合”在现货价层面的体现:Stableswap 的价格在平衡区几乎不动(≈1),失衡时才开始像 Uniswap 那样滑动。
8. 例 4:Curve V2(Cryptoswap)与 get_p
Curve V2 的不变量(第 2 章那条)更复杂:
F = K·D^(N-1)·Σxᵢ + Πxᵢ − K·D^N − (D/N)^N = 0
其中 K = A·K0·(γ/(γ+1-K0))², K0 = Πxᵢ·N^N/D^N
求它的现货价同样是”求偏导再相除”,只不过:
- 这里有 N 个变量(三币池 N=3),所以是对每一对币求偏导比,得到每对币之间的现货价。
- K 本身又依赖所有 xᵢ(通过 K0),所以求偏导时要用乘积法则 + 链式法则,展开后非常长。
合约里 get_p(xp, D, A_gamma) 干的就是这件事——把这套偏导比的结果用定点数实现出来,直接返回 coin1/coin2 相对 coin0 的现货价。
你不需要手推这个庞大的偏导表达式(那是 Curve 团队和审计员的工作)。本章真正要你带走的是这个统一视角:
从恒定和到 Curve V2,所有 AMM 的现货价都是同一个东西——不变量曲线在当前点的切线斜率,都可以用”两个偏导相除”求出。
get_p只是把 V2 那条复杂曲线的斜率算出来而已。
而第 7 章里 last_prices = get_p(...) 拿到的就是这个现货价,再喂给 EMA 变成 price_oracle,最终驱动重锚。整门课的逻辑链到这里闭环了。
9. 现货价 vs 成交价:别混淆
最后澄清一个极易混淆的点:
| 现货价(spot price) | 成交价(execution price) | |
|---|---|---|
| 定义 | 无穷小交易的边际价 −dy/dx | 有限金额交易的平均价 Δy/Δx |
| 几何 | 曲线在当前点的切线斜率 | 起点到终点的割线斜率 |
| 用途 | 喂给预言机、算 last_prices | 用户实际换到多少(第 4 章 exchange 的 dy) |
| 有无滑点 | 无(理想边际) | 有(金额越大滑点越大) |
- 第 4 章你
exchange实际拿到的是成交价(含滑点和手续费)。 - 第 7 章预言机跟踪的是现货价(
get_p算的边际价)。
两者在”交易无穷小”时相等,金额越大差距越大。第 6 节的例子就量化了这个差距(现货 3000,买 1 ETH 的成交价 3030.3)。
10. 本章小结
- 现货价 = −dy/dx = 不变量曲线在当前点的切线斜率,是”无穷小交易”的边际价格。
- 不变量写成
F(x,y)=0,用隐函数求导:现货价 = (∂F/∂x)/(∂F/∂y),无需把 y 显式解出来。 - 套用结果:
- 恒定和 → 现货价 = 1(钉死,零滑点)。
- 恒定乘积 → 现货价 = y/x(随余额变,有滑点)。
- Curve V1 → 介于 1 和 y/x 之间(平衡≈1,失衡→y/x)。
- Curve V2 → 同理但更复杂,由
get_p用定点数实现。
get_p算出的现货价就是第 7 章的last_prices,经 EMA 变price_oracle,驱动重锚——全课逻辑闭环。- 切记区分现货价(边际、喂预言机)和成交价(平均、含滑点、用户实得)。
11. 动手练习
这是一个偏数学/脚本的练习,用来把”隐函数求导算现货价”亲手验证一遍。
练习 1:数值验证恒定乘积现货价
用 Python(或任意语言)写一个小脚本:
- 设
x=100, y=300000,L2 = x*y。 - 数值求导:算
(y(x-h) - y(x+h)) / (2h)的负值,h 取很小(如 1e-6),其中y(x) = L2/x。 - 和解析现货价
y/x = 3000对比,应几乎相等。 - 再算”买 1 个 ETH 的成交价”(第 6 节方法),观察它略大于现货价。
练习 2:链上验证 get_p 就是现货价
主网分叉,针对 TriCrypto:
- 调用数学库或池子的方式拿到当前
last_prices(0/1)(即get_p的结果),记下来。 - 用
get_dy(i, j, dx)做两次报价:一次dx很小(如 0.001 ETH),一次dx较大(如 10 ETH)。 - 把每次的”有效汇率”=
dy/dx算出来。 - 验证:
dx越小,有效汇率越接近last_prices(现货价);dx越大,偏离越多(滑点)。这就实证了”现货价 = 无穷小交易的极限价”。
interface ITriCrypto {
function get_dy(uint256 i, uint256 j, uint256 dx) external view returns (uint256);
function last_prices(uint256 i) external view returns (uint256);
}
练习 3(高级,选做):手推两币 Curve V1 的现货价
- 写出两币 Stableswap 不变量
F(x,y)=0。 - 用第 3 节公式求
(∂F/∂x)/(∂F/∂y)。 - 验证:令
A→∞时表达式 → 1(恒定和);令A→0时 → y/x(恒定乘积)。 - 体会”一个参数 A 如何在两种极端曲线之间连续过渡”——这正是 Curve 全部魔法的数学根源。
🎉 全课程完结
恭喜你走完了 Curve Cryptoswap 的全部核心内容!回顾这条主线:
- 第 2 章 数学:用 K、gamma 把恒定和与恒定乘积缝在一起,price_scale 让中心价可移动。
- 第 3 章 合约总览:三合约架构、状态变量打包省 gas、A/gamma 缓慢 ramp。
- 第 4 章 兑换:保持 D 不变定价、get_y 反解、动态手续费自我修复。
- 第 5 章 添加流动性:按 D 增量铸 LP、失衡费惩罚不按比例存入。
- 第 6 章 移除流动性:按比例(免费)vs 单币(收费)两种路径。
- 第 7 章 价格重锚:EMA 抗操纵预言机、两道闸门、小步移动、永不亏本。
- 第 8 章 附录:隐函数求导统一所有 AMM 的现货价,逻辑闭环。
接下来最好的巩固方式,就是把每章末尾的练习用 Foundry 真正跑一遍。祝你 DeFi 开发之路顺利!