uint256 -> uint
use 256 in more places break out separate functions
This commit is contained in:
@ -11,7 +11,7 @@ import "./token/SafeTransfer.sol";
|
||||
|
||||
contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTransfer {
|
||||
using SafeMath128 for uint128;
|
||||
using SafeMath256 for uint256;
|
||||
using SafeMath for uint;
|
||||
using UQ104x104 for uint240;
|
||||
|
||||
struct TokenData {
|
||||
@ -43,26 +43,26 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
event LiquidityMinted(
|
||||
address indexed sender,
|
||||
address indexed recipient,
|
||||
uint128 amountToken0,
|
||||
uint128 amountToken1,
|
||||
uint amountToken0,
|
||||
uint amountToken1,
|
||||
uint128 reserveToken0,
|
||||
uint128 reserveToken1,
|
||||
uint256 liquidity
|
||||
uint liquidity
|
||||
);
|
||||
event LiquidityBurned(
|
||||
address indexed sender,
|
||||
address indexed recipient,
|
||||
uint128 amountToken0,
|
||||
uint128 amountToken1,
|
||||
uint amountToken0,
|
||||
uint amountToken1,
|
||||
uint128 reserveToken0,
|
||||
uint128 reserveToken1,
|
||||
uint256 liquidity
|
||||
uint liquidity
|
||||
);
|
||||
event Swap(
|
||||
address indexed sender,
|
||||
address indexed recipient,
|
||||
uint128 amountToken0,
|
||||
uint128 amountToken1,
|
||||
uint amountToken0,
|
||||
uint amountToken1,
|
||||
uint128 reserveToken0,
|
||||
uint128 reserveToken1,
|
||||
address input
|
||||
@ -114,18 +114,16 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getAmountOutput(uint128 amountInput, uint128 reserveInput, uint128 reserveOutput)
|
||||
public pure returns (uint128 amountOutput)
|
||||
{
|
||||
require(amountInput > 0 && reserveInput > 0 && reserveOutput > 0, "UniswapV2: INVALID_VALUE");
|
||||
uint256 amountInputWithFee = uint256(amountInput).mul(997);
|
||||
uint256 numerator = amountInputWithFee.mul(reserveOutput);
|
||||
uint256 denominator = uint256(reserveInput).mul(1000).add(amountInputWithFee);
|
||||
amountOutput = (numerator / denominator).downcast128();
|
||||
// uniswap-v1 naming
|
||||
function getInputPrice(uint inputAmount, uint inputReserve, uint outputReserve) public pure returns (uint) {
|
||||
require(inputReserve > 0 && outputReserve > 0, "UniswapV2: INVALID_VALUE");
|
||||
uint amountInputWithFee = inputAmount.mul(997);
|
||||
uint numerator = amountInputWithFee.mul(outputReserve);
|
||||
uint denominator = inputReserve.mul(1000).add(amountInputWithFee);
|
||||
return numerator / denominator;
|
||||
}
|
||||
|
||||
function update(TokenData memory balances) private {
|
||||
function update(uint balanceToken0, uint balanceToken1) private {
|
||||
uint32 blockNumberLast = readOracleBlockNumber();
|
||||
|
||||
// if any blocks have gone by since the last time this function was called, we have to update
|
||||
@ -148,102 +146,97 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
}
|
||||
|
||||
// update reserves
|
||||
reserves = balances;
|
||||
reserves = TokenData({
|
||||
token0: balanceToken0.clamp128(),
|
||||
token1: balanceToken1.clamp128()
|
||||
});
|
||||
}
|
||||
|
||||
function mintLiquidity(address recipient) external lock returns (uint256 liquidity) {
|
||||
TokenData memory balances = TokenData({
|
||||
token0: IERC20(token0).balanceOf(address(this)).downcast128(),
|
||||
token1: IERC20(token1).balanceOf(address(this)).downcast128()
|
||||
});
|
||||
TokenData memory amounts = TokenData({
|
||||
token0: balances.token0.sub(reserves.token0),
|
||||
token1: balances.token1.sub(reserves.token1)
|
||||
});
|
||||
function mintLiquidity(address recipient) external lock returns (uint liquidity) {
|
||||
uint balanceToken0 = IERC20(token0).balanceOf(address(this));
|
||||
uint balanceToken1 = IERC20(token1).balanceOf(address(this));
|
||||
uint amountToken0 = balanceToken0.sub(reserves.token0);
|
||||
uint amountToken1 = balanceToken1.sub(reserves.token1);
|
||||
|
||||
if (totalSupply == 0) {
|
||||
liquidity = Math.sqrt(uint256(amounts.token0).mul(amounts.token1));
|
||||
} else {
|
||||
liquidity = Math.min(
|
||||
uint256(amounts.token0).mul(totalSupply) / reserves.token0,
|
||||
uint256(amounts.token1).mul(totalSupply) / reserves.token1
|
||||
);
|
||||
}
|
||||
liquidity = totalSupply == 0 ?
|
||||
Math.sqrt(amountToken0.mul(amountToken1)) :
|
||||
Math.min(amountToken0.mul(totalSupply) / reserves.token0, amountToken1.mul(totalSupply) / reserves.token1);
|
||||
require(liquidity > 0, "UniswapV2: INSUFFICIENT_VALUE");
|
||||
mint(recipient, liquidity);
|
||||
|
||||
if (liquidity > 0) mint(recipient, liquidity);
|
||||
update(balances);
|
||||
update(balanceToken0, balanceToken1);
|
||||
emit LiquidityMinted(
|
||||
msg.sender, recipient, amounts.token0, amounts.token1, balances.token0, balances.token1, liquidity
|
||||
msg.sender, recipient, amountToken0, amountToken1, reserves.token0, reserves.token1, liquidity
|
||||
);
|
||||
}
|
||||
|
||||
function burnLiquidity(address recipient) external lock returns (uint128 amountToken0, uint128 amountToken1) {
|
||||
uint256 liquidity = balanceOf[address(this)];
|
||||
TokenData memory amounts = TokenData({
|
||||
token0: amountToken0 = (liquidity.mul(reserves.token0) / totalSupply).downcast128(),
|
||||
token1: amountToken1 = (liquidity.mul(reserves.token1) / totalSupply).downcast128()
|
||||
});
|
||||
if (amounts.token0 > 0) safeTransfer(token0, recipient, amounts.token0);
|
||||
if (amounts.token1 > 0) safeTransfer(token1, recipient, amounts.token1);
|
||||
if (liquidity > 0) _burn(address(this), liquidity);
|
||||
function burnLiquidity(address recipient) external lock returns (uint amountToken0, uint amountToken1) {
|
||||
uint liquidity = balanceOf[address(this)];
|
||||
require(liquidity > 0, "UniswapV2: INSUFFICIENT_VALUE");
|
||||
|
||||
TokenData memory balances = TokenData({
|
||||
token0: IERC20(token0).balanceOf(address(this)).downcast128(),
|
||||
token1: IERC20(token1).balanceOf(address(this)).downcast128()
|
||||
});
|
||||
update(balances);
|
||||
amountToken0 = liquidity.mul(reserves.token0) / totalSupply;
|
||||
amountToken1 = liquidity.mul(reserves.token1) / totalSupply;
|
||||
require(amountToken0 > 0 && amountToken1 > 0, "UniswapV2: INSUFFICIENT_VALUE");
|
||||
safeTransfer(token0, recipient, amountToken0);
|
||||
safeTransfer(token1, recipient, amountToken1);
|
||||
|
||||
update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)));
|
||||
emit LiquidityBurned(
|
||||
msg.sender, recipient, amounts.token0, amounts.token1, balances.token0, balances.token1, liquidity
|
||||
msg.sender, recipient, amountToken0, amountToken1, reserves.token0, reserves.token1, liquidity
|
||||
);
|
||||
}
|
||||
|
||||
function rageQuit(address output, address recipient) external lock returns (uint128 amountOutput) {
|
||||
uint256 liquidity = balanceOf[address(this)];
|
||||
TokenData memory amounts;
|
||||
function rageQuitToken0(address recipient) external lock returns (uint amountToken1) {
|
||||
uint liquidity = balanceOf[address(this)];
|
||||
require(liquidity > 0, "UniswapV2: INSUFFICIENT_VALUE");
|
||||
|
||||
if (output == token0) {
|
||||
amounts.token0 = amountOutput = (liquidity.mul(reserves.token0) / totalSupply).downcast128();
|
||||
safeTransfer(token0, recipient, amounts.token0);
|
||||
} else {
|
||||
require(output == token1, "UniswapV2: INVALID_OUTPUT");
|
||||
amounts.token1 = amountOutput = (liquidity.mul(reserves.token1) / totalSupply).downcast128();
|
||||
safeTransfer(token1, recipient, amounts.token1);
|
||||
}
|
||||
amountToken1 = liquidity.mul(reserves.token1) / totalSupply;
|
||||
require(amountToken1 > 0, "UniswapV2: INSUFFICIENT_VALUE");
|
||||
safeTransfer(token1, recipient, amountToken1);
|
||||
|
||||
if (liquidity > 0) _burn(address(this), liquidity);
|
||||
|
||||
TokenData memory balances = TokenData({
|
||||
token0: IERC20(token0).balanceOf(address(this)).downcast128(),
|
||||
token1: IERC20(token1).balanceOf(address(this)).downcast128()
|
||||
});
|
||||
update(balances);
|
||||
emit LiquidityBurned(
|
||||
msg.sender, recipient, amounts.token0, amounts.token1, balances.token0, balances.token1, liquidity
|
||||
);
|
||||
update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)));
|
||||
emit LiquidityBurned(msg.sender, recipient, 0, amountToken1, reserves.token0, reserves.token1, liquidity);
|
||||
}
|
||||
|
||||
function swap(address input, address recipient) external lock returns (uint128 amountOutput) {
|
||||
TokenData memory balances;
|
||||
TokenData memory amounts;
|
||||
function rageQuitToken1(address recipient) external lock returns (uint amountToken0) {
|
||||
uint liquidity = balanceOf[address(this)];
|
||||
require(liquidity > 0, "UniswapV2: INSUFFICIENT_VALUE");
|
||||
|
||||
if (input == token0) {
|
||||
balances.token0 = IERC20(input).balanceOf(address(this)).downcast128();
|
||||
amounts.token0 = balances.token0.sub(reserves.token0);
|
||||
amounts.token1 = amountOutput = getAmountOutput(amounts.token0, reserves.token0, reserves.token1);
|
||||
safeTransfer(token1, recipient, amounts.token1);
|
||||
balances.token1 = IERC20(token1).balanceOf(address(this)).downcast128();
|
||||
} else {
|
||||
require(input == token1, "UniswapV2: INVALID_INPUT");
|
||||
balances.token1 = IERC20(input).balanceOf(address(this)).downcast128();
|
||||
amounts.token1 = balances.token1.sub(reserves.token1);
|
||||
amounts.token0 = amountOutput = getAmountOutput(amounts.token1, reserves.token1, reserves.token0);
|
||||
safeTransfer(token0, recipient, amounts.token0);
|
||||
balances.token0 = IERC20(token0).balanceOf(address(this)).downcast128();
|
||||
}
|
||||
amountToken0 = liquidity.mul(reserves.token0) / totalSupply;
|
||||
require(amountToken0 > 0, "UniswapV2: INSUFFICIENT_VALUE");
|
||||
safeTransfer(token0, recipient, amountToken0);
|
||||
|
||||
update(balances);
|
||||
emit Swap(
|
||||
msg.sender, recipient, amounts.token0, amounts.token1, balances.token0, balances.token1, input
|
||||
);
|
||||
update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)));
|
||||
emit LiquidityBurned(msg.sender, recipient, amountToken0, 0, reserves.token0, reserves.token1, liquidity);
|
||||
}
|
||||
|
||||
function swapToken0(address recipient) external lock returns (uint amountToken1) {
|
||||
uint balanceToken0 = IERC20(token0).balanceOf(address(this));
|
||||
uint amountToken0 = balanceToken0.sub(reserves.token0); // this can fail
|
||||
require(amountToken0 > 0, "UniswapV2: INSUFFICIENT_VALUE_INPUT");
|
||||
|
||||
amountToken1 = getInputPrice(amountToken0, reserves.token0, reserves.token1);
|
||||
require(amountToken1 > 0, "UniswapV2: INSUFFICIENT_VALUE_OUTPUT");
|
||||
safeTransfer(token1, recipient, amountToken1);
|
||||
|
||||
update(balanceToken0, IERC20(token1).balanceOf(address(this)));
|
||||
emit Swap(msg.sender, recipient, amountToken0, amountToken1, reserves.token0, reserves.token1, token0);
|
||||
}
|
||||
|
||||
function swapToken1(address recipient) external lock returns (uint amountToken0) {
|
||||
uint balanceToken1 = IERC20(token1).balanceOf(address(this));
|
||||
uint amountToken1 = balanceToken1.sub(reserves.token1); // this can fail
|
||||
require(amountToken1 > 0, "UniswapV2: INSUFFICIENT_VALUE_INPUT");
|
||||
|
||||
amountToken0 = getInputPrice(amountToken1, reserves.token1, reserves.token0);
|
||||
require(amountToken0 > 0, "UniswapV2: INSUFFICIENT_VALUE_OUTPUT");
|
||||
safeTransfer(token0, recipient, amountToken0);
|
||||
|
||||
update(IERC20(token0).balanceOf(address(this)), balanceToken1);
|
||||
emit Swap(msg.sender, recipient, amountToken0, amountToken1, reserves.token0, reserves.token1, token1);
|
||||
}
|
||||
|
||||
function sync() external {
|
||||
update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ contract UniswapV2Factory is IUniswapV2Factory {
|
||||
mapping (address => address[]) private tokensToOtherTokens;
|
||||
address[] public exchanges;
|
||||
|
||||
event ExchangeCreated(address indexed token0, address indexed token1, address exchange, uint256 exchangeNumber);
|
||||
event ExchangeCreated(address indexed token0, address indexed token1, address exchange, uint exchangeNumber);
|
||||
|
||||
constructor(bytes memory _exchangeBytecode) public {
|
||||
require(_exchangeBytecode.length >= 0x20, "UniswapV2Factory: SHORT_BYTECODE");
|
||||
@ -38,11 +38,11 @@ contract UniswapV2Factory is IUniswapV2Factory {
|
||||
return tokensToOtherTokens[token];
|
||||
}
|
||||
|
||||
function getOtherTokensLength(address token) external view returns (uint256) {
|
||||
function getOtherTokensLength(address token) external view returns (uint) {
|
||||
return tokensToOtherTokens[token].length;
|
||||
}
|
||||
|
||||
function getExchangesLength() external view returns(uint256) {
|
||||
function getExchangesLength() external view returns(uint) {
|
||||
return exchanges.length;
|
||||
}
|
||||
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
pragma solidity 0.5.12;
|
||||
|
||||
interface IERC20 {
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
event Transfer(address indexed from, address indexed to, uint value);
|
||||
event Approval(address indexed owner, address indexed spender, uint value);
|
||||
|
||||
function name() external view returns (string memory);
|
||||
function symbol() external view returns (string memory);
|
||||
function decimals() external view returns (uint8);
|
||||
function totalSupply() external view returns (uint256);
|
||||
function balanceOf(address owner) external view returns (uint256);
|
||||
function allowance(address owner, address spender) external view returns (uint256);
|
||||
function totalSupply() external view returns (uint);
|
||||
function balanceOf(address owner) external view returns (uint);
|
||||
function allowance(address owner, address spender) external view returns (uint);
|
||||
|
||||
function transfer(address to, uint256 value) external returns (bool);
|
||||
function approve(address spender, uint256 value) external returns (bool);
|
||||
function transferFrom(address from, address to, uint256 value) external returns (bool);
|
||||
function transfer(address to, uint value) external returns (bool);
|
||||
function approve(address spender, uint value) external returns (bool);
|
||||
function transferFrom(address from, address to, uint value) external returns (bool);
|
||||
|
||||
function burn(uint256 value) external;
|
||||
function burnFrom(address from, uint256 value) external;
|
||||
function burn(uint value) external;
|
||||
function burnFrom(address from, uint value) external;
|
||||
|
||||
function DOMAIN_SEPARATOR() external view returns (bytes32);
|
||||
function APPROVE_TYPEHASH() external pure returns (bytes32);
|
||||
function nonces(address owner) external view returns (uint256);
|
||||
function nonces(address owner) external view returns (uint);
|
||||
|
||||
function approveMeta(
|
||||
address owner, address spender, uint256 value, uint256 nonce, uint256 expiration, uint8 v, bytes32 r, bytes32 s
|
||||
address owner, address spender, uint value, uint nonce, uint expiration, uint8 v, bytes32 r, bytes32 s
|
||||
)
|
||||
external;
|
||||
}
|
||||
|
||||
@ -4,26 +4,26 @@ interface IUniswapV2 {
|
||||
event LiquidityMinted(
|
||||
address indexed sender,
|
||||
address indexed recipient,
|
||||
uint128 amountToken0,
|
||||
uint128 amountToken1,
|
||||
uint amountToken0,
|
||||
uint amountToken1,
|
||||
uint128 reserveToken0,
|
||||
uint128 reserveToken1,
|
||||
uint256 liquidity
|
||||
uint liquidity
|
||||
);
|
||||
event LiquidityBurned(
|
||||
address indexed sender,
|
||||
address indexed recipient,
|
||||
uint128 amountToken0,
|
||||
uint128 amountToken1,
|
||||
uint amountToken0,
|
||||
uint amountToken1,
|
||||
uint128 reserveToken0,
|
||||
uint128 reserveToken1,
|
||||
uint256 liquidity
|
||||
uint liquidity
|
||||
);
|
||||
event Swap(
|
||||
address indexed sender,
|
||||
address indexed recipient,
|
||||
uint128 amountToken0,
|
||||
uint128 amountToken1,
|
||||
uint amountToken0,
|
||||
uint amountToken1,
|
||||
uint128 reserveToken0,
|
||||
uint128 reserveToken1,
|
||||
address input
|
||||
@ -38,11 +38,13 @@ interface IUniswapV2 {
|
||||
function readOracleBlockNumber() external view returns (uint32);
|
||||
function consultOracle() external view returns (uint240, uint240);
|
||||
|
||||
function getAmountOutput(uint128 amountInput, uint128 reserveInput, uint128 reserveOutput)
|
||||
external pure returns (uint128 amountOutput);
|
||||
function getInputPrice(uint inputAmount, uint inputReserve, uint outputReserve) external pure returns (uint);
|
||||
|
||||
function mintLiquidity(address recipient) external returns (uint256 liquidity);
|
||||
function burnLiquidity(address recipient) external returns (uint128 amountToken0, uint128 amountToken1);
|
||||
function rageQuit(address output, address recipient) external returns (uint128 amountOutput);
|
||||
function swap(address input, address recipient) external returns (uint128 amountOutput);
|
||||
function mintLiquidity(address recipient) external returns (uint liquidity);
|
||||
function burnLiquidity(address recipient) external returns (uint amountToken0, uint amountToken1);
|
||||
function rageQuitToken0(address recipient) external returns (uint amountToken1);
|
||||
function rageQuitToken1(address recipient) external returns (uint amountToken0);
|
||||
function swapToken0(address recipient) external returns (uint amountToken1);
|
||||
function swapToken1(address recipient) external returns (uint amountToken0);
|
||||
function sync() external;
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
pragma solidity 0.5.12;
|
||||
|
||||
library Math {
|
||||
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
function min(uint x, uint y) internal pure returns (uint z) {
|
||||
return x <= y ? x : y;
|
||||
}
|
||||
|
||||
function sqrt(uint256 x) internal pure returns (uint256 y) {
|
||||
function sqrt(uint x) internal pure returns (uint y) {
|
||||
if (x == 0) return 0;
|
||||
else if (x <= 3) return 1;
|
||||
uint256 z = (x + 1) / 2;
|
||||
uint z = (x + 1) / 2;
|
||||
y = x;
|
||||
while (z < y) {
|
||||
y = z;
|
||||
|
||||
27
contracts/libraries/SafeMath.sol
Normal file
27
contracts/libraries/SafeMath.sol
Normal file
@ -0,0 +1,27 @@
|
||||
pragma solidity 0.5.12;
|
||||
|
||||
library SafeMath {
|
||||
function add(uint x, uint y) internal pure returns (uint z) {
|
||||
require((z = x + y) >= x, "ds-math-add-overflow");
|
||||
}
|
||||
function sub(uint x, uint y) internal pure returns (uint z) {
|
||||
require((z = x - y) <= x, "ds-math-sub-underflow");
|
||||
}
|
||||
function mul(uint x, uint y) internal pure returns (uint z) {
|
||||
require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
|
||||
}
|
||||
|
||||
function clamp128(uint y) internal pure returns (uint128 z) {
|
||||
z = y <= uint128(-1) ? uint128(y) : uint128(-1);
|
||||
}
|
||||
|
||||
function downcast128(uint y) internal pure returns (uint128 z) {
|
||||
require(y <= uint128(-1), "downcast-128-overflow");
|
||||
z = uint128(y);
|
||||
}
|
||||
|
||||
function downcast32(uint y) internal pure returns (uint32 z) {
|
||||
require(y <= uint32(-1), "downcast-32-overflow");
|
||||
z = uint32(y);
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
pragma solidity 0.5.12;
|
||||
|
||||
library SafeMath256 {
|
||||
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
require((z = x + y) >= x, "ds-math-add-overflow");
|
||||
}
|
||||
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
require((z = x - y) <= x, "ds-math-sub-underflow");
|
||||
}
|
||||
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
|
||||
}
|
||||
|
||||
function downcast128(uint256 y) internal pure returns (uint128 z) {
|
||||
require(y <= uint128(-1), "downcast-128-overflow");
|
||||
z = uint128(y);
|
||||
}
|
||||
|
||||
function downcast32(uint256 y) internal pure returns (uint32 z) {
|
||||
require(y <= uint32(-1), "downcast-32-overflow");
|
||||
z = uint32(y);
|
||||
}
|
||||
}
|
||||
@ -2,33 +2,33 @@ pragma solidity 0.5.12;
|
||||
|
||||
import "../interfaces/IERC20.sol";
|
||||
|
||||
import "../libraries/SafeMath256.sol";
|
||||
import "../libraries/SafeMath.sol";
|
||||
|
||||
contract ERC20 is IERC20 {
|
||||
using SafeMath256 for uint256;
|
||||
using SafeMath for uint;
|
||||
|
||||
// ERC-20 data
|
||||
string public name;
|
||||
string public symbol;
|
||||
uint8 public decimals;
|
||||
uint256 public totalSupply;
|
||||
mapping (address => uint256) public balanceOf;
|
||||
mapping (address => mapping (address => uint256)) public allowance;
|
||||
uint public totalSupply;
|
||||
mapping (address => uint) public balanceOf;
|
||||
mapping (address => mapping (address => uint)) public allowance;
|
||||
|
||||
// ERC-721 data
|
||||
bytes32 public DOMAIN_SEPARATOR;
|
||||
// keccak256("Approve(address owner,address spender,uint256 value,uint256 nonce,uint256 expiration)");
|
||||
bytes32 public constant APPROVE_TYPEHASH = hex'25a0822e8c2ed7ff64a57c55df37ff176282195b9e0c9bb770ed24a300c89762';
|
||||
mapping (address => uint256) public nonces;
|
||||
mapping (address => uint) public nonces;
|
||||
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
event Transfer(address indexed from, address indexed to, uint value);
|
||||
event Approval(address indexed owner, address indexed spender, uint value);
|
||||
|
||||
function MOCK_getChainId() private pure returns (uint256) {
|
||||
function MOCK_getChainId() private pure returns (uint) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _totalSupply) public {
|
||||
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint _totalSupply) public {
|
||||
name = _name;
|
||||
symbol = _symbol;
|
||||
decimals = _decimals;
|
||||
@ -42,52 +42,52 @@ contract ERC20 is IERC20 {
|
||||
));
|
||||
}
|
||||
|
||||
function mint(address to, uint256 value) internal {
|
||||
function mint(address to, uint value) internal {
|
||||
totalSupply = totalSupply.add(value);
|
||||
balanceOf[to] = balanceOf[to].add(value);
|
||||
emit Transfer(address(0), to, value);
|
||||
}
|
||||
|
||||
function _burn(address from, uint256 value) internal {
|
||||
function _burn(address from, uint value) internal {
|
||||
balanceOf[from] = balanceOf[from].sub(value);
|
||||
totalSupply = totalSupply.sub(value);
|
||||
emit Transfer(from, address(0), value);
|
||||
}
|
||||
|
||||
function _transfer(address from, address to, uint256 value) private {
|
||||
function _transfer(address from, address to, uint value) private {
|
||||
balanceOf[from] = balanceOf[from].sub(value);
|
||||
balanceOf[to] = balanceOf[to].add(value);
|
||||
emit Transfer(from, to, value);
|
||||
}
|
||||
|
||||
function _approve(address owner, address spender, uint256 value) private {
|
||||
function _approve(address owner, address spender, uint value) private {
|
||||
allowance[owner][spender] = value;
|
||||
emit Approval(owner, spender, value);
|
||||
}
|
||||
|
||||
function transfer(address to, uint256 value) external returns (bool) {
|
||||
function transfer(address to, uint value) external returns (bool) {
|
||||
_transfer(msg.sender, to, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function burn(uint256 value) external {
|
||||
function burn(uint value) external {
|
||||
_burn(msg.sender, value);
|
||||
}
|
||||
|
||||
function approve(address spender, uint256 value) external returns (bool) {
|
||||
function approve(address spender, uint value) external returns (bool) {
|
||||
_approve(msg.sender, spender, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function approveMeta(
|
||||
address owner, address spender, uint256 value, uint256 nonce, uint256 expiration, uint8 v, bytes32 r, bytes32 s
|
||||
address owner, address spender, uint value, uint nonce, uint expiration, uint8 v, bytes32 r, bytes32 s
|
||||
)
|
||||
external
|
||||
{
|
||||
require(nonce == nonces[owner]++, "ERC20: INVALID_NONCE");
|
||||
require(expiration > block.timestamp, "ERC20: EXPIRED_SIGNATURE");
|
||||
require(v == 27 || v == 28, "ECDSA: INVALID_V");
|
||||
require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: INVALID_S");
|
||||
require(uint(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: INVALID_S");
|
||||
|
||||
bytes32 digest = keccak256(abi.encodePacked(
|
||||
hex'19',
|
||||
@ -109,16 +109,16 @@ contract ERC20 is IERC20 {
|
||||
_approve(owner, spender, value);
|
||||
}
|
||||
|
||||
function transferFrom(address from, address to, uint256 value) external returns (bool) {
|
||||
if (allowance[from][msg.sender] != uint256(-1)) {
|
||||
function transferFrom(address from, address to, uint value) external returns (bool) {
|
||||
if (allowance[from][msg.sender] != uint(-1)) {
|
||||
allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
|
||||
}
|
||||
_transfer(from, to, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function burnFrom(address from, uint256 value) external {
|
||||
if (allowance[from][msg.sender] != uint256(-1)) {
|
||||
function burnFrom(address from, uint value) external {
|
||||
if (allowance[from][msg.sender] != uint(-1)) {
|
||||
allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
|
||||
}
|
||||
_burn(from, value);
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
pragma solidity 0.5.12;
|
||||
|
||||
contract SafeTransfer {
|
||||
function safeTransfer(address token, address to, uint256 value) internal {
|
||||
(bool success, bytes memory data) = token.call(abi.encodeWithSignature("transfer(address,uint256)", to, value));
|
||||
function safeTransfer(address token, address to, uint value) internal {
|
||||
(bool success, bytes memory data) = token.call(abi.encodeWithSignature("transfer(address,uint)", to, value));
|
||||
|
||||
require(success, "SafeTransfer: SWAP_FAILED");
|
||||
require(success, "SafeTransfer: SWAP_REVERTED");
|
||||
|
||||
if (data.length == 32) {
|
||||
require(abi.decode(data, (bool)), "SafeTransfer: SWAP_FAILED");
|
||||
require(abi.decode(data, (bool)), "SafeTransfer: SWAP_UNSUCCESSFUL");
|
||||
} else if (data.length > 32) {
|
||||
revert("SafeTransfer: SWAP_FAILED");
|
||||
revert("SafeTransfer: SWAP_INVALID_RETURN");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user