remove extraneous files
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user