V2中添加/移除流动性&无常损失
前置文章: https://kizzy899.github.io/2025/08/06/Uniswap%E4%B8%93%E9%A1%B9/
项目代码: https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol
添加流动性
在 Router.addLiquidity() 流程中:
- Router 会先调用
Factory.getPair(tokenA, tokenB)
检查池子是否存在
getPair[token0][token1]
用来查询该交易对是否已经存在 Pair 合约。如果返回 非零地址,说明这个交易对已经有 Pair 了 → **不会再调用
create2
**。如果返回 零地址,才会用
create2
部署新的 Pair 合约,并初始化。
如果不存在 →
Factory.createPair(tokenA, tokenB)
创建一个新的 Pair 合约然后 Router 才把用户代币转到 Pair 并调用
mint()
mint() : 把用户添加到池子里的代币,转换成 LP Token(流动性份额)并分发给用户
代码设计
- 代码中还有一个变量:
MIMIMUM.LIQUIDITY
作用:
防止除零错误 防止价格操纵 提高安全性 维持价格稳定
项目地址:https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Factory.sol
2.getPair[token0][token1]``getPair[token0][token1]
有一个对token0
和token1
的排序(小的放前面)
作用:
避免顺序不一样带来两种结果
- 为什么要使用
create2( )
来创建pair
作用:
在执行之后直接拿到pair
的地址 无需等交易上链
移除流动性
项目代码: https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol
代码中的参数:
1 | address tokenA, |
代码设计
.burn( )
:当用户 移除流动性 时调用,销毁 LP Token,并把底层资产返还给用户
与添加流动性中的
mint()
作用相对
uint liquidity = balanceOf[address(this)];
balanceOf
映射记录了 每个地址持有的 LP Token 数量address(this)
指的是 当前 Pair 合约自己的地址
👉 balanceOf[address(this)]
= Pair 合约自己持有的 LP Token 数量
原理解释笔记
无常损失
为什么要提供手续费给LP
交易所用于吸引别人来做LP
弥补无常损失
举例
对以下手写笔记中第一、二点的解释:
为什么做 LP(持 LP Token)和单纯持币(HODL)结果不同,以及公式为什么看起来不一样。
我们拆开来看:
🔹 1. 初始情况
- 池子最初:
100 A + 1 B
- 价格:
1 B = 100 A
- 总价值:
200 A
假设你作为唯一 LP,把资金都放进池子,获得池子 100% 的份额(LPT)。
🔹 2. 价格变化后
价格变了:
- 新价格
1 B ≈ 120 A
(也就是 A 涨价了) - 或者换个写法:
k = 120 * 0.83
(也就是池子自动调整后,储备可能是120 A + 0.83 B
)
这时候有两种策略:
🔹 3. 不做 LP(HODL 策略)
初始你是 100 A + 1 B。
涨价后:
- 1 B 的价值 =
120 A
- 你总价值 =
100 A + 1 B × 120 A = 100 A + 120 A = 220 A
但你提到结果是 244.58 A,这里其实对应的是你如果 纯粹 HODL B(因为 B 涨了),再折算的结果。
👉 公式:
1 | 不做 LP = 1 * (120/0.83 + 120) |
解释:
120 / 0.83 ≈ 144.58
表示 1 B 现在相当于多少 A- 再加上手里原来那部分 A (
120
) - 所以得到 244.58 A
🔹 4. 做 LP(提供流动性)
作为 LP,你的资产在价格变动时会 被动再平衡,变成 120 A + 0.83 B
。
也就是说:
- 你不再是单纯拿
100 A + 1 B
- 而是池子帮你“自动再配置”到新比例
👉 公式:
1 | 做 LP = 0.83 * (120 / 0.83) + 120 |
解释:
0.83 B
折算成 A:0.83 * (120 / 0.83) = 120 A
- 加上池子里那部分 120 A
- 总计 =
240 A
🔹 5. 差异的原因(核心)
- 不做 LP:你完全跟随 B 的涨幅(相当于持有单边仓位),因此获得更高的收益 → 244.58 A
- 做 LP:池子自动帮你做了「A-B 的平衡配置」,你在 A 涨的时候被动卖掉了一部分 B,所以赚得少 → 240 A
这就是著名的 无常损失(Impermanent Loss, IL):
- 相比单纯持有,你少赚了一点
- 但 LP 有手续费奖励(swap 手续费),这可能会补偿 IL