DEX Swap 计算:正向推导与反向推导
在去中心化交易所(DEX)中,自动做市商(AMM)使用数学公式自动计算交易价格。本文将用通俗易懂的方式,讲解两个核心问题:
- 正向推导:卖出一定数量的代币 A,能买入多少代币 B?
- 反向推导:想买入指定数量的代币 B,需要卖出多少代币 A?
核心公式回顾
Uniswap 等 AMM 采用恒定乘积公式:
其中:
- :池中代币 A 的储备量
- :池中代币 B 的储备量
- :恒定乘积(流动性常数)
交易前后, 值保持不变(暂不考虑手续费)。
一、正向推导:已知卖出量,求买入量
场景描述
假设当前池中有:
- 代币 A:1000 个
- 代币 B:2000 个
你想卖出 100 个代币 A,能买入多少代币 B?
计算步骤
第一步:确定初始状态
第二步:计算交易后的代币 A 数量
你卖出 100 个代币 A 进入池子:
第三步:根据恒定乘积求交易后的代币 B 数量
第四步:计算获得的代币 B 数量
通用公式
代码示例
// 正向推导:计算卖出 dx 个代币A能获得多少代币B
function getAmountOut(reserveA, reserveB, amountIn) {
return (reserveB * amountIn) / (reserveA + amountIn);
}
// 示例
const amountOut = getAmountOut(1000, 2000, 100);
console.log(amountOut); // 181.818181...
二、反向推导:已知目标买入量,求所需卖出量
场景描述
同样的池子:
- 代币 A:1000 个
- 代币 B:2000 个
你想精确买入 200 个代币 B,需要卖出多少代币 A?
计算步骤
第一步:确定初始状态
第二步:计算交易后的代币 B 数量
你想获得 200 个代币 B,所以池子里的代币 B 会减少:
第三步:根据恒定乘积求交易后的代币 A 数量
第四步:计算需要卖出的代币 A 数量
所以需要卖出约 111.11 个代币 A。
通用公式
代码示例
// 反向推导:计算买入 dy 个代币B需要卖出多少代币A
function getAmountIn(reserveA, reserveB, amountOut) {
return (reserveA * amountOut) / (reserveB - amountOut);
}
// 示例
const amountIn = getAmountIn(1000, 2000, 200);
console.log(amountIn); // 111.111111...
三、考虑手续费的情况
实际交易中,DEX 会收取手续费(如 Uniswap V2 收取 0.3%)。手续费从输入代币中扣除。
正向推导(含手续费)
卖出 个代币 A,实际进入池子的只有 ,其中 为手续费率。
// Uniswap V2 风格(0.3% 手续费)
function getAmountOutWithFee(reserveA, reserveB, amountIn, feeRate = 0.003) {
const amountInWithFee = amountIn * (1 - feeRate);
return (reserveB * amountInWithFee) / (reserveA + amountInWithFee);
}
反向推导(含手续费)
需要卖出更多代币来补偿手续费:
function getAmountInWithFee(reserveA, reserveB, amountOut, feeRate = 0.003) {
return (reserveA * amountOut) / ((reserveB - amountOut) * (1 - feeRate));
}
四、对比总结
| 方向 | 已知 | 求解 | 公式 |
|---|---|---|---|
| 正向 | 卖出 | 获得 | |
| 反向 | 目标 | 需卖 |
直观理解
- 正向推导:池子变大(输入代币增加),输出代币减少
- 反向推导:先确定输出量,反推需要多少输入才能维持 不变
五、实际应用场景
场景一:交易预览
用户在 DEX 界面输入卖出数量,前端实时显示预计获得的代币数量——这就是正向推导。
场景二:精确交易
某些策略需要精确控制买入数量(如套利、清算),这时需要反向推导计算输入量。
场景三:滑点保护
计算预期输出后,设置滑点容忍度:
const minAmountOut = expectedAmountOut * (1 - slippageTolerance);
如果实际输出低于 minAmountOut,交易回滚。
总结
AMM 的计算核心是恒定乘积公式 :
- 正向推导:已知输入求输出,直接代入公式
- 反向推导:已知输出求输入,先算池子新状态再反推
- 手续费:从输入端扣除,公式稍作调整
理解这两个方向的计算,是开发 DEX 前端、编写交易策略的基础。
本文仅供技术学习参考,不构成任何投资建议。