{"content":{"title":"uniswapV2交易流程简介","body":"###### uniswap V2 协议\r\nV2是uniswap协议的第二版，第一版只支持ETH/ERC20交易对，uniswap应该是目前最大的去中心化交易所，目前常用的是V2，和V3，EVM链的很多去中心化交易所，都是基于uniswap V2改造的，这里先介绍V2（路由合约）。\r\nuniswap V2 提供的功能有，添加流动性，币币兑换，赎回流动性，闪电兑换（不在路由合约）。这里讲解一下，我们添加流动性，赎回流动性，交换币种时都发生了什么，在合约层面调用了哪些方法，不讲细节，只讲重点。\r\n\r\n###### uniswap V2的主要合约:\r\nUniswapV2Router02 路由合约(下文用Router)\r\nUniswapV2Factory 工厂合约（下文用Factory）\r\nUniswapV2Pair 交易对合约（下文用Pair）\r\n\r\n与前端直接交互的是路由合约 router\r\n\r\n###### 1.添加流动性\r\n addLiquidity\r\naddLiquidityETH\r\n这两个方法区别在于，两种币之中，如果有一个是ETH的，前端就会调用addLiquidityETH。如果是两个普通ERC20的币种，就用addLiquidity。（实际上，addLiquidityETH里也是把ETH也是要换成WETH，最后还是变成ERC20/ERC20交易对）\r\n添加流动性时，如果是第一次添加会判断是否存在这两种币对，不存在就调用工厂合约Factory的createPair方法创建交易对地址。\r\n添加的tokenA和tokenB数量会存到交易对地址里，然后通过交易对合约Pair 铸造一定数量的凭证pairToken给用户，到时用这些pairToken赎回tokenA和tokenB。\r\n代码层面流程(省略参数)：\r\nUniswapV2Router02.addLiquidity()  - 如果不存在交易对 Factory.createPair() - Pair.mint() \r\n\r\n###### 2.币币兑换\r\n币币交换Router V2合约提供了很多方法，大部分从V1遗留的。为了简洁，下面方法不给出参数\r\nswapExactTokensForTokens()  // ERC20Token直接的兑换\r\nswapTokensForExactTokens()  // 同上\r\nswapExactETHForTokens() // WETH换ERC20\r\nswapTokensForExactETH() // ERC20换WETH\r\nswapExactTokensForETH()  // ERC20换ETH\r\nswapETHForExactTokens() // ETH换ERC20\r\nswapExactTokensForTokensSupportingFeeOnTransferTokens() // 支持收取费用的token\r\nswapExactETHForTokensSupportingFeeOnTransferTokens() // 同上，换成了ETH而已\r\nswapExactTokensForETHSupportingFeeOnTransferTokens() // 同上\r\n\r\n总结一下以上方法规律，含有ETH，就是可兑换ETH交易对的，其中ExtraETH就是WETH，最后三个带SupportingFee的方法是V2新增的，意思是支持转账时收取费用的token，和前面方法计算输入token数量方式不一样。\r\n代码层面流程：\r\nRouter.swapExactTokensForTokens() - (中间涉及计算输出数量UniswapV2Library.getAmountsOut ) Pair.swap()\r\nswap涉及到一个计算公式：x * y = k,恒定乘积算法\r\n例如 A 换 B，池子里的流动性乘积 k 在交易前后是不变的。这里不考虑流动性挖矿的费用。如 交易对A/B 里有100 A ，200 B，现在用10A能换多少B呢，\r\n\r\n```\r\n输出B数量 =数量B -  k / （A + 输入A数量） = 200 - (100 * 200) / (100+10) = 18.1\r\n```\r\n</br>\r\n\r\n###### 3.赎回流动性\r\nremoveLiquidity\r\nremoveLiquidityETH\r\nremoveLiquidityWithPermit\r\nremoveLiquidityETHWithPermit\r\nremoveLiquidityETHSupportingFeeOnTransferTokens\r\nremoveLiquidityETHWithPermitSupportingFeeOnTransferTokens\r\n区别在于，如果赎回token中有ETH，则用 removeLiquidityETH。没带permit的用户要先授权给Router合约可以转走pairToken，带permit的把签名做参数一起传输，少一步授权交易。SupportingFee和兑换一样，支持转账收手续费的token。\r\n上面添加流动性说过，赎回流动性，是用pairToken换回tokenA和tokenB, Pair会销毁用户的pairToken，计算出能换回的两种token数量，转给用户。\r\n代码流程：\r\nPair.approve() , Router.removeLiquidity() - Pair. burn()"},"author":{"user":"https://learnblockchain.cn/people/6296","address":null},"history":"bafkreieviegu3h2zprz5sigmibbfmydpknrslq4ybswiagszteq5mfq7hy","timestamp":1706259371,"version":1}