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;
}
}
网友评论