diff --git a/contracts/UniswapV2Helper.sol.unreviewed b/contracts/UniswapV2Helper.sol.unreviewed deleted file mode 100644 index da8431f..0000000 --- a/contracts/UniswapV2Helper.sol.unreviewed +++ /dev/null @@ -1,131 +0,0 @@ -// TODO ema oracle, review -pragma solidity 0.5.12; - -import "./libraries/Math.sol"; -import "./libraries/SafeMath.sol"; - -import "./UniswapV2Factory.sol"; -import "./UniswapV2.sol"; - -contract UniswapV2Helper { - using SafeMath for uint256; - - event Swap(address inputToken, address outputToken, address indexed buyer, address recipient, uint256 amountSold, uint256 amountBought); - - address factory; // Uniswap ERC20 factory - - constructor(address _factory) public { - factory = _factory; - } - - bool private reentrancyLock = false; - - modifier nonReentrant() { - require(!reentrancyLock, "REENTRANCY_FORBIDDEN"); - reentrancyLock = true; - _; - reentrancyLock = false; - } - - function _send( - address inputToken, - address outputToken, - uint256 amountSold, - address recipient - ) internal returns (uint256) { - address exchange = UniswapV2Factory(factory).getExchange(inputToken, outputToken); - require(exchange != address(0), "NO_EXCHANGE"); - if (amountSold != 0) { - require(IERC20(inputToken).transferFrom(msg.sender, exchange, amountSold), "TRANSFER_FAILED"); - } - return UniswapV2(exchange).swap(inputToken, recipient); - } - - function send( - address inputToken, - address outputToken, - uint256 amountSold, - uint256 minBought, - uint256 deadline, - address recipient - ) public nonReentrant returns (uint256) { - require(block.timestamp <= deadline, "DEADLINE_PASSED"); - uint256 amountBought = _send(inputToken, outputToken, amountSold, recipient); - require(amountBought >= minBought, "INSUFFICIENT_AMOUNT_BOUGHT"); - emit Swap(inputToken, outputToken, msg.sender, recipient, amountSold, amountBought); - return amountBought; - } - - function sendIndirect( - address inputToken, - address intermediateToken, - address outputToken, - uint256 amountSold, - uint256 minBought, - uint256 deadline, - address recipient - ) public nonReentrant returns (uint256) { - require(block.timestamp <= deadline, "DEADLINE_PASSED"); - // send intermediate amount directly to the next contract - uint256 intermediateAmountBought = _send(inputToken, intermediateToken, amountSold, outputToken); - emit Swap(inputToken, intermediateToken, msg.sender, msg.sender, amountSold, intermediateAmountBought); - uint256 amountBought = _send(inputToken, intermediateToken, 0, recipient); - emit Swap(intermediateToken, outputToken, msg.sender, recipient, intermediateAmountBought, amountBought); - require(amountBought >= minBought, "INSUFFICIENT_AMOUNT_BOUGHT"); - return amountBought; - } - - function swap( - address inputToken, - address outputToken, - uint256 amountSold, - uint256 minBought, - uint256 deadline - ) public nonReentrant returns (uint256) { - return send(inputToken, outputToken, amountSold, minBought, deadline, msg.sender); - } - - function _addLiquidity( - address token1, - address token2, - uint256 amount1, - uint256 amount2, - address exchange, - address recipient - ) public nonReentrant returns (uint256) { - require(IERC20(token1).transferFrom(msg.sender, exchange, amount1), "TRANSFER_FAILED"); - require(IERC20(token2).transferFrom(msg.sender, exchange, amount2), "TRANSFER_FAILED"); - return UniswapV2(exchange).addLiquidity(recipient); - } - - function addLiquidity( - address token1, - address token2, - uint256 amount1, - uint256 minBought, - address recipient, - uint256 deadline - ) public nonReentrant returns (uint256) { - require(block.timestamp <= deadline, "DEADLINE_PASSED"); - address exchange = UniswapV2Factory(factory).getExchange(token1, token2); - require(exchange != address(0), "NO_EXCHANGE"); - (uint256 reserve1,) = UniswapV2(exchange).dataForToken(token1); - (uint256 reserve2,) = UniswapV2(exchange).dataForToken(token2); - uint256 amount2 = amount1.mul(reserve2).div(reserve1); - uint256 amountBought = _addLiquidity(token1, token2, amount1, amount2, exchange, recipient); - require(amountBought >= minBought, "INSUFFICIENT_AMOUNT_BOUGHT"); - } - - function removeLiquidity( - address token1, - address token2, - uint256 amount, - address recipient, - uint256 deadline - ) public nonReentrant returns (uint256, uint256) { - require(block.timestamp <= deadline, "DEADLINE_PASSED"); - address exchange = UniswapV2Factory(factory).getExchange(token1, token2); - require(exchange != address(0), "NO_EXCHANGE"); - return UniswapV2(exchange).removeLiquidity(amount, recipient); - } -} diff --git a/contracts/test/Oracle.sol b/contracts/test/Oracle.sol deleted file mode 100644 index 5839c4e..0000000 --- a/contracts/test/Oracle.sol +++ /dev/null @@ -1,164 +0,0 @@ -pragma solidity 0.5.12; - -import "../interfaces/IUniswapV2.sol"; - -import "../libraries/SafeMath256.sol"; - -contract Oracle { - using SafeMath256 for uint256; - - enum OracleStates { NeedsInitialization, NeedsActivation, Active } - - struct TokenData { - uint128 token0; - uint128 token1; - } - - struct TimeData { - uint128 blockNumber; - uint128 blockTimestamp; - } - - address public exchange; - uint128 constant period = 1 days; - - OracleStates private state = OracleStates.NeedsInitialization; - - TokenData private reservesCumulative; - TokenData private reservesCumulativeOverflows; - - TokenData private currentPrice; - - TimeData private updateLast; - - constructor(address _exchange) public { - exchange = _exchange; - } - - function getReservesCumulative() private view returns (TokenData memory, TokenData memory) { - ( - uint128 reservesCumulativeToken0, - uint128 reservesCumulativeToken1, - uint128 reservesCumulativeOverflowsToken0, - uint128 reservesCumulativeOverflowsToken1 - ) = IUniswapV2(exchange).getReservesCumulative(); - return ( - TokenData(reservesCumulativeToken0, reservesCumulativeToken1), - TokenData(reservesCumulativeOverflowsToken0, reservesCumulativeOverflowsToken1) - ); - } - - function getNow() private view returns (TimeData memory) { - return TimeData(block.number.downcast128(), block.timestamp.downcast128()); - } - - function reset() private { - delete(reservesCumulative); - delete(reservesCumulativeOverflows); - delete(currentPrice); - delete(updateLast); - state = OracleStates.NeedsInitialization; - } - - function initialize() external { - require(state == OracleStates.NeedsInitialization, "Oracle: DOES_NOT_NEED_INITIALIZATION"); - - (reservesCumulative, reservesCumulativeOverflows) = getReservesCumulative(); - updateLast = getNow(); - - state = OracleStates.NeedsActivation; - } - - function activate() external { - require(state == OracleStates.NeedsActivation, "Oracle: DOES_NOT_NEED_ACTIVATION"); - - // get the current time, ensure it's been >=1 blocks since the last update - TimeData memory _now = getNow(); - uint128 blocksElapsed = _now.blockNumber - updateLast.blockNumber; - require(blocksElapsed > 0, "Oracle: INSUFFICIENT_BLOCKS_PASSED"); - - // get the current cumulative reserves and overflows - TokenData memory reservesCumulativeNext; - TokenData memory reservesCumulativeOverflowsNext; - (reservesCumulativeNext, reservesCumulativeOverflowsNext) = getReservesCumulative(); - - // reset if there's been an overflow - if ( - reservesCumulativeOverflows.token0 != reservesCumulativeOverflowsNext.token0 || - reservesCumulativeOverflows.token1 != reservesCumulativeOverflowsNext.token1 - ) { - reset(); - require(false, "Oracle: OVERFLOW"); - } - - // calculate the deltas, and record the new values - TokenData memory deltas = TokenData({ - token0: reservesCumulativeNext.token0 - reservesCumulative.token0, - token1: reservesCumulativeNext.token1 - reservesCumulative.token1 - }); - reservesCumulative = reservesCumulativeNext; - - // get the average price over the period and set it to the current price - currentPrice = TokenData({ - token0: deltas.token0 / blocksElapsed, - token1: deltas.token1 / blocksElapsed - }); - - updateLast = _now; - - state = OracleStates.Active; - } - - function update() external { - require(state == OracleStates.Active, "Oracle: INACTIVE"); - - // get the current time, ensure it's been >=1 blocks since the last update - TimeData memory _now = getNow(); - uint128 blocksElapsed = _now.blockNumber - updateLast.blockNumber; - require(blocksElapsed > 0, "Oracle: INSUFFICIENT_BLOCKS_PASSED"); - uint128 timeElapsed = _now.blockTimestamp - updateLast.blockTimestamp; - - // get the current cumulative reserves and overflows - TokenData memory reservesCumulativeNext; - TokenData memory reservesCumulativeOverflowsNext; - (reservesCumulativeNext, reservesCumulativeOverflowsNext) = getReservesCumulative(); - - // reset if there's been an overflow - if ( - reservesCumulativeOverflows.token0 != reservesCumulativeOverflowsNext.token0 || - reservesCumulativeOverflows.token1 != reservesCumulativeOverflowsNext.token1 - ) { - reset(); - require(false, "Oracle: OVERFLOW"); - } - - // calculate the deltas, and record the new values - TokenData memory deltas = TokenData({ - token0: reservesCumulativeNext.token0 - reservesCumulative.token0, - token1: reservesCumulativeNext.token1 - reservesCumulative.token1 - }); - reservesCumulative = reservesCumulativeNext; - - // get the average price over the period - TokenData memory averages = TokenData({ - token0: deltas.token0 / blocksElapsed, - token1: deltas.token1 / blocksElapsed - }); - - // update the current price with this information - if (timeElapsed < period) { - currentPrice = TokenData({ - token0: (currentPrice.token0 * (period - timeElapsed) + averages.token0 * timeElapsed) / period, - token1: (currentPrice.token1 * (period - timeElapsed) + averages.token1 * timeElapsed) / period - }); - } else { - currentPrice = averages; - } - - updateLast = _now; - } - - function getCurrentPrice() external view returns (uint128, uint128) { - return (currentPrice.token0, currentPrice.token1); - } -}