UniswapV2Router02.sol

pragma solidity =0.6.6;

//导入工厂接口
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
//导入TransferHelper,里面提供一些safe转账方法,以后细看
import '@uniswap/lib/contracts/libraries/TransferHelper.sol';

//导入Router02接口
import './interfaces/IUniswapV2Router02.sol';
//导入Library
import './libraries/UniswapV2Library.sol';
//SafeMath
import './libraries/SafeMath.sol';
//IERC20
import './interfaces/IERC20.sol';
//IWETH,包含deposit、withdraw、transfer
import './interfaces/IWETH.sol';

//继承接口
contract UniswapV2Router02 is IUniswapV2Router02 {
    using SafeMath for uint;

    //immutable表示该值为不可变量
    //override表示覆盖了父函数/变量
    address public immutable override factory;
    address public immutable override WETH;

    //提交一个deadline,函数会验证当前时间是否超过deadline,若未超过,函数继续调用
    modifier ensure(uint deadline) {
        require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED');
        _;
    }

    //部署合约时,提交一个工厂地址,一个WETH地址,被合约写入状态变量,且不可更改
    constructor(address _factory, address _WETH) public {
        factory = _factory;
        //一个兑换WETH的池子
        WETH = _WETH;
    }

    //当调用者只传ETH,并未调用函数,并未提供信息,receive被触发
    receive() external payable {
        //若向本合约打钱的对象地址为WETH,验证通过
        //assert用于验证内部错误
        //只通过回调接收来自WETH合约的ETH
        assert(msg.sender == WETH); // only accept ETH via fallback from the WETH contract
    }

    //增加流动性
    // **** ADD LIQUIDITY ****
    //提交两种代币的地址、期望的注入量、注入最小值,返回经过计算后,函数建议注入的两种代币的数量
    function _addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin
    ) internal virtual returns (uint amountA, uint amountB) {
        //创建一个交易对,如果它此前并不存在
        // create the pair if it doesn't exist yet
        if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) {
            IUniswapV2Factory(factory).createPair(tokenA, tokenB);
        }
        //获取交易对中两种代币的储备量,这种getReserves()里面填参数的形式是从哪里规定的?
        //在Pair中的定义是不填参的
        (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB);
        //如果交易对的代币储备量为0
        if (reserveA == 0 && reserveB == 0) {
            //建议的注入量即为函数调用者自己想注入的量
            (amountA, amountB) = (amountADesired, amountBDesired);
        } 
        //若交易对的代币储备量不为0
        else {
            //通过Library.quote()计算若按照用户的期望量注入A,B的最优注入量应该为多少
            uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB);
            //如果B的最优注入量<=B的期望注入量,说明用户的B数量足够
            if (amountBOptimal <= amountBDesired) {
                //保证B的最优注入量>=最小注入量
                require(amountBOptimal >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT');
                //将建议的A、B注入量进行设置
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } 
            //若用户的B数量不足
            else {
                //计算A的最优注入量
                uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA);
                //保证用户的A币数量足够
                assert(amountAOptimal <= amountADesired);
                //保证A最优注入量>=最小注入量
                require(amountAOptimal >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT');
                //返回建议的A、B注入量
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }
    //先调用_addLiquidity()计算应该最优注入A、B量,然后真的进行交易,同时转给用户相应的流动性token
    //to参数表示接收流动性代币的地址,deadline表示交易的最迟时间
    //返回的参数增加了一个liquidity,表示注入流动性时,同步返给用户记录流动性的代币的数量
    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
        //先调用_addLiquidity()
        (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        //获取交易对的地址
        address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB);
        //将token从用户手里传入交易对
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amoun
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值