UniswapV2学习记录
function createPair( address tokenA, address tokenB ) external returns (address pair)
用create2创建交易对,并初始化pair中的token
ERC20合约,提供LP代币
function mint(address to) external lock returns (uint liquidity)
给流动性提供者铸造LP
function burn( address to ) external lock returns (uint amount0, uint amount1)
销毁LP,拿回代币
function swap( uint amount0Out, uint amount1Out, address to, bytes calldata data ) external
兑换代币
前端交互合约
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
)
external
override
ensure(deadline)
returns (uint amountA, uint amountB, uint liquidity)
添加流动性,根据用户提供的代币和数量,计算出实际需要的代币数量和LP,然后调用Pair合约的mint铸造代币
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) public override ensure(deadline) returns (uint amountA, uint amountB)
移除流动性,调用Pair合约的burn销毁LP并返回代币
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external override ensure(deadline) returns (uint[] memory amounts)
代币兑换,根据代币兑换路径和输入/输出代币,计算出输出/输入代币数量,调用Pair合约的swap进行交换
function swap( uint amount0Out, uint amount1Out, address to, bytes calldata data )
当to为合约地址时并且data不为空时可以实现闪电贷,合约先把代币转给to合约,to合约在uniswapV2Call函数中必须还回代币(代币0或者代币1都行),Pair合约会检查当前的代币乘积(去除手续费)不能小于原来的k值,否则回滚交易不同的编译器结果不同,在UniswapV2Library中的pariFor拿池子的地址的hash由于是硬编码需要重新计算type(UniswapV2Pair).creationCode
每次update都会跟新用于oracle计算价格。记录 Token1 对 Token0 的时间累积价格,用于下个时间段计算新的价格,新的价格 = (price0Cumulative - price0CumulativeLast) / (t - t0)
UniswapV2Factory中的feeTo一旦设置,表示平台会收取一定手续费。平台收0.3%手续费的1/6 给到这个地址,每次 mint或者burn的时候收费,而不是用户swap的时候,收到的钱又添加到池子里继续拿lp。拿到增发的1/6 除以 (上次的+增发的5/6) = 等比例拿到池子里的lp => (k-klast)/6 / (klast+(k-klast)5/6) = lp/totalSupply => totalSupply(k-klast) / (k*5+klast) 用的这个公式
liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);代码中有最小流动性的限制。如果没有这个限制:
本人初学小白,记录智能合约学习知识,文章内容可信度低,仅供参考,谢谢!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!