添加流动性时保障 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