diff --git a/contracts/UniswapV2ERC20.sol b/contracts/UniswapV2ERC20.sol index 5d50990..404a8be 100644 --- a/contracts/UniswapV2ERC20.sol +++ b/contracts/UniswapV2ERC20.sol @@ -1,36 +1,40 @@ pragma solidity =0.5.16; -import "./interfaces/IUniswapV2ERC20.sol"; -import "./libraries/SafeMath.sol"; +import './interfaces/IUniswapV2ERC20.sol'; +import './libraries/SafeMath.sol'; contract UniswapV2ERC20 is IUniswapV2ERC20 { using SafeMath for uint; - string constant public name = "Uniswap V2"; - string constant public symbol = "UNI-V2"; - uint8 constant public decimals = 18; + string public constant name = 'Uniswap V2'; + string public constant symbol = 'UNI-V2'; + uint8 public constant decimals = 18; uint public totalSupply; - mapping (address => uint) public balanceOf; - mapping (address => mapping (address => uint)) public allowance; + mapping(address => uint) public balanceOf; + mapping(address => mapping(address => uint)) public allowance; bytes32 public DOMAIN_SEPARATOR; // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; - mapping (address => uint) public nonces; + mapping(address => uint) public nonces; event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); constructor() public { uint chainId; - assembly { chainId := chainid() } - DOMAIN_SEPARATOR = keccak256(abi.encode( - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), - keccak256(bytes(name)), - keccak256(bytes("1")), - chainId, - address(this) - )); + assembly { + chainId := chainid + } + DOMAIN_SEPARATOR = keccak256( + abi.encode( + keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), + keccak256(bytes(name)), + keccak256(bytes('1')), + chainId, + address(this) + ) + ); } function _mint(address to, uint value) internal { @@ -75,14 +79,16 @@ contract UniswapV2ERC20 is IUniswapV2ERC20 { } function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { - require(deadline >= block.timestamp, "UniswapV2: EXPIRED"); - bytes32 digest = keccak256(abi.encodePacked( - "\x19\x01", - DOMAIN_SEPARATOR, - keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) - )); + require(deadline >= block.timestamp, 'UniswapV2: EXPIRED'); + bytes32 digest = keccak256( + abi.encodePacked( + '\x19\x01', + DOMAIN_SEPARATOR, + keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) + ) + ); address recoveredAddress = ecrecover(digest, v, r, s); - require(recoveredAddress != address(0) && recoveredAddress == owner, "UniswapV2: INVALID_SIGNATURE"); + require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE'); _approve(owner, spender, value); } } diff --git a/contracts/UniswapV2Exchange.sol b/contracts/UniswapV2Exchange.sol index e6899c6..5ba2834 100644 --- a/contracts/UniswapV2Exchange.sol +++ b/contracts/UniswapV2Exchange.sol @@ -1,17 +1,17 @@ pragma solidity =0.5.16; -import "./interfaces/IUniswapV2Exchange.sol"; -import "./UniswapV2ERC20.sol"; -import "./libraries/Math.sol"; -import "./libraries/UQ112x112.sol"; -import "./interfaces/IERC20.sol"; -import "./interfaces/IUniswapV2Factory.sol"; +import './interfaces/IUniswapV2Exchange.sol'; +import './UniswapV2ERC20.sol'; +import './libraries/Math.sol'; +import './libraries/UQ112x112.sol'; +import './interfaces/IERC20.sol'; +import './interfaces/IUniswapV2Factory.sol'; contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 { using SafeMath for uint; using UQ112x112 for uint224; - bytes4 constant public selector = bytes4(keccak256(bytes("transfer(address,uint256)"))); + bytes4 public constant selector = bytes4(keccak256(bytes('transfer(address,uint256)'))); address public factory; address public token0; address public token1; @@ -19,10 +19,10 @@ contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 { uint112 private reserve0; // single storage slot, (jointly) access via getReserves uint112 private reserve1; // single storage slot, (jointly) access via getReserves uint32 private blockTimestampLast; // single storage slot, (jointly) access via getReserves - - uint public price0CumulativeLast; - uint public price1CumulativeLast; - uint public invariantLast; + + uint public price0CumulativeLast; + uint public price1CumulativeLast; + uint public invariantLast; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); @@ -31,7 +31,7 @@ contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 { bool private unlocked = true; modifier lock() { - require(unlocked, "UniswapV2: LOCKED"); + require(unlocked, 'UniswapV2: LOCKED'); unlocked = false; _; unlocked = true; @@ -39,7 +39,7 @@ contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 { function _safeTransfer(address token, address to, uint value) private { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(selector, to, value)); - require(success && (data.length == 0 || abi.decode(data, (bool))), "UniswapV2: TRANSFER_FAILED"); + require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED'); } constructor() public { @@ -47,7 +47,7 @@ contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 { } function initialize(address _token0, address _token1) external { - require(msg.sender == factory && token0 == address(0) && token1 == address(0), "UniswapV2: FORBIDDEN"); + require(msg.sender == factory && token0 == address(0) && token1 == address(0), 'UniswapV2: FORBIDDEN'); token0 = _token0; token1 = _token1; } @@ -60,7 +60,7 @@ contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 { // update reserves and, on the first time this function is called per block, price accumulators function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private { - require(balance0 <= uint112(-1) && balance1 <= uint112(-1), "UniswapV2: BALANCE_OVERFLOW"); + require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: BALANCE_OVERFLOW'); uint32 blockTimestamp = uint32(block.timestamp % 2**32); uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { @@ -94,19 +94,19 @@ contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 { // mint liquidity function mint(address to) external lock returns (uint liquidity) { - uint _totalSupply = totalSupply; // gas savings - uint112 _reserve0 = reserve0; // gas savings - uint112 _reserve1 = reserve1; // gas savings - uint balance0 = IERC20(token0).balanceOf(address(this)); - uint balance1 = IERC20(token1).balanceOf(address(this)); - uint amount0 = balance0.sub(_reserve0); - uint amount1 = balance1.sub(_reserve1); + uint _totalSupply = totalSupply; // gas savings + uint112 _reserve0 = reserve0; // gas savings + uint112 _reserve1 = reserve1; // gas savings + uint balance0 = IERC20(token0).balanceOf(address(this)); + uint balance1 = IERC20(token1).balanceOf(address(this)); + uint amount0 = balance0.sub(_reserve0); + uint amount1 = balance1.sub(_reserve1); bool feeOn = _mintFee(_reserve0, _reserve1); - liquidity = _totalSupply == 0 ? - Math.sqrt(amount0.mul(amount1)) : - Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1); - require(liquidity > 0, "UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED"); + liquidity = _totalSupply == 0 + ? Math.sqrt(amount0.mul(amount1)) + : Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1); + require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED'); _mint(to, liquidity); _update(balance0, balance1, _reserve0, _reserve1); @@ -116,19 +116,19 @@ contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 { // burn liquidity function burn(address to) external lock returns (uint amount0, uint amount1) { - uint _totalSupply = totalSupply; // gas savings - uint112 _reserve0 = reserve0; // gas savings - uint112 _reserve1 = reserve1; // gas savings - address _token0 = token0; // gas savings - address _token1 = token1; // gas savings - uint balance0 = IERC20(_token0).balanceOf(address(this)); - uint balance1 = IERC20(_token1).balanceOf(address(this)); - uint liquidity = balanceOf[address(this)]; + uint _totalSupply = totalSupply; // gas savings + uint112 _reserve0 = reserve0; // gas savings + uint112 _reserve1 = reserve1; // gas savings + address _token0 = token0; // gas savings + address _token1 = token1; // gas savings + uint balance0 = IERC20(_token0).balanceOf(address(this)); + uint balance1 = IERC20(_token1).balanceOf(address(this)); + uint liquidity = balanceOf[address(this)]; bool feeOn = _mintFee(_reserve0, _reserve1); amount0 = liquidity.mul(balance0) / _totalSupply; // use balances instead of reserves to address edge case amount1 = liquidity.mul(balance1) / _totalSupply; // use balances instead of reserves to address edge case - require(amount0 > 0 && amount1 > 0, "UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED"); + require(amount0 > 0 && amount1 > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED'); _burn(address(this), liquidity); _safeTransfer(_token0, to, amount0); _safeTransfer(_token1, to, amount1); @@ -146,23 +146,25 @@ contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 { uint112 _reserve1 = reserve1; // gas savings address _token0 = token0; // gas savings address _token1 = token1; // gas savings - uint balance0; uint balance1; uint amountIn; + uint balance0; + uint balance1; + uint amountIn; if (tokenIn == _token0) { - require(0 < amountOut && amountOut < _reserve1, "UniswapV2: INVALID_OUTPUT_AMOUNT"); + require(0 < amountOut && amountOut < _reserve1, 'UniswapV2: INVALID_OUTPUT_AMOUNT'); balance0 = IERC20(_token0).balanceOf(address(this)); amountIn = balance0.sub(_reserve0); - require(amountIn > 0, "UniswapV2: INSUFFICIENT_INPUT_AMOUNT"); - require(amountIn.mul(_reserve1 - amountOut).mul(997) >= amountOut.mul(_reserve0).mul(1000), "UniswapV2: K"); + require(amountIn > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT'); + require(amountIn.mul(_reserve1 - amountOut).mul(997) >= amountOut.mul(_reserve0).mul(1000), 'UniswapV2: K'); _safeTransfer(_token1, to, amountOut); balance1 = IERC20(_token1).balanceOf(address(this)); } else { - require(tokenIn == _token1, "UniswapV2: INVALID_INPUT_TOKEN"); - require(0 < amountOut && amountOut < _reserve0, "UniswapV2: INVALID_OUTPUT_AMOUNT"); + require(tokenIn == _token1, 'UniswapV2: INVALID_INPUT_TOKEN'); + require(0 < amountOut && amountOut < _reserve0, 'UniswapV2: INVALID_OUTPUT_AMOUNT'); balance1 = IERC20(_token1).balanceOf(address(this)); amountIn = balance1.sub(_reserve1); - require(amountIn > 0, "UniswapV2: INSUFFICIENT_INPUT_AMOUNT"); - require(amountIn.mul(_reserve0 - amountOut).mul(997) >= amountOut.mul(_reserve1).mul(1000), "UniswapV2: K"); + require(amountIn > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT'); + require(amountIn.mul(_reserve0 - amountOut).mul(997) >= amountOut.mul(_reserve1).mul(1000), 'UniswapV2: K'); _safeTransfer(_token0, to, amountOut); balance0 = IERC20(_token0).balanceOf(address(this)); } diff --git a/contracts/UniswapV2Factory.sol b/contracts/UniswapV2Factory.sol index 59dcfb3..204d96e 100644 --- a/contracts/UniswapV2Factory.sol +++ b/contracts/UniswapV2Factory.sol @@ -1,14 +1,14 @@ pragma solidity =0.5.16; -import "./interfaces/IUniswapV2Factory.sol"; -import "./UniswapV2Exchange.sol"; -import "./interfaces/IUniswapV2Exchange.sol"; +import './interfaces/IUniswapV2Factory.sol'; +import './UniswapV2Exchange.sol'; +import './interfaces/IUniswapV2Exchange.sol'; contract UniswapV2Factory is IUniswapV2Factory { address public feeTo; address public feeToSetter; - mapping (address => mapping(address => address)) private _getExchange; + mapping(address => mapping(address => address)) private _getExchange; address[] public exchanges; event ExchangeCreated(address indexed token0, address indexed token1, address exchange, uint); @@ -18,8 +18,8 @@ contract UniswapV2Factory is IUniswapV2Factory { } function sortTokens(address tokenA, address tokenB) public pure returns (address token0, address token1) { - require(tokenA != tokenB, "UniswapV2: SAME_ADDRESS"); - require(tokenA != address(0) && tokenB != address(0), "UniswapV2: ZERO_ADDRESS"); + require(tokenA != tokenB, 'UniswapV2: SAME_ADDRESS'); + require(tokenA != address(0) && tokenB != address(0), 'UniswapV2: ZERO_ADDRESS'); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); } @@ -34,10 +34,12 @@ contract UniswapV2Factory is IUniswapV2Factory { function createExchange(address tokenA, address tokenB) external returns (address exchange) { (address token0, address token1) = sortTokens(tokenA, tokenB); - require(_getExchange[token0][token1] == address(0), "UniswapV2: EXCHANGE_EXISTS"); + require(_getExchange[token0][token1] == address(0), 'UniswapV2: EXCHANGE_EXISTS'); bytes memory exchangeBytecode = type(UniswapV2Exchange).creationCode; bytes32 salt = keccak256(abi.encodePacked(token0, token1)); - assembly { exchange := create2(0, add(exchangeBytecode, 32), mload(exchangeBytecode), salt) } + assembly { + exchange := create2(0, add(exchangeBytecode, 32), mload(exchangeBytecode), salt) + } IUniswapV2Exchange(exchange).initialize(token0, token1); _getExchange[token0][token1] = exchange; exchanges.push(exchange); @@ -45,12 +47,12 @@ contract UniswapV2Factory is IUniswapV2Factory { } function setFeeTo(address _feeTo) external { - require(msg.sender == feeToSetter, "UniswapV2: FORBIDDEN"); + require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); feeTo = _feeTo; } function setFeeToSetter(address _feeToSetter) external { - require(msg.sender == feeToSetter, "UniswapV2: FORBIDDEN"); + require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); feeToSetter = _feeToSetter; } } diff --git a/contracts/libraries/SafeMath.sol b/contracts/libraries/SafeMath.sol index 68c1d9c..f2fbe16 100644 --- a/contracts/libraries/SafeMath.sol +++ b/contracts/libraries/SafeMath.sol @@ -4,14 +4,14 @@ pragma solidity =0.5.16; library SafeMath { function add(uint x, uint y) internal pure returns (uint z) { - require((z = x + y) >= x, "ds-math-add-overflow"); + 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"); + 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"); + require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow'); } } diff --git a/contracts/test/ERC20.sol b/contracts/test/ERC20.sol index ada4d74..74f0777 100644 --- a/contracts/test/ERC20.sol +++ b/contracts/test/ERC20.sol @@ -1,6 +1,6 @@ pragma solidity =0.5.16; -import "../UniswapV2ERC20.sol"; +import '../UniswapV2ERC20.sol'; contract ERC20 is UniswapV2ERC20 { constructor(uint _totalSupply) public {