Uniswap V2

Uniswap 使用恒定乘积函数来确定不同加密货币的价格。它就像一个跷跷板,让一切保持平衡。这种方法可以用方程 x*y=k 来概括,其中 x 是流动性池中代币 A 的数量,y 是流动性池中代币 B 的数量,k 是常数。

Uniswap V2 合约分为 v2-core 主要是 Factory 负责创建和管理 Pair,和 v2-periphery 主要是 Router 合约,是 swap 及询价入口

添加流动性

当前池子里有 2ETH,5000USDT,用户输入了添加 500USDT,如何计算 ETH 数量?

添加流动性时保障 x/y 的比例不变
(∆x + x) / (∆y + y) = x/y
∆y = (∆x + x) * y / x - y
∆y = (∆x * y + x * y)/x - y
∆y = ∆x * y / x + y - y
∆y = ∆x * y / x
∆ETH = ∆USDT * 2ETH / 5000USDT
∆ETH = 0.2 ETH

算出需要同投入 0.2 ETH 可以平衡流动性

@startuml skinparam backgroundColor #ffffff00 skinparam DefaultFontColor #DodgerBlue skinparam handwritten true skinparam sequence { ArrowColor LightSkyBlue ActorBorderColor LightSkyBlue LifeLineBorderColor LightSkyBlue LifeLineBackgroundColor #A9DCDF ParticipantBorderColor LightSkyBlue ParticipantBackgroundColor DodgerBlue ParticipantFontName Impact ParticipantFontSize 17 ParticipantFontColor #A9DCDF ActorBackgroundColor aqua ActorFontColor LightSkyBlue ActorFontSize 17 ActorFontName Impact } actor User participant "Router" as A participant "Factory" as B participant "Pair" as C User -> A: addLiquidity 添加/创建流动性 activate A A -> B: 查找 Pair activate B B -> A: getPair 获取 Pair 地址 deactivate B A --> B: createPair 如果未创建先创建 activate B B --> C: deploy 部署 Pair 合约 deactivate B A -> C: 读取 reserves activate C C -> A: 返回 reserve0/reserve1,可能与余额不同 deactivate C note over A: 通过 reserve0/reserve1 的比例计算需要添加的\ntokenA、tokenB 的数量 A -> C: 转账 tokenA / tokenB 给 pair A -> C: mint LP token activate C note over C: 这里有两种情况,\n1)之前流动性为0,则 mint √∆x∆y 数量 LP\n2)如果是增加流动性则 mint totalSupply * min(∆x / x, ∆y / y) 数量流动性 C -> User: mint deactivate C A --> User: 添加完成 deactivate A @enduml

Swap

比如当前池子里有 2ETH,5000USDT,用户卖出 500USDT,如何计算买入的 ETH 数量?

(x + ∆x) * (y - ∆y) = k 在 swap 时,需保证 k(也就是 x * y )值不变
y - ∆y = x*y / (x + ∆x)
∆y = y∆x / (x + ∆x)
∆ETH = 2 * 500 / (5000 + 500)
∆ETH = 0.181818182 ETH

算出卖出 500 USDT 会获得 0.1994 ETH

@startuml skinparam backgroundColor #ffffff00 skinparam DefaultFontColor #DodgerBlue skinparam handwritten true skinparam sequence { ArrowColor LightSkyBlue ActorBorderColor LightSkyBlue LifeLineBorderColor LightSkyBlue LifeLineBackgroundColor #A9DCDF ParticipantBorderColor LightSkyBlue ParticipantBackgroundColor DodgerBlue ParticipantFontName Impact ParticipantFontSize 17 ParticipantFontColor #A9DCDF ActorBackgroundColor aqua ActorFontColor LightSkyBlue ActorFontSize 17 ActorFontName Impact } actor User participant "Router" as A participant "Factory" as B participant "Pair" as C User -> A: swap 进行交易 activate A A -> B: 查找 Pair activate B B -> A: getPair 获取 Pair 地址 deactivate B A -> C: 读取 reserves activate C C -> A: 返回 reserve0/reserve1,可能与余额不同 deactivate C note over A: 通过 reserve0/reserve1 数量计算 outputAmount A -> C: 调用 Pair 的 swap 方法\n更新 Pair 中的 reverse0/reverse1 记账 activate C C -> User: token 转账 deactivate C A --> User: Swap 完成 deactivate A @enduml

在 Uniswap V2 中最重要的就是 Pair 中 reverse0/reverse1 的记账和 x · y=k 这个公式了。

Comments