原文发布在 https://github.com/33357/smartcontract-apps这是一个面向中文社区,分析市面上智能合约应用的架构与实现的仓库。欢迎关注开源知识项目!
Uniswap-v2 Router合约分析Router 合约是用户使用 Uniswap-v2 进行交换直接调用的合约,通过分析它可以深入了解 Uniswap-v2 的产品使用和运行逻辑。
演示代码仓库:https://github.com/33357/uniswap-v2-contract,这里使用的是Router02。
增加流动性-
内部函数(仅供合约内部调用)
- _addLiquidity
-
代码速浏览
function _addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin ) internal virtual returns (uint amountA, uint amountB) { if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) { IUniswapV2Factory(factory).createPair(tokenA, tokenB); } (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB); if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); } else { uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB); if (amountBOptimal = amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); (amountA, amountB) = (amountADesired, amountBOptimal); } else { uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA); assert(amountAOptimal = amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); (amountA, amountB) = (amountAOptimal, amountBDesired); } } }
-
参数分析
函数
_addLiquidity
的入参有6个,出参有2个,对应的解释如下:function _addLiquidity( address tokenA, // 添加流动性 tokenA 的地址 address tokenB, // 添加流动性 tokenB 的地址 uint amountADesired, // 期望添加 tokenA 的数量 uint amountBDesired, // 期望添加 tokenB 的数量 uint amountAMin, // 添加 tokenA 的最小数量 uint amountBMin // 添加 tokenB 的最小数量 ) internal virtual returns ( uint amountA, // 实际添加 tokenA 的数量 uint amountB // 实际添加 tokenB 的数量 ) { ... }
tokenA
和tokenB
很好理解,但是为什么要有amountADesired
、amountADesired
、amountAMin
、amountBMin
呢?实际上因为用户在区块链上添加流动性并不是实时完成的,因此会因为其他用户的操作产生数据偏差,因此需要在这里指定一个为tokenA
和tokenB
添加流动性的数值范围。在添加流动性的过程中,首先会根据amountADesired
计算出实际要添加的amountB
,如果amountB
大于amountBDesired
就换成根据amountBDesired
计算出实际要添加的amountA
。 -
实现分析
... { // 如果 tokenA,tokenB 的流动池不存在,就创建流动池 if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) { IUniswapV2Factory(factory).createPair(tokenA, tokenB); } // 获取 tokenA,tokenB 的目前库存数量 (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB); if (reserveA == 0 && reserveB == 0) { // 如果库存数量为0,也就是新建 tokenA,tokenB 的流动池,那么实际添加的amountA, amountB 就是 amountADesired 和 amountBDesired (amountA, amountB) = (amountADesired, amountBDesired); } else { // reserveA*reserveB/amountADesired,算出实际要添加的 tokenB 数量 amountBOptimal uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB); if (amountBOptimal
关注打赏
-
- _addLiquidity
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?