uint256 -> uint

use 256 in more places

break out separate functions
This commit is contained in:
Noah Zinsmeister
2019-12-04 17:08:38 -05:00
parent e88ba8b09c
commit f06361140c
9 changed files with 179 additions and 180 deletions

View File

@ -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)));
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View 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);
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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");
}
}
}