UniswapV2版本重要点的简要概述
<!--StartFragment-->
Uniswap V2 是以太坊上去中心化交易协议的第二个主要版本,于 2020 年 5 月推出。它允许任意两个 ERC20 代币之间的自动交易(无需 ETH 作为中间媒介),并引入了时间加权平均价格(TWAP)、闪电贷、合约模块化等改进。
keccak256
和 CREATE2
算法计算得出。function createPair(address tokenA, address tokenB)
用于创建新的交易对。x * y = k
的逻辑。为用户提供易用接口来进行交易、添加/移除流动性。
封装对 Pair 合约的底层调用逻辑。
主要函数如:
addLiquidity
removeLiquidity
swapExactTokensForTokens
swapTokensForExactTokens
Uniswap V2 使用的模型为常数乘积公式:
x⋅y=k
其中:
x
为 token0 的储备量,y
为 token1 的储备量,k
为常数,在添加/移除流动性除外,交易过程始终保持不变。任一交易操作(swap)都必须使 x * y
增加或保持不变(考虑手续费后)。
手续费以“留在池子中”的方式表现,即:
k
增加,LP 通过移除流动性分享这一增长部分。uint public constant MINIMUM_LIQUIDITY = 10**3;
if (_totalSupply == 0) {
//第一次添加流动性Token
liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
_mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
} else {
//>1 次添加流动性Token
liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
}
初始添加流动性时: liquidity = (amount0 * amount1) ^ (1/2) - MINIMUM_LIQUIDITY;
非首次添加时: liquidity = min(amount0 totalSupply / _reserve0 , amountb totalSupply / _reserve1);
为什么要保留MINIMUM_LIQUIDITY: <!--StartFragment-->
防止初始流动性提供者抽走全部资金
MINIMUM_LIQUIDITY
,第一位添加流动性的用户可以:
MINIMUM_LIQUIDITY
后,即使提供者移除全部流动性,这部分是 永远无法移除的,能确保池子仍有小量残余资产,防止错误。保持系统最小量精度稳定性
<!--EndFragment-->
Uniswap V2 的价格由池中两种代币储备决定:
$Ptoken0 / token1 = reserve1 / reserve0$
交易中因 x*y=k
的保持,价格会随交易滑动,产生所谓“滑点”。
例如,要用 token0 换 token1,输入 Δx 后,得到:
$Δy = reserve1−(reserve0 reserve1) / ( reserve0 + 0.997Δx) $
注意:0.997 是手续费后的因子。
每个区块更新一次 price0CumulativeLast
和 price1CumulativeLast
累加器:
$priceX+=currentPriceX⋅timeElapsed$
外部合约可根据两个时间点间的差值除以时间,得出该段时间的平均价格。主要用于喂价和防操纵。
允许用户“借出”池中资产,在同一笔交易中归还或回滚:
swap
函数时,设置 to
为一个合约地址,该地址实现 uniswapV2Call
回调。用途包括:
lock
修饰符。minAmountOut
。supportingFeeOnTransfer
变种方法。<!--EndFragment-->
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!