Uniswap

pragma solidity 0.6.2;


contract Uniswap{
    using SafeMath for uint256;
    ERC20 erc201;
    ERC20 erc202;

    uint256 public k;
    uint256 public tokenTotal1; // 当前合约总token1数量
    uint256 public tokenTotal2; // 当前合约总token2数量
    uint256 public serviceCharge = 3;   // 手续费比例
    uint256 public depositToken1;   // 用户总存储token1数量
    uint256 public depositToken2;   // 用户总存储token2数量

    mapping(address => uint256) public tokenMapping1;   // 地址对应的充值token1数量
    mapping(address => uint256) public tokenMapping2;   // 地址对应的充值token2数量

    address public tokenAddress1;   // token1地址
    address public tokenAddress2;   // token2地址

    // 初始化设置交易对
    constructor(address token1,address token2) public{
        tokenAddress1 = token1;
        tokenAddress2 = token2;
        erc201 = ERC20(token1);
        erc202 = ERC20(token2);
    }
    // 增加流动性
    function addMobility(uint256 value1,uint256 value2) public {
        // 转入token1
        uint256 beforeBalance1 = erc201.balanceOf(address(this));
        erc201.transferFrom(msg.sender,address(this),value1);
        uint256 afterBalance1 = erc201.balanceOf(address(this));
        require(beforeBalance1.add(value1) == afterBalance1);
        // 转入token2
        uint256 beforeBalance2 = erc202.balanceOf(address(this));
        erc202.transferFrom(msg.sender,address(this),value2);
        uint256 afterBalance2 = erc202.balanceOf(address(this));
        require(beforeBalance2.add(value2) == afterBalance2);
        // 更新k
        tokenTotal1 = tokenTotal1.add(value1);
        tokenTotal2 = tokenTotal2.add(value2);
        k = tokenTotal1.mul(tokenTotal2);
        // 记录地址增加流动性数量
        tokenMapping1[msg.sender] = tokenMapping1[msg.sender].add(value1);
        tokenMapping2[msg.sender] = tokenMapping2[msg.sender].add(value2);
        depositToken1 = depositToken1.add(value1);
        depositToken2 = depositToken2.add(value2);
    }
    // 取回
    function turnOut(uint256 value1,uint256 value2) public {
        require(tokenMapping1[msg.sender] >= value1,"token1 balance is not enough");
        require(tokenMapping2[msg.sender] >= value2,"token2 balance is not enough");

        tokenMapping1[msg.sender] = tokenMapping1[msg.sender].sub(value1);
        tokenMapping2[msg.sender] = tokenMapping2[msg.sender].sub(value2);
        // 取回token1
        uint256 tran1 = value1.mul(tokenTotal1).div(depositToken1);
        erc201.transfer(msg.sender,tran1);
        tokenTotal1 = tokenTotal1.sub(tran1);
        depositToken1 = depositToken1.sub(value1);
        // 取回token2
        uint256 tran2 = value2.mul(tokenTotal2).div(depositToken2);
        erc202.transfer(msg.sender,tran2);
        tokenTotal2 = tokenTotal2.sub(tran2);
        depositToken2 = depositToken2.sub(value2);
        // 更新k
        k = tokenTotal1.mul(tokenTotal2);
    }

    // 正向兑换
    function exchangeBuy(uint256 minBuyAmount,uint256 sellAmount) public {
        uint256 serviceChargeAmount = sellAmount.mul(serviceCharge).div(1000);
        // 转入token2
        uint256 beforeBalance2 = erc202.balanceOf(address(this));
        erc202.transferFrom(msg.sender,address(this),sellAmount);
        uint256 afterBalance2 = erc202.balanceOf(address(this));
        require(beforeBalance2.add(sellAmount) == afterBalance2);
        // 计算应该买到token1的数量
        tokenTotal2 = tokenTotal2.add(sellAmount);
        uint256 beforeTokenTotal1 = k.div(tokenTotal2);
        uint256 buyAmount = tokenTotal1.sub(beforeTokenTotal1);
        require(buyAmount >= minBuyAmount,"buy token1 amount is too little");
        tokenTotal1 = beforeTokenTotal1;
        // 转出token1
        uint256 beforeBalance1 = erc201.balanceOf(address(this));
        erc201.transferFrom(address(this),msg.sender,buyAmount.sub(serviceChargeAmount));
        uint256 afterBalance1 = erc201.balanceOf(address(this));
        require(beforeBalance1.sub(buyAmount.sub(serviceChargeAmount)) == afterBalance1);
        // 更新k
        k = tokenTotal1.mul(tokenTotal2);
    }
    // 反向兑换
    function exchangeSell(uint256 sellAmount,uint256 minBuyAmount) public {
        uint256 serviceChargeAmount = sellAmount.mul(serviceCharge).div(1000);
        // 转入token1
        uint256 beforeBalance1 = erc201.balanceOf(address(this));
        erc201.transferFrom(msg.sender,address(this),sellAmount);
        uint256 afterBalance1 = erc201.balanceOf(address(this));
        require(beforeBalance1.add(sellAmount) == afterBalance1);
        // 计算应该买到token2的数量
        tokenTotal1 = tokenTotal1.add(sellAmount);
        uint256 beforeTokenTotal2 = k.div(tokenTotal1);
        uint256 buyAmount = tokenTotal2.sub(beforeTokenTotal2);
        require(buyAmount >= minBuyAmount,"buy token2 amount is too little");
        tokenTotal2 = beforeTokenTotal2;
        // 转出token2
        uint256 beforeBalance2 = erc202.balanceOf(address(this));
        erc202.transferFrom(address(this),msg.sender,buyAmount.sub(serviceChargeAmount));
        uint256 afterBalance2 = erc202.balanceOf(address(this));
        require(beforeBalance2.sub(buyAmount.sub(serviceChargeAmount)) == afterBalance2);
        // 更新k
        k = tokenTotal1.mul(tokenTotal2);
    }
}

interface ERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external;
    function transferFrom(address sender, address recipient, uint256 amount) external;
}
library SafeMath {
    int256 constant private INT256_MIN = -2**255;
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);
        return c;
    }
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0);
        uint256 c = a / b;
        return c;
    }
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;

        return c;
    }
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);

        return c;
    }
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}

你可能感兴趣的:(Uniswap)