Overview
ETH Balance
0.277973903809910325 ETH
Eth Value
$944.37 (@ $3,397.34/ETH)Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 5,964 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Order Disabl... | 12193270 | 1329 days ago | IN | 0 ETH | 0.01010856 | ||||
Set Order Disabl... | 12193269 | 1329 days ago | IN | 0 ETH | 0.01009712 | ||||
Set Order Disabl... | 12193267 | 1329 days ago | IN | 0 ETH | 0.01010856 | ||||
Set Order Disabl... | 12193266 | 1329 days ago | IN | 0 ETH | 0.01009712 | ||||
Set Order Disabl... | 12193264 | 1329 days ago | IN | 0 ETH | 0.01010856 | ||||
Set Order Disabl... | 12193263 | 1329 days ago | IN | 0 ETH | 0.01009712 | ||||
Set Order Disabl... | 12193261 | 1329 days ago | IN | 0 ETH | 0.01010856 | ||||
Set Order Disabl... | 12193259 | 1329 days ago | IN | 0 ETH | 0.01009712 | ||||
Execute | 12193194 | 1329 days ago | IN | 0 ETH | 0.0470163 | ||||
Execute | 12193184 | 1329 days ago | IN | 0 ETH | 0.04517998 | ||||
Withdraw | 12193171 | 1329 days ago | IN | 0.06548717 ETH | 0.03134719 | ||||
Withdraw | 12193165 | 1329 days ago | IN | 0.066591 ETH | 0.03382219 | ||||
Execute | 12193160 | 1329 days ago | IN | 0 ETH | 0.04925569 | ||||
Withdraw | 12193144 | 1329 days ago | IN | 0.066591 ETH | 0.00592327 | ||||
Execute | 12193136 | 1329 days ago | IN | 0 ETH | 0.05600092 | ||||
Withdraw | 12193131 | 1329 days ago | IN | 0.073206 ETH | 0.03833406 | ||||
Withdraw | 12193106 | 1329 days ago | IN | 0.07497 ETH | 0.04151654 | ||||
Execute | 12193093 | 1329 days ago | IN | 0 ETH | 0.0521952 | ||||
Deposit | 12193077 | 1329 days ago | IN | 745.098301 ETH | 0.05711886 | ||||
Execute | 12193009 | 1329 days ago | IN | 0 ETH | 0.04988966 | ||||
Deposit | 12192989 | 1329 days ago | IN | 0.1081311 ETH | 0.06282958 | ||||
Execute | 12192976 | 1329 days ago | IN | 0 ETH | 0.0508067 | ||||
Execute | 12192966 | 1329 days ago | IN | 0 ETH | 0.05547298 | ||||
Withdraw | 12192957 | 1329 days ago | IN | 0.0703395 ETH | 0.03269478 | ||||
Withdraw | 12192939 | 1329 days ago | IN | 0.0708246 ETH | 0.04175393 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
12193194 | 1329 days ago | 0.01375076 ETH | ||||
12193194 | 1329 days ago | 0.04861797 ETH | ||||
12193184 | 1329 days ago | 0.01826943 ETH | ||||
12193184 | 1329 days ago | 0.0440993 ETH | ||||
12193171 | 1329 days ago | 0.00311843 ETH | ||||
12193165 | 1329 days ago | 0.00422226 ETH | ||||
12193160 | 1329 days ago | 0.01193702 ETH | ||||
12193160 | 1329 days ago | 0.04999869 ETH | ||||
12193136 | 1329 days ago | 0.01517882 ETH | ||||
12193136 | 1329 days ago | 0.04675689 ETH | ||||
12193131 | 1329 days ago | 0.01127028 ETH | ||||
12193106 | 1329 days ago | 0.01303428 ETH | ||||
12193093 | 1329 days ago | 0.04645923 ETH | ||||
12193093 | 1329 days ago | 0.04444268 ETH | ||||
12193077 | 1329 days ago | 745 ETH | ||||
12193077 | 1329 days ago | 0.00739908 ETH | ||||
12193009 | 1329 days ago | 0.04301229 ETH | ||||
12193009 | 1329 days ago | 0.04757404 ETH | ||||
12192989 | 1329 days ago | 0.01754476 ETH | ||||
12192976 | 1329 days ago | 0.01533882 ETH | ||||
12192976 | 1329 days ago | 0.04539989 ETH | ||||
12192966 | 1329 days ago | 0.01629316 ETH | ||||
12192966 | 1329 days ago | 0.04444555 ETH | ||||
12192957 | 1329 days ago | 0.00960078 ETH | ||||
12192939 | 1329 days ago | 0.01008588 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
IntegralDelay
Compiler Version
v0.7.5+commit.eb77ed08
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; pragma experimental ABIEncoderV2; import 'IIntegralPair.sol'; import 'IIntegralDelay.sol'; import 'IIntegralOracle.sol'; import 'IWETH.sol'; import 'SafeMath.sol'; import 'Normalizer.sol'; import 'Orders.sol'; import 'TokenShares.sol'; import 'AddLiquidity.sol'; contract IntegralDelay is IIntegralDelay { using SafeMath for uint256; using Normalizer for uint256; using Orders for Orders.Data; using TokenShares for TokenShares.Data; Orders.Data internal orders; TokenShares.Data internal tokenShares; uint256 public constant ORDER_CANCEL_TIME = 24 hours; uint256 private constant ORDER_EXECUTED_COST = 3700; address public override owner; address public override bot; uint256 public override botExecuteTime; constructor( address _factory, address _weth, address _bot ) { orders.factory = _factory; owner = msg.sender; bot = _bot; orders.gasPrice = tx.gasprice - (tx.gasprice % 1e6); tokenShares.setWeth(_weth); orders.delay = 5 minutes; botExecuteTime = 4 * orders.delay; orders.maxGasLimit = 5000000; orders.gasPriceInertia = 20000000; orders.maxGasPriceImpact = 1000000; } function getTransferGasCost(address token) public view override returns (uint256 gasCost) { return orders.transferGasCosts[token]; } function getDepositOrder(uint256 orderId) public view override returns (Orders.DepositOrder memory order) { return orders.getDepositOrder(orderId); } function getWithdrawOrder(uint256 orderId) public view override returns (Orders.WithdrawOrder memory order) { return orders.getWithdrawOrder(orderId); } function getSellOrder(uint256 orderId) public view override returns (Orders.SellOrder memory order) { return orders.getSellOrder(orderId); } function getBuyOrder(uint256 orderId) public view override returns (Orders.BuyOrder memory order) { return orders.getBuyOrder(orderId); } function getDepositDisabled(address pair) public view override returns (bool) { return orders.depositDisabled[pair]; } function getWithdrawDisabled(address pair) public view override returns (bool) { return orders.withdrawDisabled[pair]; } function getBuyDisabled(address pair) public view override returns (bool) { return orders.buyDisabled[pair]; } function getSellDisabled(address pair) public view override returns (bool) { return orders.sellDisabled[pair]; } function getOrderStatus(uint256 orderId) public view override returns (Orders.OrderStatus) { return orders.getOrderStatus(orderId); } uint256 private unlocked = 1; modifier lock() { require(unlocked == 1, 'ID_LOCKED'); unlocked = 0; _; unlocked = 1; } function factory() public view override returns (address) { return orders.factory; } function totalShares(address token) public view override returns (uint256) { return tokenShares.totalShares[token]; } function weth() public view override returns (address) { return tokenShares.weth; } function delay() public view override returns (uint256) { return orders.delay; } function lastProcessedOrderId() public view returns (uint256) { return orders.lastProcessedOrderId; } function newestOrderId() public view returns (uint256) { return orders.newestOrderId; } function getOrder(uint256 orderId) public view returns (Orders.OrderType orderType, uint256 validAfterTimestamp) { return orders.getOrder(orderId); } function isOrderCanceled(uint256 orderId) public view returns (bool) { return orders.canceled[orderId]; } function maxGasLimit() public view override returns (uint256) { return orders.maxGasLimit; } function maxGasPriceImpact() public view override returns (uint256) { return orders.maxGasPriceImpact; } function gasPriceInertia() public view override returns (uint256) { return orders.gasPriceInertia; } function gasPrice() public view override returns (uint256) { return orders.gasPrice; } function setOrderDisabled( address pair, Orders.OrderType orderType, bool disabled ) public override { require(msg.sender == owner, 'ID_FORBIDDEN'); require(orderType != Orders.OrderType.Empty, 'ID_INVALID_ORDER_TYPE'); if (orderType == Orders.OrderType.Deposit) { orders.depositDisabled[pair] = disabled; } else if (orderType == Orders.OrderType.Withdraw) { orders.withdrawDisabled[pair] = disabled; } else if (orderType == Orders.OrderType.Sell) { orders.sellDisabled[pair] = disabled; } else if (orderType == Orders.OrderType.Buy) { orders.buyDisabled[pair] = disabled; } emit OrderDisabled(pair, orderType, disabled); } function setOwner(address _owner) public override { require(msg.sender == owner, 'ID_FORBIDDEN'); owner = _owner; emit OwnerSet(owner); } function setBot(address _bot) public override { require(msg.sender == owner, 'ID_FORBIDDEN'); bot = _bot; emit BotSet(bot); } function setMaxGasLimit(uint256 _maxGasLimit) public override { require(msg.sender == owner, 'ID_FORBIDDEN'); orders.setMaxGasLimit(_maxGasLimit); } function setDelay(uint256 _delay) public override { require(msg.sender == owner, 'ID_FORBIDDEN'); orders.delay = _delay; botExecuteTime = 4 * _delay; emit DelaySet(_delay); } function setGasPriceInertia(uint256 _gasPriceInertia) public override { require(msg.sender == owner, 'ID_FORBIDDEN'); orders.setGasPriceInertia(_gasPriceInertia); } function setMaxGasPriceImpact(uint256 _maxGasPriceImpact) public override { require(msg.sender == owner, 'ID_FORBIDDEN'); orders.setMaxGasPriceImpact(_maxGasPriceImpact); } function setTransferGasCost(address token, uint256 gasCost) public override { require(msg.sender == owner, 'ID_FORBIDDEN'); orders.setTransferGasCost(token, gasCost); } function deposit(Orders.DepositParams calldata depositParams) external payable override lock returns (uint256 orderId) { orders.deposit(depositParams, tokenShares); return orders.newestOrderId; } function withdraw(Orders.WithdrawParams calldata withdrawParams) external payable override lock returns (uint256 orderId) { orders.withdraw(withdrawParams); return orders.newestOrderId; } function sell(Orders.SellParams calldata sellParams) external payable override lock returns (uint256 orderId) { orders.sell(sellParams, tokenShares); return orders.newestOrderId; } function buy(Orders.BuyParams calldata buyParams) external payable override lock returns (uint256 orderId) { orders.buy(buyParams, tokenShares); return orders.newestOrderId; } function execute(uint256 n) public override lock { emit Execute(msg.sender, n); uint256 gasBefore = gasleft(); bool orderExecuted = false; for (uint256 i = 0; i < n; i++) { if (isOrderCanceled(orders.lastProcessedOrderId + 1)) { orders.dequeueCanceledOrder(); continue; } (Orders.OrderType orderType, uint256 validAfterTimestamp) = orders.getNextOrder(); if (orderType == Orders.OrderType.Empty || validAfterTimestamp >= block.timestamp) { break; } require( block.timestamp >= validAfterTimestamp + botExecuteTime || msg.sender == bot || bot == address(0), 'ID_FORBIDDEN' ); orderExecuted = true; if (orderType == Orders.OrderType.Deposit) { executeDeposit(); } else if (orderType == Orders.OrderType.Withdraw) { executeWithdraw(); } else if (orderType == Orders.OrderType.Sell) { executeSell(); } else if (orderType == Orders.OrderType.Buy) { executeBuy(); } } if (orderExecuted) { orders.updateGasPrice(gasBefore.sub(gasleft())); } } function executeDeposit() internal { uint256 gasStart = gasleft(); Orders.DepositOrder memory depositOrder = orders.dequeueDepositOrder(); (, address token0, address token1) = orders.getPairInfo(depositOrder.pairId); (bool executionSuccess, bytes memory data) = address(this).call{ gas: depositOrder.gasLimit.sub( Orders.ORDER_BASE_COST.add(orders.transferGasCosts[token0]).add(orders.transferGasCosts[token1]) ) }(abi.encodeWithSelector(this._executeDeposit.selector, depositOrder)); bool refundSuccess = true; if (!executionSuccess) { refundSuccess = refundTokens( depositOrder.to, token0, depositOrder.share0, token1, depositOrder.share1, depositOrder.unwrap ); } if (!refundSuccess) { orders.markRefundFailed(); } else { orders.forgetLastProcessedOrder(); } (uint256 gasUsed, uint256 ethRefund) = refund( depositOrder.gasLimit, depositOrder.gasPrice, gasStart, depositOrder.to ); emit OrderExecuted(orders.lastProcessedOrderId, executionSuccess, data, gasUsed, ethRefund); } function executeWithdraw() internal { uint256 gasStart = gasleft(); Orders.WithdrawOrder memory withdrawOrder = orders.dequeueWithdrawOrder(); (address pair, , ) = orders.getPairInfo(withdrawOrder.pairId); (bool executionSuccess, bytes memory data) = address(this).call{ gas: withdrawOrder.gasLimit.sub(Orders.ORDER_BASE_COST.add(Orders.PAIR_TRANSFER_COST)) }(abi.encodeWithSelector(this._executeWithdraw.selector, withdrawOrder)); bool refundSuccess = true; if (!executionSuccess) { refundSuccess = refundLiquidity(pair, withdrawOrder.to, withdrawOrder.liquidity); } if (!refundSuccess) { orders.markRefundFailed(); } else { orders.forgetLastProcessedOrder(); } (uint256 gasUsed, uint256 ethRefund) = refund( withdrawOrder.gasLimit, withdrawOrder.gasPrice, gasStart, withdrawOrder.to ); emit OrderExecuted(orders.lastProcessedOrderId, executionSuccess, data, gasUsed, ethRefund); } function executeSell() internal { uint256 gasStart = gasleft(); Orders.SellOrder memory sellOrder = orders.dequeueSellOrder(); (, address token0, address token1) = orders.getPairInfo(sellOrder.pairId); (bool executionSuccess, bytes memory data) = address(this).call{ gas: sellOrder.gasLimit.sub( Orders.ORDER_BASE_COST.add(orders.transferGasCosts[sellOrder.inverse ? token1 : token0]) ) }(abi.encodeWithSelector(this._executeSell.selector, sellOrder)); bool refundSuccess = true; if (!executionSuccess) { refundSuccess = refundToken( sellOrder.inverse ? token1 : token0, sellOrder.to, sellOrder.shareIn, sellOrder.unwrap ); } if (!refundSuccess) { orders.markRefundFailed(); } else { orders.forgetLastProcessedOrder(); } (uint256 gasUsed, uint256 ethRefund) = refund(sellOrder.gasLimit, sellOrder.gasPrice, gasStart, sellOrder.to); emit OrderExecuted(orders.lastProcessedOrderId, executionSuccess, data, gasUsed, ethRefund); } function executeBuy() internal { uint256 gasStart = gasleft(); Orders.BuyOrder memory buyOrder = orders.dequeueBuyOrder(); (, address token0, address token1) = orders.getPairInfo(buyOrder.pairId); (bool executionSuccess, bytes memory data) = address(this).call{ gas: buyOrder.gasLimit.sub( Orders.ORDER_BASE_COST.add(orders.transferGasCosts[buyOrder.inverse ? token1 : token0]) ) }(abi.encodeWithSelector(this._executeBuy.selector, buyOrder)); bool refundSuccess = true; if (!executionSuccess) { refundSuccess = refundToken( buyOrder.inverse ? token1 : token0, buyOrder.to, buyOrder.shareInMax, buyOrder.unwrap ); } if (!refundSuccess) { orders.markRefundFailed(); } else { orders.forgetLastProcessedOrder(); } (uint256 gasUsed, uint256 ethRefund) = refund(buyOrder.gasLimit, buyOrder.gasPrice, gasStart, buyOrder.to); emit OrderExecuted(orders.lastProcessedOrderId, executionSuccess, data, gasUsed, ethRefund); } function refund( uint256 gasLimit, uint256 gasPriceInOrder, uint256 gasStart, address to ) private returns (uint256 gasUsed, uint256 leftOver) { uint256 feeCollected = gasLimit.mul(gasPriceInOrder); gasUsed = gasStart.sub(gasleft()).add(Orders.REFUND_END_COST).add(ORDER_EXECUTED_COST); uint256 actualRefund = Math.min(feeCollected, gasUsed.mul(orders.gasPrice)); leftOver = feeCollected.sub(actualRefund); require(refundEth(msg.sender, actualRefund), 'ID_ETH_REFUND_FAILED'); refundEth(payable(to), leftOver); } function refundEth(address payable to, uint256 value) internal returns (bool success) { if (value == 0) { return true; } success = to.send(value); emit EthRefund(to, success, value); } function refundToken( address token, address to, uint256 share, bool unwrap ) private returns (bool) { if (share == 0) { return true; } (bool success, bytes memory data) = address(this).call{ gas: orders.transferGasCosts[token] }( abi.encodeWithSelector(this._refundToken.selector, token, to, share, unwrap) ); if (!success) { emit RefundFailed(to, token, share, data); } return success; } function refundTokens( address to, address token0, uint256 share0, address token1, uint256 share1, bool unwrap ) private returns (bool) { (bool success, bytes memory data) = address(this).call{ gas: orders.transferGasCosts[token0].add(orders.transferGasCosts[token1]) }(abi.encodeWithSelector(this._refundTokens.selector, to, token0, share0, token1, share1, unwrap)); if (!success) { emit RefundFailed(to, token0, share0, data); emit RefundFailed(to, token1, share1, data); } return success; } function _refundTokens( address to, address token0, uint256 share0, address token1, uint256 share1, bool unwrap ) external { // no need to check sender, because it is checked in _refundToken _refundToken(token0, to, share0, unwrap); _refundToken(token1, to, share1, unwrap); } function _refundToken( address token, address to, uint256 share, bool unwrap ) public { require(msg.sender == address(this), 'ID_FORBIDDEN'); if (token == tokenShares.weth && unwrap) { uint256 amount = tokenShares.sharesToAmount(token, share); IWETH(tokenShares.weth).withdraw(amount); payable(to).transfer(amount); } else { return TransferHelper.safeTransfer(token, to, tokenShares.sharesToAmount(token, share)); } } function refundLiquidity( address pair, address to, uint256 liquidity ) private returns (bool) { if (liquidity == 0) { return true; } (bool success, bytes memory data) = address(this).call{ gas: Orders.PAIR_TRANSFER_COST }( abi.encodeWithSelector(this._refundLiquidity.selector, pair, to, liquidity, false) ); if (!success) { emit RefundFailed(to, pair, liquidity, data); } return success; } function _refundLiquidity( address pair, address to, uint256 liquidity ) public { require(msg.sender == address(this), 'ID_FORBIDDEN'); return TransferHelper.safeTransfer(pair, to, liquidity); } function canSwap( uint256 initialRatio, // setting it to 0 disables swap uint256 minRatioChangeToSwap, uint32 pairId ) internal view returns (bool) { (uint256 reserve0, uint256 reserve1, ) = IIntegralPair(orders.pairs[pairId].pair).getReserves(); if (reserve0 == 0 || reserve1 == 0 || initialRatio == 0) { return false; } uint256 ratio = reserve0.mul(1e18).div(reserve1); // ratioChange(before, after) = MAX(before, after) / MIN(before, after) - 1 uint256 change = Math.max(initialRatio, ratio).mul(1e3).div(Math.min(initialRatio, ratio)).sub(1e3); return change >= minRatioChangeToSwap; } function _executeDeposit(Orders.DepositOrder memory depositOrder) public { require(msg.sender == address(this), 'ID_FORBIDDEN'); require(depositOrder.deadline >= block.timestamp, 'ID_EXPIRED'); (address pair, address token0, address token1, uint256 amount0Left, uint256 amount1Left) = _initialDeposit( depositOrder ); if ( (amount0Left != 0 || amount1Left != 0) && canSwap(depositOrder.initialRatio, depositOrder.minRatioChangeToSwap, depositOrder.pairId) ) { if (amount0Left != 0) { (amount0Left, amount1Left) = AddLiquidity.swapDeposit0( pair, token0, amount0Left, depositOrder.minSwapPrice ); } else if (amount1Left != 0) { (amount0Left, amount1Left) = AddLiquidity.swapDeposit1( pair, token1, amount1Left, depositOrder.maxSwapPrice ); } } if (amount0Left != 0 && amount1Left != 0) { (amount0Left, amount1Left) = _addLiquidityAndMint( pair, depositOrder.to, token0, token1, amount0Left, amount1Left ); } _refundDeposit(depositOrder.to, token0, token1, amount0Left, amount1Left); } function _initialDeposit(Orders.DepositOrder memory depositOrder) private returns ( address pair, address token0, address token1, uint256 amount0Left, uint256 amount1Left ) { (pair, token0, token1) = orders.getPairInfo(depositOrder.pairId); uint256 amount0Desired = tokenShares.sharesToAmount(token0, depositOrder.share0); uint256 amount1Desired = tokenShares.sharesToAmount(token1, depositOrder.share1); IIntegralPair(pair).fullSync(); (amount0Left, amount1Left) = _addLiquidityAndMint( pair, depositOrder.to, token0, token1, amount0Desired, amount1Desired ); } function _addLiquidityAndMint( address pair, address to, address token0, address token1, uint256 amount0Desired, uint256 amount1Desired ) private returns (uint256 amount0Left, uint256 amount1Left) { (uint256 amount0, uint256 amount1) = AddLiquidity.addLiquidity(pair, amount0Desired, amount1Desired); if (amount0 == 0 || amount1 == 0) { return (amount0Desired, amount1Desired); } TransferHelper.safeTransfer(token0, pair, amount0); TransferHelper.safeTransfer(token1, pair, amount1); IIntegralPair(pair).mint(to); amount0Left = amount0Desired.sub(amount0); amount1Left = amount1Desired.sub(amount1); } function _refundDeposit( address to, address token0, address token1, uint256 amount0, uint256 amount1 ) private { if (amount0 > 0) { TransferHelper.safeTransfer(token0, to, amount0); } if (amount1 > 0) { TransferHelper.safeTransfer(token1, to, amount1); } } function _executeWithdraw(Orders.WithdrawOrder memory withdrawOrder) public { require(msg.sender == address(this), 'ID_FORBIDDEN'); require(withdrawOrder.deadline >= block.timestamp, 'ID_EXPIRED'); (address pair, , ) = orders.getPairInfo(withdrawOrder.pairId); IIntegralPair(pair).fullSync(); TransferHelper.safeTransfer(pair, pair, withdrawOrder.liquidity); (uint256 amount0, uint256 amount1) = IIntegralPair(pair).burn(withdrawOrder.to); require(amount0 >= withdrawOrder.amount0Min && amount1 >= withdrawOrder.amount1Min, 'ID_INSUFFICIENT_AMOUNT'); } function _executeBuy(Orders.BuyOrder memory buyOrder) public { require(msg.sender == address(this), 'ID_FORBIDDEN'); require(buyOrder.deadline >= block.timestamp, 'ID_EXPIRED'); (address pairAddress, address token0, address token1) = orders.getPairInfo(buyOrder.pairId); (address tokenIn, address tokenOut) = buyOrder.inverse ? (token1, token0) : (token0, token1); uint256 amountInMax = tokenShares.sharesToAmount(tokenIn, buyOrder.shareInMax); IIntegralPair pair = IIntegralPair(pairAddress); pair.fullSync(); uint256 amountIn = buyOrder.inverse ? pair.getSwapAmount1In(buyOrder.amountOut) : pair.getSwapAmount0In(buyOrder.amountOut); require(amountInMax >= amountIn, 'ID_INSUFFICIENT_INPUT_AMOUNT'); (uint256 amount0Out, uint256 amount1Out) = buyOrder.inverse ? (buyOrder.amountOut, uint256(0)) : (uint256(0), buyOrder.amountOut); TransferHelper.safeTransfer(tokenIn, pairAddress, amountIn); if (tokenOut == tokenShares.weth && buyOrder.unwrap) { pair.swap(amount0Out, amount1Out, address(this)); IWETH(tokenShares.weth).withdraw(buyOrder.amountOut); (bool success, ) = buyOrder.to.call{ value: buyOrder.amountOut, gas: Orders.ETHER_TRANSFER_CALL_COST }(''); if (!success) { tokenShares.onUnwrapFailed(buyOrder.to, buyOrder.amountOut); } } else { pair.swap(amount0Out, amount1Out, buyOrder.to); } } function _executeSell(Orders.SellOrder memory sellOrder) public { require(msg.sender == address(this), 'ID_FORBIDDEN'); require(sellOrder.deadline >= block.timestamp, 'ID_EXPIRED'); (address pairAddress, address token0, address token1) = orders.getPairInfo(sellOrder.pairId); (address tokenIn, address tokenOut) = sellOrder.inverse ? (token1, token0) : (token0, token1); uint256 amountIn = tokenShares.sharesToAmount(tokenIn, sellOrder.shareIn); IIntegralPair pair = IIntegralPair(pairAddress); pair.fullSync(); TransferHelper.safeTransfer(tokenIn, pairAddress, amountIn); uint256 amountOut = sellOrder.inverse ? pair.getSwapAmount0Out(amountIn) : pair.getSwapAmount1Out(amountIn); require(amountOut >= sellOrder.amountOutMin, 'ID_INSUFFICIENT_OUTPUT_AMOUNT'); (uint256 amount0Out, uint256 amount1Out) = sellOrder.inverse ? (amountOut, uint256(0)) : (uint256(0), amountOut); if (tokenOut == tokenShares.weth && sellOrder.unwrap) { pair.swap(amount0Out, amount1Out, address(this)); IWETH(tokenShares.weth).withdraw(amountOut); (bool success, ) = sellOrder.to.call{ value: amountOut, gas: Orders.ETHER_TRANSFER_CALL_COST }(''); if (!success) { tokenShares.onUnwrapFailed(sellOrder.to, amountOut); } } else { pair.swap(amount0Out, amount1Out, sellOrder.to); } } function performRefund( Orders.OrderType orderType, uint256 validAfterTimestamp, uint256 orderId, bool shouldRefundEth ) internal { bool canOwnerRefund = validAfterTimestamp.add(365 days) < block.timestamp; if (orderType == Orders.OrderType.Deposit) { Orders.DepositOrder memory depositOrder = orders.getDepositOrder(orderId); (, address token0, address token1) = orders.getPairInfo(depositOrder.pairId); address to = canOwnerRefund ? owner : depositOrder.to; require( refundTokens(to, token0, depositOrder.share0, token1, depositOrder.share1, depositOrder.unwrap), 'ID_REFUND_FAILED' ); if (shouldRefundEth) { uint256 value = depositOrder.gasPrice.mul(depositOrder.gasLimit); require(refundEth(payable(to), value), 'ID_ETH_REFUND_FAILED'); } } else if (orderType == Orders.OrderType.Withdraw) { Orders.WithdrawOrder memory withdrawOrder = orders.getWithdrawOrder(orderId); (address pair, , ) = orders.getPairInfo(withdrawOrder.pairId); address to = canOwnerRefund ? owner : withdrawOrder.to; require(refundLiquidity(pair, to, withdrawOrder.liquidity), 'ID_REFUND_FAILED'); if (shouldRefundEth) { uint256 value = withdrawOrder.gasPrice.mul(withdrawOrder.gasLimit); require(refundEth(payable(to), value), 'ID_ETH_REFUND_FAILED'); } } else if (orderType == Orders.OrderType.Sell) { Orders.SellOrder memory sellOrder = orders.getSellOrder(orderId); (, address token0, address token1) = orders.getPairInfo(sellOrder.pairId); address to = canOwnerRefund ? owner : sellOrder.to; require( refundToken(sellOrder.inverse ? token1 : token0, to, sellOrder.shareIn, sellOrder.unwrap), 'ID_REFUND_FAILED' ); if (shouldRefundEth) { uint256 value = sellOrder.gasPrice.mul(sellOrder.gasLimit); require(refundEth(payable(to), value), 'ID_ETH_REFUND_FAILED'); } } else if (orderType == Orders.OrderType.Buy) { Orders.BuyOrder memory buyOrder = orders.getBuyOrder(orderId); (, address token0, address token1) = orders.getPairInfo(buyOrder.pairId); address to = canOwnerRefund ? owner : buyOrder.to; require( refundToken(buyOrder.inverse ? token1 : token0, to, buyOrder.shareInMax, buyOrder.unwrap), 'ID_REFUND_FAILED' ); if (shouldRefundEth) { uint256 value = buyOrder.gasPrice.mul(buyOrder.gasLimit); require(refundEth(payable(to), value), 'ID_ETH_REFUND_FAILED'); } } orders.forgetOrder(orderId); } function retryRefund(uint256 orderId) public lock { (Orders.OrderType orderType, uint256 validAfterTimestamp) = orders.getFailedOrderType(orderId); performRefund(orderType, validAfterTimestamp, orderId, false); } function cancelOrder(uint256 orderId) public lock { (Orders.OrderType orderType, uint256 validAfterTimestamp) = orders.getOrder(orderId); require(validAfterTimestamp.sub(delay()).add(ORDER_CANCEL_TIME) < block.timestamp, 'ID_ORDER_NOT_EXCEEDED'); performRefund(orderType, validAfterTimestamp, orderId, true); orders.canceled[orderId] = true; } receive() external payable {} }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); event Transfer(address indexed from, address indexed to, uint256 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 approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; import 'IERC20.sol'; interface IIntegralERC20 is IERC20 { function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint256); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; interface IReserves { event Sync(uint112 reserve0, uint112 reserve1); event Fees(uint256 fee0, uint256 fee1); function getReserves() external view returns ( uint112 reserve0, uint112 reserve1, uint32 lastTimestamp ); function getReferences() external view returns ( uint112 reference0, uint112 reference1, uint32 epoch ); function getFees() external view returns (uint256 fee0, uint256 fee1); }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; import 'IIntegralERC20.sol'; import 'IReserves.sol'; interface IIntegralPair is IIntegralERC20, IReserves { event Mint(address indexed sender, address indexed to); event Burn(address indexed sender, address indexed to); event Swap(address indexed sender, address indexed to); event SetMintFee(uint256 fee); event SetBurnFee(uint256 fee); event SetSwapFee(uint256 fee); event SetOracle(address account); event SetTrader(address trader); event SetToken0AbsoluteLimit(uint256 limit); event SetToken1AbsoluteLimit(uint256 limit); event SetToken0RelativeLimit(uint256 limit); event SetToken1RelativeLimit(uint256 limit); event SetPriceDeviationLimit(uint256 limit); function MINIMUM_LIQUIDITY() external pure returns (uint256); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function oracle() external view returns (address); function trader() external view returns (address); function mintFee() external view returns (uint256); function setMintFee(uint256 fee) external; function mint(address to) external returns (uint256 liquidity); function burnFee() external view returns (uint256); function setBurnFee(uint256 fee) external; function burn(address to) external returns (uint256 amount0, uint256 amount1); function swapFee() external view returns (uint256); function setSwapFee(uint256 fee) external; function setOracle(address account) external; function setTrader(address account) external; function token0AbsoluteLimit() external view returns (uint256); function setToken0AbsoluteLimit(uint256 limit) external; function token1AbsoluteLimit() external view returns (uint256); function setToken1AbsoluteLimit(uint256 limit) external; function token0RelativeLimit() external view returns (uint256); function setToken0RelativeLimit(uint256 limit) external; function token1RelativeLimit() external view returns (uint256); function setToken1RelativeLimit(uint256 limit) external; function priceDeviationLimit() external view returns (uint256); function setPriceDeviationLimit(uint256 limit) external; function collect(address to) external; function swap( uint256 amount0Out, uint256 amount1Out, address to ) external; function sync() external; function initialize( address _token0, address _token1, address _oracle, address _trader ) external; function syncWithOracle() external; function fullSync() external; function getSpotPrice() external view returns (uint256 spotPrice); function getSwapAmount0In(uint256 amount1Out) external view returns (uint256 swapAmount0In); function getSwapAmount1In(uint256 amount0Out) external view returns (uint256 swapAmount1In); function getSwapAmount0Out(uint256 amount1In) external view returns (uint256 swapAmount0Out); function getSwapAmount1Out(uint256 amount0In) external view returns (uint256 swapAmount1Out); function getDepositAmount0In(uint256 amount0) external view returns (uint256 depositAmount0In); function getDepositAmount1In(uint256 amount1) external view returns (uint256 depositAmount1In); }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math) library SafeMath { function add(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x + y) >= x, 'SM_ADD_OVERFLOW'); } function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { z = sub(x, y, 'SM_SUB_UNDERFLOW'); } function sub( uint256 x, uint256 y, string memory message ) internal pure returns (uint256 z) { require((z = x - y) <= x, message); } function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x, 'SM_MUL_OVERFLOW'); } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, 'SM_DIV_BY_ZERO'); uint256 c = a / b; return c; } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; // a library for performing various math operations library Math { function min(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x < y ? x : y; } function max(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x > y ? x : y; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; interface IIntegralFactory { event PairCreated(address indexed token0, address indexed token1, address pair, uint256); event OwnerSet(address owner); function owner() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint256) external view returns (address pair); function allPairsLength() external view returns (uint256); function createPair( address tokenA, address tokenB, address oracle, address trader ) external returns (address pair); function setOwner(address) external; function setMintFee( address tokenA, address tokenB, uint256 fee ) external; function setBurnFee( address tokenA, address tokenB, uint256 fee ) external; function setSwapFee( address tokenA, address tokenB, uint256 fee ) external; function setOracle( address tokenA, address tokenB, address oracle ) external; function setTrader( address tokenA, address tokenB, address trader ) external; function collect( address tokenA, address tokenB, address to ) external; function withdraw( address tokenA, address tokenB, uint256 amount, address to ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity =0.7.5; interface IWETH { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TH_APPROVE_FAILED'); } function safeTransfer( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TH_TRANSFER_FAILED'); } function safeTransferFrom( address token, address from, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TH_TRANSFER_FROM_FAILED'); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{ value: value }(new bytes(0)); require(success, 'TH_ETH_TRANSFER_FAILED'); } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; import 'IERC20.sol'; import 'IWETH.sol'; import 'SafeMath.sol'; import 'TransferHelper.sol'; library TokenShares { using SafeMath for uint256; using TransferHelper for address; event UnwrapFailed(address to, uint256 amount); struct Data { mapping(address => uint256) totalShares; address weth; } function setWeth(Data storage data, address _weth) internal { data.weth = _weth; } function sharesToAmount( Data storage data, address token, uint256 share ) external returns (uint256) { if (share == 0) { return 0; } if (token == data.weth) { return share; } require(data.totalShares[token] >= share, 'TS_INSUFFICIENT_BALANCE'); uint256 balance = IERC20(token).balanceOf(address(this)); uint256 value = balance.mul(share).div(data.totalShares[token]); data.totalShares[token] = data.totalShares[token].sub(share); return value; } function amountToShares( Data storage data, address token, uint256 amount, bool wrap ) external returns (uint256) { if (amount == 0) { return 0; } if (token == data.weth) { if (wrap) { require(msg.value >= amount, 'TS_INSUFFICIENT_AMOUNT'); IWETH(token).deposit{ value: amount }(); } else { token.safeTransferFrom(msg.sender, address(this), amount); } return amount; } else { uint256 balanceBefore = IERC20(token).balanceOf(address(this)); require(balanceBefore > 0 || data.totalShares[token] == 0, 'TS_INVALID_SHARES'); if (data.totalShares[token] == 0) { data.totalShares[token] = balanceBefore; } token.safeTransferFrom(msg.sender, address(this), amount); uint256 balanceAfter = IERC20(token).balanceOf(address(this)); require(balanceAfter > balanceBefore, 'TS_INVALID_TRANSFER'); if (balanceBefore > 0) { uint256 lastShares = data.totalShares[token]; data.totalShares[token] = lastShares.mul(balanceAfter).div(balanceBefore); return data.totalShares[token] - lastShares; } else { data.totalShares[token] = balanceAfter; data.totalShares[token] = balanceAfter; return balanceAfter; } } } function onUnwrapFailed( Data storage data, address to, uint256 amount ) external { emit UnwrapFailed(to, amount); IWETH(data.weth).deposit{ value: amount }(); TransferHelper.safeTransfer(data.weth, to, amount); } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; pragma experimental ABIEncoderV2; import 'SafeMath.sol'; import 'Math.sol'; import 'IIntegralFactory.sol'; import 'IIntegralPair.sol'; import 'TokenShares.sol'; library Orders { using SafeMath for uint256; using TokenShares for TokenShares.Data; using TransferHelper for address; enum OrderType { Empty, Deposit, Withdraw, Sell, Buy } enum OrderStatus { NonExistent, EnqueuedWaiting, EnqueuedReady, ExecutedSucceeded, ExecutedFailed, Canceled } event MaxGasLimitSet(uint256 maxGasLimit); event GasPriceInertiaSet(uint256 gasPriceInertia); event MaxGasPriceImpactSet(uint256 maxGasPriceImpact); event TransferGasCostSet(address token, uint256 gasCost); event DepositEnqueued(uint256 indexed orderId, uint128 validAfterTimestamp, uint256 gasPrice); event WithdrawEnqueued(uint256 indexed orderId, uint128 validAfterTimestamp, uint256 gasPrice); event SellEnqueued(uint256 indexed orderId, uint128 validAfterTimestamp, uint256 gasPrice); event BuyEnqueued(uint256 indexed orderId, uint128 validAfterTimestamp, uint256 gasPrice); uint8 private constant DEPOSIT_TYPE = 1; uint8 private constant WITHDRAW_TYPE = 2; uint8 private constant BUY_TYPE = 3; uint8 private constant BUY_INVERTED_TYPE = 4; uint8 private constant SELL_TYPE = 5; uint8 private constant SELL_INVERTED_TYPE = 6; uint8 private constant UNWRAP_NOT_FAILED = 0; uint8 private constant KEEP_NOT_FAILED = 1; uint8 private constant UNWRAP_FAILED = 2; uint8 private constant KEEP_FAILED = 3; uint256 private constant ETHER_TRANSFER_COST = 2300; uint256 private constant BUFFER_COST = 10000; uint256 private constant EXECUTE_PREPARATION_COST = 55000; // dequeue + getPair in execute uint256 public constant ETHER_TRANSFER_CALL_COST = 10000; uint256 public constant PAIR_TRANSFER_COST = 55000; uint256 public constant REFUND_END_COST = 2 * ETHER_TRANSFER_COST + BUFFER_COST; uint256 public constant ORDER_BASE_COST = EXECUTE_PREPARATION_COST + REFUND_END_COST; uint256 private constant TIMESTAMP_OFFSET = 1609455600; // 2021 Jan 1 struct PairInfo { address pair; address token0; address token1; } struct Data { uint256 delay; uint256 newestOrderId; uint256 lastProcessedOrderId; mapping(uint256 => StoredOrder) orderQueue; address factory; uint256 maxGasLimit; uint256 gasPrice; uint256 gasPriceInertia; uint256 maxGasPriceImpact; mapping(uint32 => PairInfo) pairs; mapping(address => uint256) transferGasCosts; mapping(uint256 => bool) canceled; mapping(address => bool) depositDisabled; mapping(address => bool) withdrawDisabled; mapping(address => bool) buyDisabled; mapping(address => bool) sellDisabled; } struct StoredOrder { // slot 1 uint8 orderType; uint32 validAfterTimestamp; uint8 unwrapAndFailure; uint32 deadline; uint32 gasLimit; uint32 gasPrice; uint112 liquidityOrRatio; // slot 1 uint112 value0; uint112 value1; uint32 pairId; // slot2 address to; uint32 minRatioChangeToSwap; uint32 minSwapPrice; uint32 maxSwapPrice; } struct DepositOrder { uint32 pairId; uint256 share0; uint256 share1; uint256 initialRatio; uint256 minRatioChangeToSwap; uint256 minSwapPrice; uint256 maxSwapPrice; bool unwrap; address to; uint256 gasPrice; uint256 gasLimit; uint256 deadline; } struct WithdrawOrder { uint32 pairId; uint256 liquidity; uint256 amount0Min; uint256 amount1Min; bool unwrap; address to; uint256 gasPrice; uint256 gasLimit; uint256 deadline; } struct SellOrder { uint32 pairId; bool inverse; uint256 shareIn; uint256 amountOutMin; bool unwrap; address to; uint256 gasPrice; uint256 gasLimit; uint256 deadline; } struct BuyOrder { uint32 pairId; bool inverse; uint256 shareInMax; uint256 amountOut; bool unwrap; address to; uint256 gasPrice; uint256 gasLimit; uint256 deadline; } function decodeType(uint256 internalType) internal pure returns (OrderType orderType) { if (internalType == DEPOSIT_TYPE) { orderType = OrderType.Deposit; } else if (internalType == WITHDRAW_TYPE) { orderType = OrderType.Withdraw; } else if (internalType == BUY_TYPE) { orderType = OrderType.Buy; } else if (internalType == BUY_INVERTED_TYPE) { orderType = OrderType.Buy; } else if (internalType == SELL_TYPE) { orderType = OrderType.Sell; } else if (internalType == SELL_INVERTED_TYPE) { orderType = OrderType.Sell; } else { orderType = OrderType.Empty; } } function getOrder(Data storage data, uint256 orderId) public view returns (OrderType orderType, uint256 validAfterTimestamp) { StoredOrder storage order = data.orderQueue[orderId]; uint8 internalType = order.orderType; validAfterTimestamp = uint32ToTimestamp(order.validAfterTimestamp); orderType = decodeType(internalType); } function getOrderStatus(Data storage data, uint256 orderId) external view returns (OrderStatus orderStatus) { if (orderId > data.newestOrderId) { return OrderStatus.NonExistent; } if (data.canceled[orderId]) { return OrderStatus.Canceled; } if (isRefundFailed(data, orderId)) { return OrderStatus.ExecutedFailed; } (OrderType orderType, uint256 validAfterTimestamp) = getOrder(data, orderId); if (orderType == OrderType.Empty) { return OrderStatus.ExecutedSucceeded; } if (validAfterTimestamp >= block.timestamp) { return OrderStatus.EnqueuedWaiting; } return OrderStatus.EnqueuedReady; } function getPair( Data storage data, address tokenA, address tokenB ) internal returns ( address pair, uint32 pairId, bool inverted ) { inverted = tokenA > tokenB; (address token0, address token1) = inverted ? (tokenB, tokenA) : (tokenA, tokenB); pair = IIntegralFactory(data.factory).getPair(token0, token1); pairId = uint32(bytes4(keccak256(abi.encodePacked((pair))))); require(pair != address(0), 'OS_PAIR_NONEXISTENT'); if (data.pairs[pairId].pair == address(0)) { data.pairs[pairId] = PairInfo(pair, token0, token1); } } function getPairInfo(Data storage data, uint32 pairId) external view returns ( address pair, address token0, address token1 ) { PairInfo storage info = data.pairs[pairId]; pair = info.pair; token0 = info.token0; token1 = info.token1; } function getDepositOrder(Data storage data, uint256 index) public view returns (DepositOrder memory order) { StoredOrder memory stored = data.orderQueue[index]; require(stored.orderType == DEPOSIT_TYPE, 'OS_INVALID_ORDER_TYPE'); order.pairId = stored.pairId; order.share0 = stored.value0; order.share1 = stored.value1; order.initialRatio = stored.liquidityOrRatio; order.minRatioChangeToSwap = stored.minRatioChangeToSwap; order.minSwapPrice = float32ToUint(stored.minSwapPrice); order.maxSwapPrice = float32ToUint(stored.maxSwapPrice); order.unwrap = getUnwrap(stored.unwrapAndFailure); order.to = stored.to; order.gasPrice = uint32ToGasPrice(stored.gasPrice); order.gasLimit = stored.gasLimit; order.deadline = uint32ToTimestamp(stored.deadline); } function getWithdrawOrder(Data storage data, uint256 index) public view returns (WithdrawOrder memory order) { StoredOrder memory stored = data.orderQueue[index]; require(stored.orderType == WITHDRAW_TYPE, 'OS_INVALID_ORDER_TYPE'); order.pairId = stored.pairId; order.liquidity = stored.liquidityOrRatio; order.amount0Min = stored.value0; order.amount1Min = stored.value1; order.unwrap = getUnwrap(stored.unwrapAndFailure); order.to = stored.to; order.gasPrice = uint32ToGasPrice(stored.gasPrice); order.gasLimit = stored.gasLimit; order.deadline = uint32ToTimestamp(stored.deadline); } function getSellOrder(Data storage data, uint256 index) public view returns (SellOrder memory order) { StoredOrder memory stored = data.orderQueue[index]; require(stored.orderType == SELL_TYPE || stored.orderType == SELL_INVERTED_TYPE, 'OS_INVALID_ORDER_TYPE'); order.pairId = stored.pairId; order.inverse = stored.orderType == SELL_INVERTED_TYPE; order.shareIn = stored.value0; order.amountOutMin = stored.value1; order.unwrap = getUnwrap(stored.unwrapAndFailure); order.to = stored.to; order.gasPrice = uint32ToGasPrice(stored.gasPrice); order.gasLimit = stored.gasLimit; order.deadline = uint32ToTimestamp(stored.deadline); } function getBuyOrder(Data storage data, uint256 index) public view returns (BuyOrder memory order) { StoredOrder memory stored = data.orderQueue[index]; require(stored.orderType == BUY_TYPE || stored.orderType == BUY_INVERTED_TYPE, 'OS_INVALID_ORDER_TYPE'); order.pairId = stored.pairId; order.inverse = stored.orderType == BUY_INVERTED_TYPE; order.shareInMax = stored.value0; order.amountOut = stored.value1; order.unwrap = getUnwrap(stored.unwrapAndFailure); order.to = stored.to; order.gasPrice = uint32ToGasPrice(stored.gasPrice); order.gasLimit = stored.gasLimit; order.deadline = uint32ToTimestamp(stored.deadline); } function getFailedOrderType(Data storage data, uint256 orderId) external view returns (OrderType orderType, uint256 validAfterTimestamp) { require(isRefundFailed(data, orderId), 'OS_NO_POSSIBLE_REFUND'); (orderType, validAfterTimestamp) = getOrder(data, orderId); } function getUnwrap(uint8 unwrapAndFailure) private pure returns (bool) { return unwrapAndFailure == UNWRAP_FAILED || unwrapAndFailure == UNWRAP_NOT_FAILED; } function getUnwrapAndFailure(bool unwrap) private pure returns (uint8) { return unwrap ? UNWRAP_NOT_FAILED : KEEP_NOT_FAILED; } function timestampToUint32(uint256 timestamp) private pure returns (uint32 timestamp32) { if (timestamp == uint256(-1)) { return uint32(-1); } timestamp32 = uintToUint32(timestamp.sub(TIMESTAMP_OFFSET)); } function uint32ToTimestamp(uint32 timestamp32) private pure returns (uint256 timestamp) { if (timestamp32 == uint32(-1)) { return uint256(-1); } if (timestamp32 == 0) { return 0; } timestamp = uint256(timestamp32) + TIMESTAMP_OFFSET; } function gasPriceToUint32(uint256 gasPrice) private pure returns (uint32 gasPrice32) { require((gasPrice / 1e6) * 1e6 == gasPrice, 'OS_GAS_PRICE_PRECISION'); gasPrice32 = uintToUint32(gasPrice / 1e6); } function uint32ToGasPrice(uint32 gasPrice32) public pure returns (uint256 gasPrice) { gasPrice = uint256(gasPrice32) * 1e6; } function uintToUint32(uint256 number) private pure returns (uint32 number32) { number32 = uint32(number); require(uint256(number32) == number, 'OS_OVERFLOW_32'); } function uintToUint112(uint256 number) private pure returns (uint112 number112) { number112 = uint112(number); require(uint256(number112) == number, 'OS_OVERFLOW_112'); } function uintToFloat32(uint256 number) internal pure returns (uint32 float32) { // Number is encoded on 4 bytes. 3 bytes for mantissa and 1 for exponent. // If the number fits in the mantissa we set the exponent to zero and return. if (number < 2 << 24) { return uint32(number << 8); } // We find the exponent by counting the number of trailing zeroes. // Simultaneously we remove those zeroes from the number. uint32 exponent; for (exponent = 0; exponent < 256 - 24; exponent++) { // Last bit is one. if (number & 1 == 1) { break; } number = number >> 1; } // The number must fit in the mantissa. require(number < 2 << 24, 'OS_OVERFLOW_FLOAT_ENCODE'); // Set the first three bytes to the number and the fourth to the exponent. float32 = uint32(number << 8) | exponent; } function float32ToUint(uint32 float32) internal pure returns (uint256 number) { // Number is encoded on 4 bytes. 3 bytes for mantissa and 1 for exponent. // We get the exponent by extracting the last byte. uint256 exponent = float32 & 0xFF; // Sanity check. Only triggered for values not encoded with uintToFloat32. require(exponent <= 256 - 24, 'OS_OVERFLOW_FLOAT_DECODE'); // We get the mantissa by extracting the first three bytes and removing the fourth. uint256 mantissa = (float32 & 0xFFFFFF00) >> 8; // We add exponent number zeroes after the mantissa. number = mantissa << exponent; } function enqueueDepositOrder(Data storage data, DepositOrder memory depositOrder) internal { data.newestOrderId++; uint128 validAfterTimestamp = uint128(block.timestamp + data.delay); emit DepositEnqueued(data.newestOrderId, validAfterTimestamp, depositOrder.gasPrice); data.orderQueue[data.newestOrderId] = StoredOrder( DEPOSIT_TYPE, timestampToUint32(validAfterTimestamp), getUnwrapAndFailure(depositOrder.unwrap), timestampToUint32(depositOrder.deadline), uintToUint32(depositOrder.gasLimit), gasPriceToUint32(depositOrder.gasPrice), uintToUint112(depositOrder.initialRatio), uintToUint112(depositOrder.share0), uintToUint112(depositOrder.share1), depositOrder.pairId, depositOrder.to, uint32(depositOrder.minRatioChangeToSwap), uintToFloat32(depositOrder.minSwapPrice), uintToFloat32(depositOrder.maxSwapPrice) ); } function enqueueWithdrawOrder(Data storage data, WithdrawOrder memory withdrawOrder) internal { data.newestOrderId++; uint128 validAfterTimestamp = uint128(block.timestamp + data.delay); emit WithdrawEnqueued(data.newestOrderId, validAfterTimestamp, withdrawOrder.gasPrice); data.orderQueue[data.newestOrderId] = StoredOrder( WITHDRAW_TYPE, timestampToUint32(validAfterTimestamp), getUnwrapAndFailure(withdrawOrder.unwrap), timestampToUint32(withdrawOrder.deadline), uintToUint32(withdrawOrder.gasLimit), gasPriceToUint32(withdrawOrder.gasPrice), uintToUint112(withdrawOrder.liquidity), uintToUint112(withdrawOrder.amount0Min), uintToUint112(withdrawOrder.amount1Min), withdrawOrder.pairId, withdrawOrder.to, 0, // maxRatioChange 0, // minSwapPrice 0 // maxSwapPrice ); } function enqueueSellOrder(Data storage data, SellOrder memory sellOrder) internal { data.newestOrderId++; uint128 validAfterTimestamp = uint128(block.timestamp + data.delay); emit SellEnqueued(data.newestOrderId, validAfterTimestamp, sellOrder.gasPrice); data.orderQueue[data.newestOrderId] = StoredOrder( sellOrder.inverse ? SELL_INVERTED_TYPE : SELL_TYPE, timestampToUint32(validAfterTimestamp), getUnwrapAndFailure(sellOrder.unwrap), timestampToUint32(sellOrder.deadline), uintToUint32(sellOrder.gasLimit), gasPriceToUint32(sellOrder.gasPrice), 0, // liquidityOrRatio uintToUint112(sellOrder.shareIn), uintToUint112(sellOrder.amountOutMin), sellOrder.pairId, sellOrder.to, 0, // maxRatioChange 0, // minSwapPrice 0 // maxSwapPrice ); } function enqueueBuyOrder(Data storage data, BuyOrder memory buyOrder) internal { data.newestOrderId++; uint128 validAfterTimestamp = uint128(block.timestamp + data.delay); emit BuyEnqueued(data.newestOrderId, validAfterTimestamp, buyOrder.gasPrice); data.orderQueue[data.newestOrderId] = StoredOrder( buyOrder.inverse ? BUY_INVERTED_TYPE : BUY_TYPE, timestampToUint32(validAfterTimestamp), getUnwrapAndFailure(buyOrder.unwrap), timestampToUint32(buyOrder.deadline), uintToUint32(buyOrder.gasLimit), gasPriceToUint32(buyOrder.gasPrice), 0, // liquidityOrRatio uintToUint112(buyOrder.shareInMax), uintToUint112(buyOrder.amountOut), buyOrder.pairId, buyOrder.to, 0, // maxRatioChange 0, // minSwapPrice 0 // maxSwapPrice ); } function isRefundFailed(Data storage data, uint256 index) internal view returns (bool) { uint8 unwrapAndFailure = data.orderQueue[index].unwrapAndFailure; return unwrapAndFailure == UNWRAP_FAILED || unwrapAndFailure == KEEP_FAILED; } function markRefundFailed(Data storage data) internal { StoredOrder storage stored = data.orderQueue[data.lastProcessedOrderId]; stored.unwrapAndFailure = stored.unwrapAndFailure == UNWRAP_NOT_FAILED ? UNWRAP_FAILED : KEEP_FAILED; } function getNextOrder(Data storage data) internal view returns (OrderType orderType, uint256 validAfterTimestamp) { return getOrder(data, data.lastProcessedOrderId + 1); } function dequeueCanceledOrder(Data storage data) external { data.lastProcessedOrderId++; } function dequeueDepositOrder(Data storage data) external returns (DepositOrder memory order) { data.lastProcessedOrderId++; order = getDepositOrder(data, data.lastProcessedOrderId); } function dequeueWithdrawOrder(Data storage data) external returns (WithdrawOrder memory order) { data.lastProcessedOrderId++; order = getWithdrawOrder(data, data.lastProcessedOrderId); } function dequeueSellOrder(Data storage data) external returns (SellOrder memory order) { data.lastProcessedOrderId++; order = getSellOrder(data, data.lastProcessedOrderId); } function dequeueBuyOrder(Data storage data) external returns (BuyOrder memory order) { data.lastProcessedOrderId++; order = getBuyOrder(data, data.lastProcessedOrderId); } function forgetOrder(Data storage data, uint256 orderId) internal { delete data.orderQueue[orderId]; } function forgetLastProcessedOrder(Data storage data) internal { delete data.orderQueue[data.lastProcessedOrderId]; } struct DepositParams { address token0; address token1; uint256 amount0; uint256 amount1; uint256 initialRatio; uint256 minRatioChangeToSwap; uint256 minSwapPrice; uint256 maxSwapPrice; bool wrap; address to; uint256 gasLimit; uint256 submitDeadline; uint256 executionDeadline; } function deposit( Data storage data, DepositParams calldata depositParams, TokenShares.Data storage tokenShares ) external { require( data.transferGasCosts[depositParams.token0] != 0 && data.transferGasCosts[depositParams.token1] != 0, 'OS_TOKEN_TRANSFER_GAS_COST_UNSET' ); checkOrderParams( data, depositParams.to, depositParams.gasLimit, depositParams.submitDeadline, depositParams.executionDeadline, ORDER_BASE_COST.add(data.transferGasCosts[depositParams.token0]).add( data.transferGasCosts[depositParams.token1] ) ); require(depositParams.amount0 != 0 || depositParams.amount1 != 0, 'OS_NO_AMOUNT'); (address pair, uint32 pairId, bool inverted) = getPair(data, depositParams.token0, depositParams.token1); require(!data.depositDisabled[pair], 'OS_DEPOSIT_DISABLED'); uint256 value = msg.value; // allocate gas refund if (depositParams.token0 == tokenShares.weth && depositParams.wrap) { value = value.sub(depositParams.amount0, 'OS_NOT_ENOUGH_FUNDS'); } else if (depositParams.token1 == tokenShares.weth && depositParams.wrap) { value = value.sub(depositParams.amount1, 'OS_NOT_ENOUGH_FUNDS'); } allocateGasRefund(data, value, depositParams.gasLimit); uint256 shares0 = tokenShares.amountToShares(depositParams.token0, depositParams.amount0, depositParams.wrap); uint256 shares1 = tokenShares.amountToShares(depositParams.token1, depositParams.amount1, depositParams.wrap); IIntegralPair(pair).syncWithOracle(); enqueueDepositOrder( data, DepositOrder( pairId, inverted ? shares1 : shares0, inverted ? shares0 : shares1, depositParams.initialRatio, depositParams.minRatioChangeToSwap, depositParams.minSwapPrice, depositParams.maxSwapPrice, depositParams.wrap, depositParams.to, data.gasPrice, depositParams.gasLimit, depositParams.executionDeadline ) ); } struct WithdrawParams { address token0; address token1; uint256 liquidity; uint256 amount0Min; uint256 amount1Min; bool unwrap; address to; uint256 gasLimit; uint256 submitDeadline; uint256 executionDeadline; } function withdraw(Data storage data, WithdrawParams calldata withdrawParams) external { (address pair, uint32 pairId, bool inverted) = getPair(data, withdrawParams.token0, withdrawParams.token1); require(!data.withdrawDisabled[pair], 'OS_WITHDRAW_DISABLED'); checkOrderParams( data, withdrawParams.to, withdrawParams.gasLimit, withdrawParams.submitDeadline, withdrawParams.executionDeadline, ORDER_BASE_COST.add(PAIR_TRANSFER_COST) ); require(withdrawParams.liquidity != 0, 'OS_NO_LIQUIDITY'); allocateGasRefund(data, msg.value, withdrawParams.gasLimit); pair.safeTransferFrom(msg.sender, address(this), withdrawParams.liquidity); IIntegralPair(pair).syncWithOracle(); enqueueWithdrawOrder( data, WithdrawOrder( pairId, withdrawParams.liquidity, inverted ? withdrawParams.amount1Min : withdrawParams.amount0Min, inverted ? withdrawParams.amount0Min : withdrawParams.amount1Min, withdrawParams.unwrap, withdrawParams.to, data.gasPrice, withdrawParams.gasLimit, withdrawParams.executionDeadline ) ); } struct SellParams { address tokenIn; address tokenOut; uint256 amountIn; uint256 amountOutMin; bool wrapUnwrap; address to; uint256 gasLimit; uint256 submitDeadline; uint256 executionDeadline; } function sell( Data storage data, SellParams calldata sellParams, TokenShares.Data storage tokenShares ) external { require(data.transferGasCosts[sellParams.tokenIn] != 0, 'OS_TOKEN_TRANSFER_GAS_COST_UNSET'); checkOrderParams( data, sellParams.to, sellParams.gasLimit, sellParams.submitDeadline, sellParams.executionDeadline, ORDER_BASE_COST.add(data.transferGasCosts[sellParams.tokenIn]) ); require(sellParams.amountIn != 0, 'OS_NO_AMOUNT_IN'); (address pair, uint32 pairId, bool inverted) = getPair(data, sellParams.tokenIn, sellParams.tokenOut); require(!data.sellDisabled[pair], 'OS_SELL_DISABLED'); uint256 value = msg.value; // allocate gas refund if (sellParams.tokenIn == tokenShares.weth && sellParams.wrapUnwrap) { value = value.sub(sellParams.amountIn, 'OS_NOT_ENOUGH_FUNDS'); } allocateGasRefund(data, value, sellParams.gasLimit); uint256 shares = tokenShares.amountToShares(sellParams.tokenIn, sellParams.amountIn, sellParams.wrapUnwrap); IIntegralPair(pair).syncWithOracle(); enqueueSellOrder( data, SellOrder( pairId, inverted, shares, sellParams.amountOutMin, sellParams.wrapUnwrap, sellParams.to, data.gasPrice, sellParams.gasLimit, sellParams.executionDeadline ) ); } struct BuyParams { address tokenIn; address tokenOut; uint256 amountInMax; uint256 amountOut; bool wrapUnwrap; address to; uint256 gasLimit; uint256 submitDeadline; uint256 executionDeadline; } function buy( Data storage data, BuyParams calldata buyParams, TokenShares.Data storage tokenShares ) external { require(data.transferGasCosts[buyParams.tokenIn] != 0, 'OS_TOKEN_TRANSFER_GAS_COST_UNSET'); checkOrderParams( data, buyParams.to, buyParams.gasLimit, buyParams.submitDeadline, buyParams.executionDeadline, ORDER_BASE_COST.add(data.transferGasCosts[buyParams.tokenIn]) ); require(buyParams.amountOut != 0, 'OS_NO_AMOUNT_OUT'); (address pair, uint32 pairId, bool inverted) = getPair(data, buyParams.tokenIn, buyParams.tokenOut); require(!data.buyDisabled[pair], 'OS_BUY_DISABLED'); uint256 value = msg.value; // allocate gas refund if (buyParams.tokenIn == tokenShares.weth && buyParams.wrapUnwrap) { value = value.sub(buyParams.amountInMax, 'OS_NOT_ENOUGH_FUNDS'); } allocateGasRefund(data, value, buyParams.gasLimit); uint256 shares = tokenShares.amountToShares(buyParams.tokenIn, buyParams.amountInMax, buyParams.wrapUnwrap); IIntegralPair(pair).syncWithOracle(); enqueueBuyOrder( data, BuyOrder( pairId, inverted, shares, buyParams.amountOut, buyParams.wrapUnwrap, buyParams.to, data.gasPrice, buyParams.gasLimit, buyParams.executionDeadline ) ); } function checkOrderParams( Data storage data, address to, uint256 gasLimit, uint256 submitDeadline, uint256 executionDeadline, uint256 minGasLimit ) private view { require(submitDeadline >= block.timestamp, 'OS_EXPIRED'); require(executionDeadline > block.timestamp.add(data.delay), 'OS_INVALID_DEADLINE'); require(gasLimit <= data.maxGasLimit, 'OS_GAS_LIMIT_TOO_HIGH'); require(gasLimit >= minGasLimit, 'OS_GAS_LIMIT_TOO_LOW'); require(to != address(0), 'OS_NO_ADDRESS'); } function allocateGasRefund( Data storage data, uint256 value, uint256 gasLimit ) private returns (uint256 futureFee) { futureFee = data.gasPrice.mul(gasLimit); require(value >= futureFee, 'OS_NOT_ENOUGH_FUNDS'); if (value > futureFee) { msg.sender.transfer(value.sub(futureFee)); } } function updateGasPrice(Data storage data, uint256 gasUsed) external { uint256 scale = Math.min(gasUsed, data.maxGasPriceImpact); uint256 updated = data.gasPrice.mul(data.gasPriceInertia.sub(scale)).add(tx.gasprice.mul(scale)).div( data.gasPriceInertia ); // we lower the precision for gas savings in order queue data.gasPrice = updated - (updated % 1e6); } function setMaxGasLimit(Data storage data, uint256 _maxGasLimit) external { require(_maxGasLimit <= 10000000, 'OS_MAX_GAS_LIMIT_TOO_HIGH'); data.maxGasLimit = _maxGasLimit; emit MaxGasLimitSet(_maxGasLimit); } function setGasPriceInertia(Data storage data, uint256 _gasPriceInertia) external { require(_gasPriceInertia >= 1, 'OS_INVALID_INERTIA'); data.gasPriceInertia = _gasPriceInertia; emit GasPriceInertiaSet(_gasPriceInertia); } function setMaxGasPriceImpact(Data storage data, uint256 _maxGasPriceImpact) external { require(_maxGasPriceImpact <= data.gasPriceInertia, 'OS_INVALID_MAX_GAS_PRICE_IMPACT'); data.maxGasPriceImpact = _maxGasPriceImpact; emit MaxGasPriceImpactSet(_maxGasPriceImpact); } function setTransferGasCost( Data storage data, address token, uint256 gasCost ) external { data.transferGasCosts[token] = gasCost; emit TransferGasCostSet(token, gasCost); } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; pragma experimental ABIEncoderV2; import 'Orders.sol'; interface IIntegralDelay { event OrderExecuted(uint256 indexed id, bool indexed success, bytes data, uint256 gasSpent, uint256 ethRefunded); event RefundFailed(address indexed to, address indexed token, uint256 amount, bytes data); event EthRefund(address indexed to, bool indexed success, uint256 value); event OwnerSet(address owner); event BotSet(address bot); event DelaySet(uint256 delay); event MaxGasLimitSet(uint256 maxGasLimit); event GasPriceInertiaSet(uint256 gasPriceInertia); event MaxGasPriceImpactSet(uint256 maxGasPriceImpact); event TransferGasCostSet(address token, uint256 gasCost); event OrderDisabled(address pair, Orders.OrderType orderType, bool disabled); event UnwrapFailed(address to, uint256 amount); event Execute(address sender, uint256 n); function factory() external returns (address); function owner() external returns (address); function bot() external returns (address); function botExecuteTime() external returns (uint256); function gasPriceInertia() external returns (uint256); function gasPrice() external returns (uint256); function maxGasPriceImpact() external returns (uint256); function maxGasLimit() external returns (uint256); function delay() external returns (uint256); function totalShares(address token) external returns (uint256); function weth() external returns (address); function getTransferGasCost(address token) external returns (uint256); function getDepositOrder(uint256 orderId) external returns (Orders.DepositOrder memory order); function getWithdrawOrder(uint256 orderId) external returns (Orders.WithdrawOrder memory order); function getSellOrder(uint256 orderId) external returns (Orders.SellOrder memory order); function getBuyOrder(uint256 orderId) external returns (Orders.BuyOrder memory order); function getDepositDisabled(address pair) external returns (bool); function getWithdrawDisabled(address pair) external returns (bool); function getBuyDisabled(address pair) external returns (bool); function getSellDisabled(address pair) external returns (bool); function getOrderStatus(uint256 orderId) external returns (Orders.OrderStatus); function setOrderDisabled( address pair, Orders.OrderType orderType, bool disabled ) external; function setOwner(address _owner) external; function setBot(address _bot) external; function setMaxGasLimit(uint256 _maxGasLimit) external; function setDelay(uint256 _delay) external; function setGasPriceInertia(uint256 _gasPriceInertia) external; function setMaxGasPriceImpact(uint256 _maxGasPriceImpact) external; function setTransferGasCost(address token, uint256 gasCost) external; function deposit(Orders.DepositParams memory depositParams) external payable returns (uint256 orderId); function withdraw(Orders.WithdrawParams memory withdrawParams) external payable returns (uint256 orderId); function sell(Orders.SellParams memory sellParams) external payable returns (uint256 orderId); function buy(Orders.BuyParams memory buyParams) external payable returns (uint256 orderId); function execute(uint256 n) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; interface IIntegralOracle { event OwnerSet(address owner); event UniswapPairSet(address uniswapPair); event PriceUpdateIntervalSet(uint32 interval); event ParametersSet(uint32 epoch, int256[] bidExponents, int256[] bidQs, int256[] askExponents, int256[] askQs); function owner() external view returns (address); function setOwner(address) external; function epoch() external view returns (uint32); function xDecimals() external view returns (uint8); function yDecimals() external view returns (uint8); function getParameters() external view returns ( int256[] memory bidExponents, int256[] memory bidQs, int256[] memory askExponents, int256[] memory askQs ); function setParameters( int256[] calldata bidExponents, int256[] calldata bidQs, int256[] calldata askExponents, int256[] calldata askQs ) external; function price() external view returns (int256); function priceUpdateInterval() external view returns (uint32); function updatePrice() external returns (uint32 _epoch); function setPriceUpdateInterval(uint32 interval) external; function price0CumulativeLast() external view returns (uint256); function blockTimestampLast() external view returns (uint32); function tradeX( uint256 xAfter, uint256 xBefore, uint256 yBefore ) external view returns (uint256 yAfter); function tradeY( uint256 yAfter, uint256 xBefore, uint256 yBefore ) external view returns (uint256 xAfter); function getSpotPrice(uint256 xCurrent, uint256 xBefore) external view returns (uint256 spotPrice); }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; import 'SafeMath.sol'; library Normalizer { using SafeMath for uint256; function normalize(uint256 amount, uint8 decimals) internal pure returns (uint256) { if (decimals == 18) { return amount; } else if (decimals > 18) { return amount.div(10**(decimals - 18)); } else { return amount.mul(10**(18 - decimals)); } } function denormalize(uint256 amount, uint8 decimals) internal pure returns (uint256) { if (decimals == 18) { return amount; } else if (decimals > 18) { return amount.mul(10**(decimals - 18)); } else { return amount.div(10**(18 - decimals)); } } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; import 'TransferHelper.sol'; import 'SafeMath.sol'; import 'IIntegralPair.sol'; library AddLiquidity { using SafeMath for uint256; function _quote( uint256 amount0, uint256 reserve0, uint256 reserve1 ) private pure returns (uint256 amountB) { require(amount0 > 0, 'AL_INSUFFICIENT_AMOUNT'); require(reserve0 > 0 && reserve1 > 0, 'AL_INSUFFICIENT_LIQUIDITY'); amountB = amount0.mul(reserve1) / reserve0; } function addLiquidity( address pair, uint256 amount0Desired, uint256 amount1Desired ) external view returns (uint256 amount0, uint256 amount1) { if (amount0Desired == 0 || amount1Desired == 0) { return (0, 0); } (uint256 reserve0, uint256 reserve1, ) = IIntegralPair(pair).getReserves(); if (reserve0 == 0 && reserve1 == 0) { (amount0, amount1) = (amount0Desired, amount1Desired); } else { uint256 amount1Optimal = _quote(amount0Desired, reserve0, reserve1); if (amount1Optimal <= amount1Desired) { (amount0, amount1) = (amount0Desired, amount1Optimal); } else { uint256 amount0Optimal = _quote(amount1Desired, reserve1, reserve0); assert(amount0Optimal <= amount0Desired); (amount0, amount1) = (amount0Optimal, amount1Desired); } } } function swapDeposit0( address pair, address token0, uint256 amount0, uint256 minSwapPrice ) external returns (uint256 amount0Left, uint256 amount1Left) { uint256 amount0In = IIntegralPair(pair).getDepositAmount0In(amount0); amount1Left = IIntegralPair(pair).getSwapAmount1Out(amount0In); if (amount1Left == 0) { return (amount0, amount1Left); } uint256 price = amount1Left.mul(1e18).div(amount0In); require(minSwapPrice == 0 || price >= minSwapPrice, 'AL_PRICE_TOO_LOW'); TransferHelper.safeTransfer(token0, pair, amount0In); IIntegralPair(pair).swap(0, amount1Left, address(this)); amount0Left = amount0.sub(amount0In); } function swapDeposit1( address pair, address token1, uint256 amount1, uint256 maxSwapPrice ) external returns (uint256 amount0Left, uint256 amount1Left) { uint256 amount1In = IIntegralPair(pair).getDepositAmount1In(amount1); amount0Left = IIntegralPair(pair).getSwapAmount0Out(amount1In); if (amount0Left == 0) { return (amount0Left, amount1); } uint256 price = amount1In.mul(1e18).div(amount0Left); require(maxSwapPrice == 0 || price <= maxSwapPrice, 'AL_PRICE_TOO_HIGH'); TransferHelper.safeTransfer(token1, pair, amount1In); IIntegralPair(pair).swap(amount0Left, 0, address(this)); amount1Left = amount1.sub(amount1In); } }
{ "libraries": { "IERC20.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "IIntegralERC20.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "IReserves.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "IIntegralPair.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "SafeMath.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "Math.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "IIntegralFactory.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "IWETH.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "TransferHelper.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "TokenShares.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "Orders.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "IIntegralDelay.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "IIntegralOracle.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "Normalizer.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "AddLiquidity.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" }, "IntegralDelay.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183", "Orders": "0x7218D567b671E36c4e6B3257b8919196CF68ff5E", "AddLiquidity": "0x5a92A3615C547a18BF46b20CfFa10f9c0DB5EA46" } }, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_bot","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"bot","type":"address"}],"name":"BotSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"DelaySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"EthRefund","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"n","type":"uint256"}],"name":"Execute","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"gasPriceInertia","type":"uint256"}],"name":"GasPriceInertiaSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxGasLimit","type":"uint256"}],"name":"MaxGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxGasPriceImpact","type":"uint256"}],"name":"MaxGasPriceImpactSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"enum Orders.OrderType","name":"orderType","type":"uint8"},{"indexed":false,"internalType":"bool","name":"disabled","type":"bool"}],"name":"OrderDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"gasSpent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethRefunded","type":"uint256"}],"name":"OrderExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"OwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"RefundFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasCost","type":"uint256"}],"name":"TransferGasCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UnwrapFailed","type":"event"},{"inputs":[],"name":"ORDER_CANCEL_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"pairId","type":"uint32"},{"internalType":"bool","name":"inverse","type":"bool"},{"internalType":"uint256","name":"shareInMax","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Orders.BuyOrder","name":"buyOrder","type":"tuple"}],"name":"_executeBuy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"pairId","type":"uint32"},{"internalType":"uint256","name":"share0","type":"uint256"},{"internalType":"uint256","name":"share1","type":"uint256"},{"internalType":"uint256","name":"initialRatio","type":"uint256"},{"internalType":"uint256","name":"minRatioChangeToSwap","type":"uint256"},{"internalType":"uint256","name":"minSwapPrice","type":"uint256"},{"internalType":"uint256","name":"maxSwapPrice","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Orders.DepositOrder","name":"depositOrder","type":"tuple"}],"name":"_executeDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"pairId","type":"uint32"},{"internalType":"bool","name":"inverse","type":"bool"},{"internalType":"uint256","name":"shareIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Orders.SellOrder","name":"sellOrder","type":"tuple"}],"name":"_executeSell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"pairId","type":"uint32"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Orders.WithdrawOrder","name":"withdrawOrder","type":"tuple"}],"name":"_executeWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"name":"_refundLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"share","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"}],"name":"_refundToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"uint256","name":"share0","type":"uint256"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint256","name":"share1","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"}],"name":"_refundTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bot","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"botExecuteTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"bool","name":"wrapUnwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"submitDeadline","type":"uint256"},{"internalType":"uint256","name":"executionDeadline","type":"uint256"}],"internalType":"struct Orders.BuyParams","name":"buyParams","type":"tuple"}],"name":"buy","outputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"uint256","name":"initialRatio","type":"uint256"},{"internalType":"uint256","name":"minRatioChangeToSwap","type":"uint256"},{"internalType":"uint256","name":"minSwapPrice","type":"uint256"},{"internalType":"uint256","name":"maxSwapPrice","type":"uint256"},{"internalType":"bool","name":"wrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"submitDeadline","type":"uint256"},{"internalType":"uint256","name":"executionDeadline","type":"uint256"}],"internalType":"struct Orders.DepositParams","name":"depositParams","type":"tuple"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"n","type":"uint256"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasPriceInertia","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"getBuyDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"getBuyOrder","outputs":[{"components":[{"internalType":"uint32","name":"pairId","type":"uint32"},{"internalType":"bool","name":"inverse","type":"bool"},{"internalType":"uint256","name":"shareInMax","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Orders.BuyOrder","name":"order","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"getDepositDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"getDepositOrder","outputs":[{"components":[{"internalType":"uint32","name":"pairId","type":"uint32"},{"internalType":"uint256","name":"share0","type":"uint256"},{"internalType":"uint256","name":"share1","type":"uint256"},{"internalType":"uint256","name":"initialRatio","type":"uint256"},{"internalType":"uint256","name":"minRatioChangeToSwap","type":"uint256"},{"internalType":"uint256","name":"minSwapPrice","type":"uint256"},{"internalType":"uint256","name":"maxSwapPrice","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Orders.DepositOrder","name":"order","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"getOrder","outputs":[{"internalType":"enum Orders.OrderType","name":"orderType","type":"uint8"},{"internalType":"uint256","name":"validAfterTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"getOrderStatus","outputs":[{"internalType":"enum Orders.OrderStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"getSellDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"getSellOrder","outputs":[{"components":[{"internalType":"uint32","name":"pairId","type":"uint32"},{"internalType":"bool","name":"inverse","type":"bool"},{"internalType":"uint256","name":"shareIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Orders.SellOrder","name":"order","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getTransferGasCost","outputs":[{"internalType":"uint256","name":"gasCost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"getWithdrawDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"getWithdrawOrder","outputs":[{"components":[{"internalType":"uint32","name":"pairId","type":"uint32"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct Orders.WithdrawOrder","name":"order","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"isOrderCanceled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastProcessedOrderId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxGasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxGasPriceImpact","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newestOrderId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"retryRefund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"bool","name":"wrapUnwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"submitDeadline","type":"uint256"},{"internalType":"uint256","name":"executionDeadline","type":"uint256"}],"internalType":"struct Orders.SellParams","name":"sellParams","type":"tuple"}],"name":"sell","outputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_bot","type":"address"}],"name":"setBot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasPriceInertia","type":"uint256"}],"name":"setGasPriceInertia","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxGasLimit","type":"uint256"}],"name":"setMaxGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxGasPriceImpact","type":"uint256"}],"name":"setMaxGasPriceImpact","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"enum Orders.OrderType","name":"orderType","type":"uint8"},{"internalType":"bool","name":"disabled","type":"bool"}],"name":"setOrderDisabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"gasCost","type":"uint256"}],"name":"setTransferGasCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"submitDeadline","type":"uint256"},{"internalType":"uint256","name":"executionDeadline","type":"uint256"}],"internalType":"struct Orders.WithdrawParams","name":"withdrawParams","type":"tuple"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405260016015553480156200001657600080fd5b5060405162005b0f38038062005b0f833981016040819052620000399162000104565b600480546001600160a01b038086166001600160a01b031992831617909255601280548216331790556013805492841692909116919091179055620f42403a063a0360065562000097601083620000c2602090811b6200289117901c565b505061012c600055506104b0601455624c4b406005556301312d00600755620f42406008556200014d565b60019190910180546001600160a01b0319166001600160a01b03909216919091179055565b80516001600160a01b0381168114620000ff57600080fd5b919050565b60008060006060848603121562000119578283fd5b6200012484620000e7565b92506200013460208501620000e7565b91506200014460408501620000e7565b90509250925092565b6159b2806200015d6000396000f3fe6080604052600436106102975760003560e01c8063945317131161015a578063d09ef241116100c1578063e5e7988e1161007a578063e5e7988e146107b5578063e6a0cc94146107d5578063f0aa61a3146107ea578063f968bc2a146107ff578063fe0d94c11461081f578063fe173b971461083f5761029e565b8063d09ef241146106ff578063d22e92421461072d578063e085272f1461074d578063e177246e14610760578063e30a499314610780578063e5b1be65146107955761029e565b8063b800522611610113578063b800522614610655578063be5813041461066a578063bf6b874e1461068a578063c35930c3146106aa578063c45a0155146106ca578063c9cd9760146106df5761029e565b806394531713146105955780639718f627146105b5578063af482b58146105d5578063b1af1bda146105f5578063b32ac93614610615578063b3756220146106355761029e565b80634c016016116101fe5780636b5caec4116101b75780636b5caec4146104eb5780636de3c67c1461050b57806377632ec2146105205780637f6a1caf1461054057806381449470146105605780638da5cb5b146105805761029e565b80634c0160161461043f578063514fcac71461045f57806354df6d741461047f57806357a62a4f146104ac5780635e45da23146104c15780636a42b8f8146104d65761029e565b80632da7cbfd116102505780632da7cbfd1461038a578063390ce0d31461039d5780633ed76f17146103ca5780633fc8cef3146103ea57806343133c4b146103ff57806345fa8aae146104125761029e565b806307ddd3bc146102a357806310814c37146102cc57806313af4035146102ee5780631776834a1461031057806317818a5c1461033057806320a68fab1461035d5761029e565b3661029e57005b600080fd5b6102b66102b1366004615025565b610854565b6040516102c3919061557b565b60405180910390f35b3480156102d857600080fd5b506102e16108ff565b6040516102c39190615245565b3480156102fa57600080fd5b5061030e610309366004614b16565b61090e565b005b34801561031c57600080fd5b5061030e61032b366004615072565b610994565b34801561033c57600080fd5b5061035061034b366004615072565b610a2b565b6040516102c39190615819565b34801561036957600080fd5b5061037d610378366004614b16565b610ac6565b6040516102c3919061534c565b6102b6610398366004614eed565b610ae4565b3480156103a957600080fd5b506103bd6103b8366004615072565b610b4a565b6040516102c3919061556c565b3480156103d657600080fd5b5061030e6103e5366004614bbe565b610bdd565b3480156103f657600080fd5b506102e1610bfd565b6102b661040d366004614d6d565b610c0c565b34801561041e57600080fd5b5061043261042d366004615072565b610c72565b6040516102c3919061537c565b34801561044b57600080fd5b5061037d61045a366004614b16565b610cfe565b34801561046b57600080fd5b5061030e61047a366004615072565b610d1c565b34801561048b57600080fd5b5061049f61049a366004615072565b610e40565b6040516102c39190615779565b3480156104b857600080fd5b506102b6610ed3565b3480156104cd57600080fd5b506102b6610ed9565b3480156104e257600080fd5b506102b6610edf565b3480156104f757600080fd5b5061030e610506366004614b16565b610ee5565b34801561051757600080fd5b506102b6610f60565b34801561052c57600080fd5b5061037d61053b366004615072565b610f66565b34801561054c57600080fd5b5061030e61055b366004614c7f565b610f7b565b34801561056c57600080fd5b5061030e61057b366004614d89565b611101565b34801561058c57600080fd5b506102e161130a565b3480156105a157600080fd5b5061030e6105b0366004615072565b611319565b3480156105c157600080fd5b506102b66105d0366004614b16565b61137d565b3480156105e157600080fd5b5061037d6105f0366004614b16565b611398565b34801561060157600080fd5b506103bd610610366004615072565b6113b6565b34801561062157600080fd5b5061030e610630366004615072565b6113f8565b34801561064157600080fd5b5061030e610650366004614eff565b61145c565b34801561066157600080fd5b506102b6611655565b34801561067657600080fd5b5061030e610685366004615072565b61165c565b34801561069657600080fd5b506102b66106a5366004614b16565b61172a565b3480156106b657600080fd5b5061030e6106c5366004614d35565b611745565b3480156106d657600080fd5b506102e1611cd3565b3480156106eb57600080fd5b5061030e6106fa366004614b7e565b611ce2565b34801561070b57600080fd5b5061071f61071a366004615072565b611d11565b6040516102c3929190615390565b34801561073957600080fd5b5061030e610748366004614cbe565b611da7565b6102b661075b366004614d6d565b611e39565b34801561076c57600080fd5b5061030e61077b366004615072565b611e9e565b34801561078c57600080fd5b506102b6611f04565b3480156107a157600080fd5b5061030e6107b0366004614c2d565b611f0a565b3480156107c157600080fd5b5061037d6107d0366004614b16565b612115565b3480156107e157600080fd5b506102b6612133565b3480156107f657600080fd5b506102b6612139565b34801561080b57600080fd5b5061030e61081a366004614d35565b61213f565b34801561082b57600080fd5b5061030e61083a366004615072565b61260b565b34801561084b57600080fd5b506102b661288b565b60006015546001146108815760405162461bcd60e51b8152600401610878906153ab565b60405180910390fd5b60006015819055604051636587992160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e916365879921916108c0919086906004016156a9565b60006040518083038186803b1580156108d857600080fd5b505af41580156108ec573d6000803e3d6000fd5b5050600154925050506001601555919050565b6013546001600160a01b031681565b6012546001600160a01b031633146109385760405162461bcd60e51b8152600401610878906154b1565b601280546001600160a01b0319166001600160a01b0383811691909117918290556040517f50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe292610989921690615245565b60405180910390a150565b6012546001600160a01b031633146109be5760405162461bcd60e51b8152600401610878906154b1565b604051636702eca360e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e90636702eca3906109f8906000908590600401615757565b60006040518083038186803b158015610a1057600080fd5b505af4158015610a24573d6000803e3d6000fd5b5050505050565b610a33614849565b604051634ce4436960e11b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906399c886d290610a6d906000908690600401615757565b6101206040518083038186803b158015610a8657600080fd5b505af4158015610a9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614f92565b90505b919050565b6001600160a01b03166000908152600d602052604090205460ff1690565b6000601554600114610b085760405162461bcd60e51b8152600401610878906153ab565b60006015819055604051638f0e6bef60e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e91638f0e6bef916108c0919086906010906004016155c7565b610b526148a6565b60405163ac1ecdb360e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063ac1ecdb390610b8c906000908690600401615757565b6101206040518083038186803b158015610ba557600080fd5b505af4158015610bb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614d51565b610be985878684611f0a565b610bf583878484611f0a565b505050505050565b6011546001600160a01b031690565b6000601554600114610c305760405162461bcd60e51b8152600401610878906153ab565b6000601581905560405163758e99b360e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9163758e99b3916108c0919086906010906004016155a3565b604051634dc1ffe760e11b8152600090737218d567b671e36c4e6b3257b8919196cf68ff5e90639b83ffce90610cae9084908690600401615757565b60206040518083038186803b158015610cc657600080fd5b505af4158015610cda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614ce9565b6001600160a01b03166000908152600f602052604090205460ff1690565b601554600114610d3e5760405162461bcd60e51b8152600401610878906153ab565b6000601581905560405163317e626f60e21b81528190737218d567b671e36c4e6b3257b8919196cf68ff5e9063c5f989bc90610d809084908790600401615757565b604080518083038186803b158015610d9757600080fd5b505af4158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190614d08565b9150915042610df362015180610ded610de6610edf565b85906128b6565b906128f2565b10610e105760405162461bcd60e51b815260040161087890615405565b610e1d8282856001612942565b50506000908152600b60205260409020805460ff19166001908117909155601555565b610e48614905565b60405163117d7ab160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063117d7ab190610e82906000908690600401615757565b6101806040518083038186803b158015610e9b57600080fd5b505af4158015610eaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614e3b565b60085490565b60055490565b60005490565b6012546001600160a01b03163314610f0f5760405162461bcd60e51b8152600401610878906154b1565b601380546001600160a01b0319166001600160a01b0383811691909117918290556040517f2dd8c90b4846f9ecba5790aa82e17144ea4201912f3abc8c51fd7320b527134092610989921690615245565b60075490565b6000908152600b602052604090205460ff1690565b6012546001600160a01b03163314610fa55760405162461bcd60e51b8152600401610878906154b1565b6000826004811115610fb357fe5b1415610fd15760405162461bcd60e51b815260040161087890615434565b6001826004811115610fdf57fe5b141561100e576001600160a01b0383166000908152600c60205260409020805460ff19168215151790556110c1565b600282600481111561101c57fe5b141561104b576001600160a01b0383166000908152600d60205260409020805460ff19168215151790556110c1565b600382600481111561105957fe5b1415611088576001600160a01b0383166000908152600f60205260409020805460ff19168215151790556110c1565b600482600481111561109657fe5b14156110c1576001600160a01b0383166000908152600e60205260409020805460ff19168215151790555b7f3d5726ff7c14d1fb7a71ac46100040a8b7a9edb7624e96b8abde4a15649fdf498383836040516110f4939291906152fe565b60405180910390a1505050565b3330146111205760405162461bcd60e51b8152600401610878906154b1565b4281610160015110156111455760405162461bcd60e51b815260040161087890615463565b6000806000806000611156866130c5565b9450945094509450945081600014158061116f57508015155b801561118d575061118d866060015187608001518860000151613303565b156112cc5781156112315760a0860151604051634f57f14d60e11b8152735a92a3615c547a18bf46b20cffa10f9c0db5ea4691639eafe29a916111d8918991899188916004016152d5565b604080518083038186803b1580156111ef57600080fd5b505af4158015611203573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122791906150a2565b90925090506112cc565b80156112cc5760c086015160405163aceb17df60e01b8152735a92a3615c547a18bf46b20cffa10f9c0db5ea469163aceb17df91611277918991889187916004016152d5565b604080518083038186803b15801561128e57600080fd5b505af41580156112a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c691906150a2565b90925090505b81158015906112da57508015155b156112f8576112f28587610100015186868686613431565b90925090505b610bf58661010001518585858561359f565b6012546001600160a01b031681565b6012546001600160a01b031633146113435760405162461bcd60e51b8152600401610878906154b1565b604051630fd1437d60e11b8152737218d567b671e36c4e6b3257b8919196cf68ff5e90631fa286fa906109f8906000908590600401615757565b6001600160a01b03166000908152600a602052604090205490565b6001600160a01b03166000908152600c602052604090205460ff1690565b6113be6148a6565b6040516311c8197f60e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906311c8197f90610b8c906000908690600401615757565b6012546001600160a01b031633146114225760405162461bcd60e51b8152600401610878906154b1565b60405163153cc2fd60e31b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063a9e617e8906109f8906000908590600401615757565b33301461147b5760405162461bcd60e51b8152600401610878906154b1565b4281610100015110156114a05760405162461bcd60e51b815260040161087890615463565b8051604051630270f5c360e51b8152600091737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb860916114dd91859190600401615765565b60606040518083038186803b1580156114f557600080fd5b505af4158015611509573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152d9190614b32565b50509050806001600160a01b031663caeba2176040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561156c57600080fd5b505af1158015611580573d6000803e3d6000fd5b50505050611593818284602001516135bd565b600080826001600160a01b03166389afcb448560a001516040518263ffffffff1660e01b81526004016115c69190615245565b6040805180830381600087803b1580156115df57600080fd5b505af11580156115f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161791906150a2565b9150915083604001518210158015611633575083606001518110155b61164f5760405162461bcd60e51b8152600401610878906154d7565b50505050565b6201518081565b60155460011461167e5760405162461bcd60e51b8152600401610878906153ab565b60006015819055604051631ae4f06f60e01b81528190737218d567b671e36c4e6b3257b8919196cf68ff5e90631ae4f06f906116c09084908790600401615757565b604080518083038186803b1580156116d757600080fd5b505af41580156116eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170f9190614d08565b915091506117208282856000612942565b5050600160155550565b6001600160a01b031660009081526010602052604090205490565b3330146117645760405162461bcd60e51b8152600401610878906154b1565b4281610100015110156117895760405162461bcd60e51b815260040161087890615463565b8051604051630270f5c360e51b815260009182918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb860916117ca91859190600401615765565b60606040518083038186803b1580156117e257600080fd5b505af41580156117f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181a9190614b32565b9250925092506000808560200151611833578383611836565b82845b915091506000601073c82938b53e0e190459ba4e3502bf26f194760183636c5d9cf09091858a604001516040518463ffffffff1660e01b815260040161187e93929190615584565b60206040518083038186803b15801561189657600080fd5b505af41580156118aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ce919061508a565b90506000869050806001600160a01b031663caeba2176040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561191057600080fd5b505af1158015611924573d6000803e3d6000fd5b50505050600088602001516119b8576060890151604051631b8109cf60e31b81526001600160a01b0384169163dc084e7891611963919060040161557b565b60206040518083038186803b15801561197b57600080fd5b505afa15801561198f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b3919061508a565b611a38565b6060890151604051631782077d60e31b81526001600160a01b0384169163bc103be8916119e8919060040161557b565b60206040518083038186803b158015611a0057600080fd5b505afa158015611a14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a38919061508a565b905080831015611a5a5760405162461bcd60e51b815260040161087890615535565b6000808a60200151611a725760008b60600151611a7a565b8a6060015160005b91509150611a89878b856135bd565b6011546001600160a01b038781169116148015611aa757508a608001515b15611c5f576040516336cd320560e11b81526001600160a01b03851690636d9a640a90611adc908590859030906004016158a8565b600060405180830381600087803b158015611af657600080fd5b505af1158015611b0a573d6000803e3d6000fd5b505060115460608e0151604051632e1a7d4d60e01b81526001600160a01b039092169350632e1a7d4d9250611b419160040161557b565b600060405180830381600087803b158015611b5b57600080fd5b505af1158015611b6f573d6000803e3d6000fd5b5050505060008b60a001516001600160a01b03168c6060015161271090604051611b9890615242565b600060405180830381858888f193505050503d8060008114611bd6576040519150601f19603f3d011682016040523d82523d6000602084013e611bdb565b606091505b5050905080611c595760a08c015160608d015160405163032b310f60e51b815273c82938b53e0e190459ba4e3502bf26f1947601839263656621e092611c28926010929190600401615584565b60006040518083038186803b158015611c4057600080fd5b505af4158015611c54573d6000803e3d6000fd5b505050505b50611cc6565b60a08b01516040516336cd320560e11b81526001600160a01b03861691636d9a640a91611c939186918691906004016158a8565b600060405180830381600087803b158015611cad57600080fd5b505af1158015611cc1573d6000803e3d6000fd5b505050505b5050505050505050505050565b6004546001600160a01b031690565b333014611d015760405162461bcd60e51b8152600401610878906154b1565b611d0c8383836135bd565b505050565b60405163317e626f60e21b81526000908190737218d567b671e36c4e6b3257b8919196cf68ff5e9063c5f989bc90611d4f9084908790600401615757565b604080518083038186803b158015611d6657600080fd5b505af4158015611d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9e9190614d08565b91509150915091565b6012546001600160a01b03163314611dd15760405162461bcd60e51b8152600401610878906154b1565b60405163b2456a0760e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063b2456a0790611e0d9060009086908690600401615584565b60006040518083038186803b158015611e2557600080fd5b505af4158015610bf5573d6000803e3d6000fd5b6000601554600114611e5d5760405162461bcd60e51b8152600401610878906153ab565b6000601581905560405162c44ff160e31b8152737218d567b671e36c4e6b3257b8919196cf68ff5e916306227f88916108c0919086906010906004016155a3565b6012546001600160a01b03163314611ec85760405162461bcd60e51b8152600401610878906154b1565b6000819055600481026014556040517f63e09f16584208fba1fc7ff64c62b00f07bec177c0d97ca6689891b1e77a35c79061098990839061557b565b60015490565b333014611f295760405162461bcd60e51b8152600401610878906154b1565b6011546001600160a01b038581169116148015611f435750805b15612077576040516306c5d9cf60e41b815260009073c82938b53e0e190459ba4e3502bf26f19476018390636c5d9cf090611f879060109089908890600401615584565b60206040518083038186803b158015611f9f57600080fd5b505af4158015611fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd7919061508a565b601154604051632e1a7d4d60e01b81529192506001600160a01b031690632e1a7d4d9061200890849060040161557b565b600060405180830381600087803b15801561202257600080fd5b505af1158015612036573d6000803e3d6000fd5b50506040516001600160a01b038716925083156108fc02915083906000818181858888f19350505050158015612070573d6000803e3d6000fd5b505061164f565b6040516306c5d9cf60e41b8152612110908590859073c82938b53e0e190459ba4e3502bf26f19476018390636c5d9cf0906120bb9060109086908a90600401615584565b60206040518083038186803b1580156120d357600080fd5b505af41580156120e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210b919061508a565b6135bd565b61164f565b6001600160a01b03166000908152600e602052604090205460ff1690565b60025490565b60145481565b33301461215e5760405162461bcd60e51b8152600401610878906154b1565b4281610100015110156121835760405162461bcd60e51b815260040161087890615463565b8051604051630270f5c360e51b815260009182918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb860916121c491859190600401615765565b60606040518083038186803b1580156121dc57600080fd5b505af41580156121f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122149190614b32565b925092509250600080856020015161222d578383612230565b82845b915091506000601073c82938b53e0e190459ba4e3502bf26f194760183636c5d9cf09091858a604001516040518463ffffffff1660e01b815260040161227893929190615584565b60206040518083038186803b15801561229057600080fd5b505af41580156122a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c8919061508a565b90506000869050806001600160a01b031663caeba2176040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561230a57600080fd5b505af115801561231e573d6000803e3d6000fd5b5050505061232d8488846135bd565b600088602001516123b9576040516357db007f60e11b81526001600160a01b0383169063afb600fe9061236490869060040161557b565b60206040518083038186803b15801561237c57600080fd5b505afa158015612390573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b4919061508a565b612435565b604051632e34fcc760e21b81526001600160a01b0383169063b8d3f31c906123e590869060040161557b565b60206040518083038186803b1580156123fd57600080fd5b505afa158015612411573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612435919061508a565b9050886060015181101561245b5760405162461bcd60e51b8152600401610878906153ce565b6000808a6020015161246f57600083612473565b8260005b60115491935091506001600160a01b03878116911614801561249657508a608001515b15611c5f576040516336cd320560e11b81526001600160a01b03851690636d9a640a906124cb908590859030906004016158a8565b600060405180830381600087803b1580156124e557600080fd5b505af11580156124f9573d6000803e3d6000fd5b5050601154604051632e1a7d4d60e01b81526001600160a01b039091169250632e1a7d4d915061252d90869060040161557b565b600060405180830381600087803b15801561254757600080fd5b505af115801561255b573d6000803e3d6000fd5b5050505060008b60a001516001600160a01b0316846127109060405161258090615242565b600060405180830381858888f193505050503d80600081146125be576040519150601f19603f3d011682016040523d82523d6000602084013e6125c3565b606091505b5050905080611c595760a08c015160405163032b310f60e51b815273c82938b53e0e190459ba4e3502bf26f1947601839163656621e091611c28916010918990600401615584565b60155460011461262d5760405162461bcd60e51b8152600401610878906153ab565b60006015556040517f892cd8f5b436bd5fb7dac1f11aafb73345d892ba3e9fe09cd94d95ba84928e73906126649033908490615259565b60405180910390a160005a90506000805b838110156128065760025461268c90600101610f66565b156126fe576040516305d4bd1160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906305d4bd11906126c99060009060040161557b565b60006040518083038186803b1580156126e157600080fd5b505af41580156126f5573d6000803e3d6000fd5b505050506127fe565b60008061270b6000613715565b9092509050600082600481111561271e57fe5b148061272a5750428110155b15612736575050612806565b60145481014210158061275357506013546001600160a01b031633145b8061276757506013546001600160a01b0316155b6127835760405162461bcd60e51b8152600401610878906154b1565b600193508382600481111561279457fe5b14156127a7576127a2613729565b6127fb565b60028260048111156127b557fe5b14156127c3576127a26139fe565b60038260048111156127d157fe5b14156127df576127a2613c94565b60048260048111156127ed57fe5b14156127fb576127fb613f28565b50505b600101612675565b50801561172057737218d567b671e36c4e6b3257b8919196cf68ff5e639db74df160006128345a86906128b6565b6040518363ffffffff1660e01b8152600401612851929190615757565b60006040518083038186803b15801561286957600080fd5b505af415801561287d573d6000803e3d6000fd5b505050505050600160155550565b60065490565b60019190910180546001600160a01b0319166001600160a01b03909216919091179055565b60006128eb83836040518060400160405280601081526020016f534d5f5355425f554e444552464c4f5760801b815250614099565b9392505050565b8082018281101561293c576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4144445f4f564552464c4f5760881b604482015290519081900360640190fd5b92915050565b600042612953856301e133806128f2565b109050600185600481111561296457fe5b1415612b4357612972614905565b60405163117d7ab160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063117d7ab1906129ac906000908890600401615757565b6101806040518083038186803b1580156129c557600080fd5b505af41580156129d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129fd9190614e3b565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091612a3f91859190600401615765565b60606040518083038186803b158015612a5757600080fd5b505af4158015612a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8f9190614b32565b9250925050600084612aa657836101000151612ab3565b6012546001600160a01b03165b9050612acf818486602001518588604001518960e00151614131565b612aeb5760405162461bcd60e51b815260040161087890615487565b8515612b3a576000612b1085610140015186610120015161429890919063ffffffff16565b9050612b1c82826142f6565b612b385760405162461bcd60e51b815260040161087890615507565b505b505050506130ba565b6002856004811115612b5157fe5b1415612d1b57612b5f614849565b604051634ce4436960e11b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906399c886d290612b99906000908890600401615757565b6101206040518083038186803b158015612bb257600080fd5b505af4158015612bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bea9190614f92565b8051604051630270f5c360e51b8152919250600091737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091612c29918591600401615765565b60606040518083038186803b158015612c4157600080fd5b505af4158015612c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c799190614b32565b50509050600083612c8e578260a00151612c9b565b6012546001600160a01b03165b9050612cac82828560200151614376565b612cc85760405162461bcd60e51b815260040161087890615487565b8415612d13576000612ceb8460e001518560c0015161429890919063ffffffff16565b9050612cf782826142f6565b612b3a5760405162461bcd60e51b815260040161087890615507565b5050506130ba565b6003856004811115612d2957fe5b1415612edc57612d376148a6565b60405163ac1ecdb360e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063ac1ecdb390612d71906000908890600401615757565b6101206040518083038186803b158015612d8a57600080fd5b505af4158015612d9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dc29190614d51565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091612e0491859190600401615765565b60606040518083038186803b158015612e1c57600080fd5b505af4158015612e30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e549190614b32565b9250925050600084612e6a578360a00151612e77565b6012546001600160a01b03165b9050612e9d8460200151612e8b5783612e8d565b825b8286604001518760800151614486565b612eb95760405162461bcd60e51b815260040161087890615487565b8515612b3a576000612b108560e001518660c0015161429890919063ffffffff16565b6004856004811115612eea57fe5b14156130ba57612ef86148a6565b6040516311c8197f60e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906311c8197f90612f32906000908890600401615757565b6101206040518083038186803b158015612f4b57600080fd5b505af4158015612f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f839190614d51565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091612fc591859190600401615765565b60606040518083038186803b158015612fdd57600080fd5b505af4158015612ff1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130159190614b32565b925092505060008461302b578360a00151613038565b6012546001600160a01b03165b905061304c8460200151612e8b5783612e8d565b6130685760405162461bcd60e51b815260040161087890615487565b85156130b557600061308b8560e001518660c0015161429890919063ffffffff16565b905061309782826142f6565b6130b35760405162461bcd60e51b815260040161087890615507565b505b505050505b610a246000846145a6565b8051604051630270f5c360e51b81526000918291829182918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb8609161310a91859190600401615765565b60606040518083038186803b15801561312257600080fd5b505af4158015613136573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061315a9190614b32565b60208901516040516306c5d9cf60e41b8152939850919650945060009173c82938b53e0e190459ba4e3502bf26f19476018391636c5d9cf0916131a5916010918a9190600401615584565b60206040518083038186803b1580156131bd57600080fd5b505af41580156131d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f5919061508a565b60408089015190516306c5d9cf60e41b815291925060009173c82938b53e0e190459ba4e3502bf26f19476018391636c5d9cf09161323b916010918a9190600401615584565b60206040518083038186803b15801561325357600080fd5b505af4158015613267573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061328b919061508a565b9050866001600160a01b031663caeba2176040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156132c857600080fd5b505af11580156132dc573d6000803e3d6000fd5b505050506132f38789610100015188888686613431565b9799969850949694959350505050565b63ffffffff8116600090815260096020526040808220548151630240bc6b60e21b81529151839283926001600160a01b031691630902f1ac91600480820192606092909190829003018186803b15801561335c57600080fd5b505afa158015613370573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133949190615037565b506001600160701b031691506001600160701b0316915081600014806133b8575080155b806133c1575085155b156133d1576000925050506128eb565b60006133ef826133e985670de0b6b3a7640000614298565b906145c7565b905060006134226103e861341c6134068b86614622565b6133e96103e86134168e89614638565b90614298565b906128b6565b90961115979650505050505050565b600080600080735a92a3615c547a18bf46b20cffa10f9c0db5ea466355776b778b88886040518463ffffffff1660e01b81526004016134729392919061532b565b604080518083038186803b15801561348957600080fd5b505af415801561349d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c191906150a2565b9150915081600014806134d2575080155b156134e4578585935093505050613594565b6134ef888b846135bd565b6134fa878b836135bd565b6040516335313c2160e11b81526001600160a01b038b1690636a62784290613526908c90600401615245565b602060405180830381600087803b15801561354057600080fd5b505af1158015613554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613578919061508a565b5061358386836128b6565b935061358f85826128b6565b925050505b965096945050505050565b81156135b0576135b08486846135bd565b8015610a2457610a248386835b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b6020831061363a5780518252601f19909201916020918201910161361b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461369c576040519150601f19603f3d011682016040523d82523d6000602084013e6136a1565b606091505b50915091508180156136cf5750805115806136cf57508080602001905160208110156136cc57600080fd5b50515b610a24576040805162461bcd60e51b8152602060048201526012602482015271151217d514905394d1915497d1905253115160721b604482015290519081900360640190fd5b600080611d9e838460020154600101614647565b60005a9050613736614905565b60405163a81df10f60e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063a81df10f9061376e9060009060040161557b565b6101806040518083038186803b15801561378757600080fd5b505af415801561379b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bf9190614e3b565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb8609161380191859190600401615765565b60606040518083038186803b15801561381957600080fd5b505af415801561382d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138519190614b32565b6001600160a01b038082166000908152600a602052604080822054928516825281205493965091945090925060609130916138a5916138999190610ded9062010fe0906128f2565b610140880151906128b6565b604051630814494760e41b906138bf908990602401615779565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516138fd9190615226565b60006040518083038160008787f1925050503d806000811461393b576040519150601f19603f3d011682016040523d82523d6000602084013e613940565b606091505b50909250905060018261396f5761396c866101000151868860200151878a604001518b60e00151614131565b90505b806139835761397e600061468e565b61398d565b61398d60006146e1565b6000806139ab8861014001518961012001518b8b6101000151614706565b915091508415156000600201547ff0cc99aeb224e65869630a14e23683d20b9c535c00427b50024ce8b6b21d35c38685856040516139eb93929190615357565b60405180910390a3505050505050505050565b60005a9050613a0b614849565b6040516313ed2f6160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906313ed2f6190613a439060009060040161557b565b6101206040518083038186803b158015613a5c57600080fd5b505af4158015613a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a949190614f92565b8051604051630270f5c360e51b8152919250600091737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091613ad3918591600401615765565b60606040518083038186803b158015613aeb57600080fd5b505af4158015613aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b239190614b32565b5090915060009050606030613b4b613b4062010fe061d6d86128f2565b60e0870151906128b6565b60405163059bab1160e51b90613b65908890602401615819565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613ba39190615226565b60006040518083038160008787f1925050503d8060008114613be1576040519150601f19603f3d011682016040523d82523d6000602084013e613be6565b606091505b509092509050600182613c0957613c06848660a001518760200151614376565b90505b80613c1d57613c18600061468e565b613c27565b613c2760006146e1565b600080613c428760e001518860c001518a8a60a00151614706565b915091508415156000600201547ff0cc99aeb224e65869630a14e23683d20b9c535c00427b50024ce8b6b21d35c3868585604051613c8293929190615357565b60405180910390a35050505050505050565b60005a9050613ca16148a6565b604051632e9d30e160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e90632e9d30e190613cd99060009060040161557b565b6101206040518083038186803b158015613cf257600080fd5b505af4158015613d06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d2a9190614d51565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091613d6c91859190600401615765565b60606040518083038186803b158015613d8457600080fd5b505af4158015613d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dbc9190614b32565b925092505060006060306001600160a01b0316613e1c613e116000600a0160008960200151613deb5788613ded565b875b6001600160a01b0316815260208101919091526040016000205462010fe0906128f2565b60e0880151906128b6565b604051637cb45e1560e11b90613e3690899060240161556c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613e749190615226565b60006040518083038160008787f1925050503d8060008114613eb2576040519150601f19603f3d011682016040523d82523d6000602084013e613eb7565b606091505b509092509050600182613eef57613eec8660200151613ed65785613ed8565b845b8760a0015188604001518960800151614486565b90505b80613f0357613efe600061468e565b613f0d565b613f0d60006146e1565b6000806139ab8860e001518960c001518b8b60a00151614706565b60005a9050613f356148a6565b60405163a1ba139560e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063a1ba139590613f6d9060009060040161557b565b6101206040518083038186803b158015613f8657600080fd5b505af4158015613f9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fbe9190614d51565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb8609161400091859190600401615765565b60606040518083038186803b15801561401857600080fd5b505af415801561402c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140509190614b32565b925092505060006060306001600160a01b031661407f613e116000600a0160008960200151613deb5788613ded565b60405163c35930c360e01b90613e3690899060240161556c565b81830381848211156141295760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156140ee5781810151838201526020016140d6565b50505050905090810190601f16801561411b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b6001600160a01b038381166000908152600a6020526040808220549288168252812054909182916060913091614166916128f2565b604051633ed76f1760e01b9061418a908d908d908d908d908d908d90602401615272565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516141c89190615226565b60006040518083038160008787f1925050503d8060008114614206576040519150601f19603f3d011682016040523d82523d6000602084013e61420b565b606091505b50915091508161428c57876001600160a01b0316896001600160a01b031660008051602061595d833981519152898460405161424892919061588f565b60405180910390a3856001600160a01b0316896001600160a01b031660008051602061595d833981519152878460405161428392919061588f565b60405180910390a35b50979650505050505050565b60008115806142b3575050808202828282816142b057fe5b04145b61293c576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4d554c5f4f564552464c4f5760881b604482015290519081900360640190fd5b6000816143055750600161293c565b6040516001600160a01b0384169083156108fc029084906000818181858888f193505050509050801515836001600160a01b03167fdbef2fc26e7694e7a1c5a4801b1ad144136d149cf76f310a780689b4087f0ffe84604051614368919061557b565b60405180910390a392915050565b600081614385575060016128eb565b60006060306001600160a01b031661d6d863c9cd976060e01b88888860006040516024016143b694939291906152ac565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516143f49190615226565b60006040518083038160008787f1925050503d8060008114614432576040519150601f19603f3d011682016040523d82523d6000602084013e614437565b606091505b50915091508161447d57856001600160a01b0316856001600160a01b031660008051602061595d833981519152868460405161447492919061588f565b60405180910390a35b50949350505050565b6000826144955750600161459e565b6001600160a01b0385166000908152600a6020526040808220549051606091309163e5b1be6560e01b906144d3908b908b908b908b906024016152ac565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516145119190615226565b60006040518083038160008787f1925050503d806000811461454f576040519150601f19603f3d011682016040523d82523d6000602084013e614554565b606091505b50915091508161459a57866001600160a01b0316866001600160a01b031660008051602061595d833981519152878460405161459192919061588f565b60405180910390a35b5090505b949350505050565b60009081526003909101602052604081208181556001810182905560020155565b600080821161460e576040805162461bcd60e51b815260206004820152600e60248201526d534d5f4449565f42595f5a45524f60901b604482015290519081900360640190fd5b600082848161461957fe5b04949350505050565b600081831061463157816128eb565b5090919050565b600081831161463157816128eb565b60008181526003830160205260408120805482919060ff81169061467590610100900463ffffffff1661479a565b92506146838160ff166147d9565b935050509250929050565b600281015460009081526003820160205260409020805465010000000000900460ff16156146bd5760036146c0565b60025b815460ff91909116650100000000000265ff00000000001990911617905550565b6002808201546000908152600390920160205260408220828155600181018390550155565b600080806147148787614298565b905061472b610e74610ded613908815a8a906128b6565b925060006147508261474b6000600601548761429890919063ffffffff16565b614622565b905061475c82826128b6565b925061476833826142f6565b6147845760405162461bcd60e51b815260040161087890615507565b61478e85846142f6565b50505094509492505050565b600063ffffffff82811614156147b35750600019610ac1565b63ffffffff82166147c657506000610ac1565b5063ffffffff8116635fee57f001919050565b600060018214156147ec57506001610ac1565b60028214156147fd57506002610ac1565b600382141561480e57506004610ac1565b600482141561481f57506004610ac1565b600582141561483057506003610ac1565b600682141561484157506003610ac1565b506000919050565b604051806101200160405280600063ffffffff16815260200160008152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b604051806101200160405280600063ffffffff168152602001600015158152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b604051806101800160405280600063ffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b8035610ac181615917565b8051610ac181615917565b8035610ac18161592f565b8051610ac18161592f565b60006101208083850312156149b6578182fd5b6149bf816158c7565b9150506149cb82614b00565b81526149d96020830161498d565b602082015260408201356040820152606082013560608201526149fe6080830161498d565b6080820152614a0f60a08301614977565b60a082015260c082013560c082015260e082013560e082015261010080830135818301525092915050565b6000610120808385031215614a4d578182fd5b614a56816158c7565b915050614a6282614b0b565b8152614a7060208301614998565b60208201526040820151604082015260608201516060820152614a9560808301614998565b6080820152614aa660a08301614982565b60a082015260c082015160c082015260e082015160e082015261010080830151818301525092915050565b60006101208284031215614ae3578081fd5b50919050565b80516001600160701b0381168114610ac157600080fd5b8035610ac18161594a565b8051610ac18161594a565b600060208284031215614b27578081fd5b81356128eb81615917565b600080600060608486031215614b46578182fd5b8351614b5181615917565b6020850151909350614b6281615917565b6040850151909250614b7381615917565b809150509250925092565b600080600060608486031215614b92578081fd5b8335614b9d81615917565b92506020840135614bad81615917565b929592945050506040919091013590565b60008060008060008060c08789031215614bd6578384fd5b8635614be181615917565b95506020870135614bf181615917565b9450604087013593506060870135614c0881615917565b92506080870135915060a0870135614c1f8161592f565b809150509295509295509295565b60008060008060808587031215614c42578182fd5b8435614c4d81615917565b93506020850135614c5d81615917565b9250604085013591506060850135614c748161592f565b939692955090935050565b600080600060608486031215614c93578081fd5b8335614c9e81615917565b92506020840135614cae8161593d565b91506040840135614b738161592f565b60008060408385031215614cd0578182fd5b8235614cdb81615917565b946020939093013593505050565b600060208284031215614cfa578081fd5b8151600681106128eb578182fd5b60008060408385031215614d1a578182fd5b8251614d258161593d565b6020939093015192949293505050565b60006101208284031215614d47578081fd5b6128eb83836149a3565b60006101208284031215614d63578081fd5b6128eb8383614a3a565b60006101208284031215614d7f578081fd5b6128eb8383614ad1565b6000610180808385031215614d9c578182fd5b614da5816158c7565b9050614db083614b00565b81526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c0820152614dfa60e0840161498d565b60e0820152610100614e0d818501614977565b9082015261012083810135908201526101408084013590820152610160928301359281019290925250919050565b6000610180808385031215614e4e578182fd5b614e57816158c7565b9050614e6283614b0b565b81526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c0820152614eac60e08401614998565b60e0820152610100614ebf818501614982565b9082015261012083810151908201526101408084015190820152610160928301519281019290925250919050565b60006101a08284031215614ae3578081fd5b6000610120808385031215614f12578182fd5b614f1b816158c7565b9050614f2683614b00565b8152602083013560208201526040830135604082015260608301356060820152614f526080840161498d565b6080820152614f6360a08401614977565b60a082015260c083013560c082015260e083013560e08201526101008084013581830152508091505092915050565b6000610120808385031215614fa5578182fd5b614fae816158c7565b9050614fb983614b0b565b8152602083015160208201526040830151604082015260608301516060820152614fe560808401614998565b6080820152614ff660a08401614982565b60a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b60006101408284031215614ae3578081fd5b60008060006060848603121561504b578081fd5b61505484614ae9565b925061506260208501614ae9565b91506040840151614b738161594a565b600060208284031215615083578081fd5b5035919050565b60006020828403121561509b578081fd5b5051919050565b600080604083850312156150b4578182fd5b505080516020909101519092909150565b6001600160a01b03169052565b15159052565b600081518084526150f08160208601602086016158eb565b601f01601f19169290920160200192915050565b6005811061510e57fe5b9052565b63ffffffff81511682526020810151151560208301526040810151604083015260608101516060830152608081015161514e60808401826150d2565b5060a081015161516160a08401826150c5565b5060c0818101519083015260e0808201519083015261010090810151910152565b803561518d81615917565b6001600160a01b0316825260208101356151a681615917565b6151b360208401826150c5565b5060408101356040830152606081013560608301526151d46080820161498d565b6151e160808401826150d2565b506151ee60a08201614977565b6151fb60a08401826150c5565b5060c0818101359083015260e0808201359083015261010090810135910152565b63ffffffff169052565b600082516152388184602087016158eb565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0396871681529486166020860152604085019390935293166060830152608082019290925290151560a082015260c00190565b6001600160a01b0394851681529290931660208301526040820152901515606082015260800190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b03841681526060810161531b6020830185615104565b8215156040830152949350505050565b6001600160a01b039390931683526020830191909152604082015260600190565b901515815260200190565b60006060825261536a60608301866150d8565b60208301949094525060400152919050565b602081016006831061538a57fe5b91905290565b6040810161539e8285615104565b8260208301529392505050565b602080825260099082015268125117d313d0d2d15160ba1b604082015260600190565b6020808252601d908201527f49445f494e53554646494349454e545f4f55545055545f414d4f554e54000000604082015260600190565b602080825260159082015274125117d3d491115497d393d517d15610d151511151605a1b604082015260600190565b60208082526015908201527449445f494e56414c49445f4f524445525f5459504560581b604082015260600190565b6020808252600a9082015269125117d156141254915160b21b604082015260600190565b60208082526010908201526f125117d4915195539117d1905253115160821b604082015260600190565b6020808252600c908201526b24a22fa327a92124a22222a760a11b604082015260600190565b602080825260169082015275125117d25394d551919250d251539517d05353d5539560521b604082015260600190565b602080825260149082015273125117d1551217d4915195539117d1905253115160621b604082015260600190565b6020808252601c908201527f49445f494e53554646494349454e545f494e5055545f414d4f554e5400000000604082015260600190565b610120810161293c8284615112565b90815260200190565b9283526001600160a01b03919091166020830152604082015260600190565b83815261016081016155b86020830185615182565b82610140830152949350505050565b8381526101e081016155e4602083016155df86614977565b6150c5565b6155f060208501614977565b6155fd60408401826150c5565b506040840135606083015260608401356080830152608084013560a083015260a084013560c083015260c084013560e083015261010060e08501358184015261564781860161498d565b9050610120615658818501836150d2565b615663818701614977565b915050610140615675818501836150c5565b61016091508086013582850152506101808186013581850152808601356101a08501525050826101c0830152949350505050565b82815261016081016156c1602083016155df85614977565b6156cd60208401614977565b6156da60408401826150c5565b506040830135606083015260608301356080830152608083013560a083015261570560a0840161498d565b61571260c08401826150d2565b5061571f60c08401614977565b61572c60e08401826150c5565b5061010060e08401358184015261012081850135818501528085013561014085015250509392505050565b918252602082015260400190565b91825263ffffffff16602082015260400190565b60006101808201905061578d82845161521c565b6020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e08301516157db60e08401826150d2565b50610100808401516157ef828501826150c5565b50506101208381015190830152610140808401519083015261016092830151929091019190915290565b60006101208201905063ffffffff835116825260208301516020830152604083015160408301526060830151606083015260808301511515608083015260a083015161586860a08401826150c5565b5060c083015160c083015260e083015160e083015261010080840151818401525092915050565b60008382526040602083015261459e60408301846150d8565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff811182821017156158e357fe5b604052919050565b60005b838110156159065781810151838201526020016158ee565b8381111561164f5750506000910152565b6001600160a01b038116811461592c57600080fd5b50565b801515811461592c57600080fd5b6005811061592c57600080fd5b63ffffffff8116811461592c57600080fdfe786212e89f390a4c768f3b935b85e0ec2561a24b6f48cda3c4b48a996b211592a2646970667358221220f18653046a066186c9c793dfac645bbc6f5193a5321321ce8223f880e84f465f64736f6c63430007050033000000000000000000000000673662e97b05e001816c380ba5a628d2e29f55d1000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000008971dc0105a22e54d81593af02167fc82af935e3
Deployed Bytecode
0x6080604052600436106102975760003560e01c8063945317131161015a578063d09ef241116100c1578063e5e7988e1161007a578063e5e7988e146107b5578063e6a0cc94146107d5578063f0aa61a3146107ea578063f968bc2a146107ff578063fe0d94c11461081f578063fe173b971461083f5761029e565b8063d09ef241146106ff578063d22e92421461072d578063e085272f1461074d578063e177246e14610760578063e30a499314610780578063e5b1be65146107955761029e565b8063b800522611610113578063b800522614610655578063be5813041461066a578063bf6b874e1461068a578063c35930c3146106aa578063c45a0155146106ca578063c9cd9760146106df5761029e565b806394531713146105955780639718f627146105b5578063af482b58146105d5578063b1af1bda146105f5578063b32ac93614610615578063b3756220146106355761029e565b80634c016016116101fe5780636b5caec4116101b75780636b5caec4146104eb5780636de3c67c1461050b57806377632ec2146105205780637f6a1caf1461054057806381449470146105605780638da5cb5b146105805761029e565b80634c0160161461043f578063514fcac71461045f57806354df6d741461047f57806357a62a4f146104ac5780635e45da23146104c15780636a42b8f8146104d65761029e565b80632da7cbfd116102505780632da7cbfd1461038a578063390ce0d31461039d5780633ed76f17146103ca5780633fc8cef3146103ea57806343133c4b146103ff57806345fa8aae146104125761029e565b806307ddd3bc146102a357806310814c37146102cc57806313af4035146102ee5780631776834a1461031057806317818a5c1461033057806320a68fab1461035d5761029e565b3661029e57005b600080fd5b6102b66102b1366004615025565b610854565b6040516102c3919061557b565b60405180910390f35b3480156102d857600080fd5b506102e16108ff565b6040516102c39190615245565b3480156102fa57600080fd5b5061030e610309366004614b16565b61090e565b005b34801561031c57600080fd5b5061030e61032b366004615072565b610994565b34801561033c57600080fd5b5061035061034b366004615072565b610a2b565b6040516102c39190615819565b34801561036957600080fd5b5061037d610378366004614b16565b610ac6565b6040516102c3919061534c565b6102b6610398366004614eed565b610ae4565b3480156103a957600080fd5b506103bd6103b8366004615072565b610b4a565b6040516102c3919061556c565b3480156103d657600080fd5b5061030e6103e5366004614bbe565b610bdd565b3480156103f657600080fd5b506102e1610bfd565b6102b661040d366004614d6d565b610c0c565b34801561041e57600080fd5b5061043261042d366004615072565b610c72565b6040516102c3919061537c565b34801561044b57600080fd5b5061037d61045a366004614b16565b610cfe565b34801561046b57600080fd5b5061030e61047a366004615072565b610d1c565b34801561048b57600080fd5b5061049f61049a366004615072565b610e40565b6040516102c39190615779565b3480156104b857600080fd5b506102b6610ed3565b3480156104cd57600080fd5b506102b6610ed9565b3480156104e257600080fd5b506102b6610edf565b3480156104f757600080fd5b5061030e610506366004614b16565b610ee5565b34801561051757600080fd5b506102b6610f60565b34801561052c57600080fd5b5061037d61053b366004615072565b610f66565b34801561054c57600080fd5b5061030e61055b366004614c7f565b610f7b565b34801561056c57600080fd5b5061030e61057b366004614d89565b611101565b34801561058c57600080fd5b506102e161130a565b3480156105a157600080fd5b5061030e6105b0366004615072565b611319565b3480156105c157600080fd5b506102b66105d0366004614b16565b61137d565b3480156105e157600080fd5b5061037d6105f0366004614b16565b611398565b34801561060157600080fd5b506103bd610610366004615072565b6113b6565b34801561062157600080fd5b5061030e610630366004615072565b6113f8565b34801561064157600080fd5b5061030e610650366004614eff565b61145c565b34801561066157600080fd5b506102b6611655565b34801561067657600080fd5b5061030e610685366004615072565b61165c565b34801561069657600080fd5b506102b66106a5366004614b16565b61172a565b3480156106b657600080fd5b5061030e6106c5366004614d35565b611745565b3480156106d657600080fd5b506102e1611cd3565b3480156106eb57600080fd5b5061030e6106fa366004614b7e565b611ce2565b34801561070b57600080fd5b5061071f61071a366004615072565b611d11565b6040516102c3929190615390565b34801561073957600080fd5b5061030e610748366004614cbe565b611da7565b6102b661075b366004614d6d565b611e39565b34801561076c57600080fd5b5061030e61077b366004615072565b611e9e565b34801561078c57600080fd5b506102b6611f04565b3480156107a157600080fd5b5061030e6107b0366004614c2d565b611f0a565b3480156107c157600080fd5b5061037d6107d0366004614b16565b612115565b3480156107e157600080fd5b506102b6612133565b3480156107f657600080fd5b506102b6612139565b34801561080b57600080fd5b5061030e61081a366004614d35565b61213f565b34801561082b57600080fd5b5061030e61083a366004615072565b61260b565b34801561084b57600080fd5b506102b661288b565b60006015546001146108815760405162461bcd60e51b8152600401610878906153ab565b60405180910390fd5b60006015819055604051636587992160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e916365879921916108c0919086906004016156a9565b60006040518083038186803b1580156108d857600080fd5b505af41580156108ec573d6000803e3d6000fd5b5050600154925050506001601555919050565b6013546001600160a01b031681565b6012546001600160a01b031633146109385760405162461bcd60e51b8152600401610878906154b1565b601280546001600160a01b0319166001600160a01b0383811691909117918290556040517f50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe292610989921690615245565b60405180910390a150565b6012546001600160a01b031633146109be5760405162461bcd60e51b8152600401610878906154b1565b604051636702eca360e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e90636702eca3906109f8906000908590600401615757565b60006040518083038186803b158015610a1057600080fd5b505af4158015610a24573d6000803e3d6000fd5b5050505050565b610a33614849565b604051634ce4436960e11b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906399c886d290610a6d906000908690600401615757565b6101206040518083038186803b158015610a8657600080fd5b505af4158015610a9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614f92565b90505b919050565b6001600160a01b03166000908152600d602052604090205460ff1690565b6000601554600114610b085760405162461bcd60e51b8152600401610878906153ab565b60006015819055604051638f0e6bef60e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e91638f0e6bef916108c0919086906010906004016155c7565b610b526148a6565b60405163ac1ecdb360e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063ac1ecdb390610b8c906000908690600401615757565b6101206040518083038186803b158015610ba557600080fd5b505af4158015610bb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614d51565b610be985878684611f0a565b610bf583878484611f0a565b505050505050565b6011546001600160a01b031690565b6000601554600114610c305760405162461bcd60e51b8152600401610878906153ab565b6000601581905560405163758e99b360e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9163758e99b3916108c0919086906010906004016155a3565b604051634dc1ffe760e11b8152600090737218d567b671e36c4e6b3257b8919196cf68ff5e90639b83ffce90610cae9084908690600401615757565b60206040518083038186803b158015610cc657600080fd5b505af4158015610cda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614ce9565b6001600160a01b03166000908152600f602052604090205460ff1690565b601554600114610d3e5760405162461bcd60e51b8152600401610878906153ab565b6000601581905560405163317e626f60e21b81528190737218d567b671e36c4e6b3257b8919196cf68ff5e9063c5f989bc90610d809084908790600401615757565b604080518083038186803b158015610d9757600080fd5b505af4158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190614d08565b9150915042610df362015180610ded610de6610edf565b85906128b6565b906128f2565b10610e105760405162461bcd60e51b815260040161087890615405565b610e1d8282856001612942565b50506000908152600b60205260409020805460ff19166001908117909155601555565b610e48614905565b60405163117d7ab160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063117d7ab190610e82906000908690600401615757565b6101806040518083038186803b158015610e9b57600080fd5b505af4158015610eaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614e3b565b60085490565b60055490565b60005490565b6012546001600160a01b03163314610f0f5760405162461bcd60e51b8152600401610878906154b1565b601380546001600160a01b0319166001600160a01b0383811691909117918290556040517f2dd8c90b4846f9ecba5790aa82e17144ea4201912f3abc8c51fd7320b527134092610989921690615245565b60075490565b6000908152600b602052604090205460ff1690565b6012546001600160a01b03163314610fa55760405162461bcd60e51b8152600401610878906154b1565b6000826004811115610fb357fe5b1415610fd15760405162461bcd60e51b815260040161087890615434565b6001826004811115610fdf57fe5b141561100e576001600160a01b0383166000908152600c60205260409020805460ff19168215151790556110c1565b600282600481111561101c57fe5b141561104b576001600160a01b0383166000908152600d60205260409020805460ff19168215151790556110c1565b600382600481111561105957fe5b1415611088576001600160a01b0383166000908152600f60205260409020805460ff19168215151790556110c1565b600482600481111561109657fe5b14156110c1576001600160a01b0383166000908152600e60205260409020805460ff19168215151790555b7f3d5726ff7c14d1fb7a71ac46100040a8b7a9edb7624e96b8abde4a15649fdf498383836040516110f4939291906152fe565b60405180910390a1505050565b3330146111205760405162461bcd60e51b8152600401610878906154b1565b4281610160015110156111455760405162461bcd60e51b815260040161087890615463565b6000806000806000611156866130c5565b9450945094509450945081600014158061116f57508015155b801561118d575061118d866060015187608001518860000151613303565b156112cc5781156112315760a0860151604051634f57f14d60e11b8152735a92a3615c547a18bf46b20cffa10f9c0db5ea4691639eafe29a916111d8918991899188916004016152d5565b604080518083038186803b1580156111ef57600080fd5b505af4158015611203573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122791906150a2565b90925090506112cc565b80156112cc5760c086015160405163aceb17df60e01b8152735a92a3615c547a18bf46b20cffa10f9c0db5ea469163aceb17df91611277918991889187916004016152d5565b604080518083038186803b15801561128e57600080fd5b505af41580156112a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c691906150a2565b90925090505b81158015906112da57508015155b156112f8576112f28587610100015186868686613431565b90925090505b610bf58661010001518585858561359f565b6012546001600160a01b031681565b6012546001600160a01b031633146113435760405162461bcd60e51b8152600401610878906154b1565b604051630fd1437d60e11b8152737218d567b671e36c4e6b3257b8919196cf68ff5e90631fa286fa906109f8906000908590600401615757565b6001600160a01b03166000908152600a602052604090205490565b6001600160a01b03166000908152600c602052604090205460ff1690565b6113be6148a6565b6040516311c8197f60e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906311c8197f90610b8c906000908690600401615757565b6012546001600160a01b031633146114225760405162461bcd60e51b8152600401610878906154b1565b60405163153cc2fd60e31b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063a9e617e8906109f8906000908590600401615757565b33301461147b5760405162461bcd60e51b8152600401610878906154b1565b4281610100015110156114a05760405162461bcd60e51b815260040161087890615463565b8051604051630270f5c360e51b8152600091737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb860916114dd91859190600401615765565b60606040518083038186803b1580156114f557600080fd5b505af4158015611509573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152d9190614b32565b50509050806001600160a01b031663caeba2176040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561156c57600080fd5b505af1158015611580573d6000803e3d6000fd5b50505050611593818284602001516135bd565b600080826001600160a01b03166389afcb448560a001516040518263ffffffff1660e01b81526004016115c69190615245565b6040805180830381600087803b1580156115df57600080fd5b505af11580156115f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161791906150a2565b9150915083604001518210158015611633575083606001518110155b61164f5760405162461bcd60e51b8152600401610878906154d7565b50505050565b6201518081565b60155460011461167e5760405162461bcd60e51b8152600401610878906153ab565b60006015819055604051631ae4f06f60e01b81528190737218d567b671e36c4e6b3257b8919196cf68ff5e90631ae4f06f906116c09084908790600401615757565b604080518083038186803b1580156116d757600080fd5b505af41580156116eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170f9190614d08565b915091506117208282856000612942565b5050600160155550565b6001600160a01b031660009081526010602052604090205490565b3330146117645760405162461bcd60e51b8152600401610878906154b1565b4281610100015110156117895760405162461bcd60e51b815260040161087890615463565b8051604051630270f5c360e51b815260009182918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb860916117ca91859190600401615765565b60606040518083038186803b1580156117e257600080fd5b505af41580156117f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181a9190614b32565b9250925092506000808560200151611833578383611836565b82845b915091506000601073c82938b53e0e190459ba4e3502bf26f194760183636c5d9cf09091858a604001516040518463ffffffff1660e01b815260040161187e93929190615584565b60206040518083038186803b15801561189657600080fd5b505af41580156118aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ce919061508a565b90506000869050806001600160a01b031663caeba2176040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561191057600080fd5b505af1158015611924573d6000803e3d6000fd5b50505050600088602001516119b8576060890151604051631b8109cf60e31b81526001600160a01b0384169163dc084e7891611963919060040161557b565b60206040518083038186803b15801561197b57600080fd5b505afa15801561198f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b3919061508a565b611a38565b6060890151604051631782077d60e31b81526001600160a01b0384169163bc103be8916119e8919060040161557b565b60206040518083038186803b158015611a0057600080fd5b505afa158015611a14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a38919061508a565b905080831015611a5a5760405162461bcd60e51b815260040161087890615535565b6000808a60200151611a725760008b60600151611a7a565b8a6060015160005b91509150611a89878b856135bd565b6011546001600160a01b038781169116148015611aa757508a608001515b15611c5f576040516336cd320560e11b81526001600160a01b03851690636d9a640a90611adc908590859030906004016158a8565b600060405180830381600087803b158015611af657600080fd5b505af1158015611b0a573d6000803e3d6000fd5b505060115460608e0151604051632e1a7d4d60e01b81526001600160a01b039092169350632e1a7d4d9250611b419160040161557b565b600060405180830381600087803b158015611b5b57600080fd5b505af1158015611b6f573d6000803e3d6000fd5b5050505060008b60a001516001600160a01b03168c6060015161271090604051611b9890615242565b600060405180830381858888f193505050503d8060008114611bd6576040519150601f19603f3d011682016040523d82523d6000602084013e611bdb565b606091505b5050905080611c595760a08c015160608d015160405163032b310f60e51b815273c82938b53e0e190459ba4e3502bf26f1947601839263656621e092611c28926010929190600401615584565b60006040518083038186803b158015611c4057600080fd5b505af4158015611c54573d6000803e3d6000fd5b505050505b50611cc6565b60a08b01516040516336cd320560e11b81526001600160a01b03861691636d9a640a91611c939186918691906004016158a8565b600060405180830381600087803b158015611cad57600080fd5b505af1158015611cc1573d6000803e3d6000fd5b505050505b5050505050505050505050565b6004546001600160a01b031690565b333014611d015760405162461bcd60e51b8152600401610878906154b1565b611d0c8383836135bd565b505050565b60405163317e626f60e21b81526000908190737218d567b671e36c4e6b3257b8919196cf68ff5e9063c5f989bc90611d4f9084908790600401615757565b604080518083038186803b158015611d6657600080fd5b505af4158015611d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9e9190614d08565b91509150915091565b6012546001600160a01b03163314611dd15760405162461bcd60e51b8152600401610878906154b1565b60405163b2456a0760e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063b2456a0790611e0d9060009086908690600401615584565b60006040518083038186803b158015611e2557600080fd5b505af4158015610bf5573d6000803e3d6000fd5b6000601554600114611e5d5760405162461bcd60e51b8152600401610878906153ab565b6000601581905560405162c44ff160e31b8152737218d567b671e36c4e6b3257b8919196cf68ff5e916306227f88916108c0919086906010906004016155a3565b6012546001600160a01b03163314611ec85760405162461bcd60e51b8152600401610878906154b1565b6000819055600481026014556040517f63e09f16584208fba1fc7ff64c62b00f07bec177c0d97ca6689891b1e77a35c79061098990839061557b565b60015490565b333014611f295760405162461bcd60e51b8152600401610878906154b1565b6011546001600160a01b038581169116148015611f435750805b15612077576040516306c5d9cf60e41b815260009073c82938b53e0e190459ba4e3502bf26f19476018390636c5d9cf090611f879060109089908890600401615584565b60206040518083038186803b158015611f9f57600080fd5b505af4158015611fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd7919061508a565b601154604051632e1a7d4d60e01b81529192506001600160a01b031690632e1a7d4d9061200890849060040161557b565b600060405180830381600087803b15801561202257600080fd5b505af1158015612036573d6000803e3d6000fd5b50506040516001600160a01b038716925083156108fc02915083906000818181858888f19350505050158015612070573d6000803e3d6000fd5b505061164f565b6040516306c5d9cf60e41b8152612110908590859073c82938b53e0e190459ba4e3502bf26f19476018390636c5d9cf0906120bb9060109086908a90600401615584565b60206040518083038186803b1580156120d357600080fd5b505af41580156120e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210b919061508a565b6135bd565b61164f565b6001600160a01b03166000908152600e602052604090205460ff1690565b60025490565b60145481565b33301461215e5760405162461bcd60e51b8152600401610878906154b1565b4281610100015110156121835760405162461bcd60e51b815260040161087890615463565b8051604051630270f5c360e51b815260009182918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb860916121c491859190600401615765565b60606040518083038186803b1580156121dc57600080fd5b505af41580156121f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122149190614b32565b925092509250600080856020015161222d578383612230565b82845b915091506000601073c82938b53e0e190459ba4e3502bf26f194760183636c5d9cf09091858a604001516040518463ffffffff1660e01b815260040161227893929190615584565b60206040518083038186803b15801561229057600080fd5b505af41580156122a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c8919061508a565b90506000869050806001600160a01b031663caeba2176040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561230a57600080fd5b505af115801561231e573d6000803e3d6000fd5b5050505061232d8488846135bd565b600088602001516123b9576040516357db007f60e11b81526001600160a01b0383169063afb600fe9061236490869060040161557b565b60206040518083038186803b15801561237c57600080fd5b505afa158015612390573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b4919061508a565b612435565b604051632e34fcc760e21b81526001600160a01b0383169063b8d3f31c906123e590869060040161557b565b60206040518083038186803b1580156123fd57600080fd5b505afa158015612411573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612435919061508a565b9050886060015181101561245b5760405162461bcd60e51b8152600401610878906153ce565b6000808a6020015161246f57600083612473565b8260005b60115491935091506001600160a01b03878116911614801561249657508a608001515b15611c5f576040516336cd320560e11b81526001600160a01b03851690636d9a640a906124cb908590859030906004016158a8565b600060405180830381600087803b1580156124e557600080fd5b505af11580156124f9573d6000803e3d6000fd5b5050601154604051632e1a7d4d60e01b81526001600160a01b039091169250632e1a7d4d915061252d90869060040161557b565b600060405180830381600087803b15801561254757600080fd5b505af115801561255b573d6000803e3d6000fd5b5050505060008b60a001516001600160a01b0316846127109060405161258090615242565b600060405180830381858888f193505050503d80600081146125be576040519150601f19603f3d011682016040523d82523d6000602084013e6125c3565b606091505b5050905080611c595760a08c015160405163032b310f60e51b815273c82938b53e0e190459ba4e3502bf26f1947601839163656621e091611c28916010918990600401615584565b60155460011461262d5760405162461bcd60e51b8152600401610878906153ab565b60006015556040517f892cd8f5b436bd5fb7dac1f11aafb73345d892ba3e9fe09cd94d95ba84928e73906126649033908490615259565b60405180910390a160005a90506000805b838110156128065760025461268c90600101610f66565b156126fe576040516305d4bd1160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906305d4bd11906126c99060009060040161557b565b60006040518083038186803b1580156126e157600080fd5b505af41580156126f5573d6000803e3d6000fd5b505050506127fe565b60008061270b6000613715565b9092509050600082600481111561271e57fe5b148061272a5750428110155b15612736575050612806565b60145481014210158061275357506013546001600160a01b031633145b8061276757506013546001600160a01b0316155b6127835760405162461bcd60e51b8152600401610878906154b1565b600193508382600481111561279457fe5b14156127a7576127a2613729565b6127fb565b60028260048111156127b557fe5b14156127c3576127a26139fe565b60038260048111156127d157fe5b14156127df576127a2613c94565b60048260048111156127ed57fe5b14156127fb576127fb613f28565b50505b600101612675565b50801561172057737218d567b671e36c4e6b3257b8919196cf68ff5e639db74df160006128345a86906128b6565b6040518363ffffffff1660e01b8152600401612851929190615757565b60006040518083038186803b15801561286957600080fd5b505af415801561287d573d6000803e3d6000fd5b505050505050600160155550565b60065490565b60019190910180546001600160a01b0319166001600160a01b03909216919091179055565b60006128eb83836040518060400160405280601081526020016f534d5f5355425f554e444552464c4f5760801b815250614099565b9392505050565b8082018281101561293c576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4144445f4f564552464c4f5760881b604482015290519081900360640190fd5b92915050565b600042612953856301e133806128f2565b109050600185600481111561296457fe5b1415612b4357612972614905565b60405163117d7ab160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063117d7ab1906129ac906000908890600401615757565b6101806040518083038186803b1580156129c557600080fd5b505af41580156129d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129fd9190614e3b565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091612a3f91859190600401615765565b60606040518083038186803b158015612a5757600080fd5b505af4158015612a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8f9190614b32565b9250925050600084612aa657836101000151612ab3565b6012546001600160a01b03165b9050612acf818486602001518588604001518960e00151614131565b612aeb5760405162461bcd60e51b815260040161087890615487565b8515612b3a576000612b1085610140015186610120015161429890919063ffffffff16565b9050612b1c82826142f6565b612b385760405162461bcd60e51b815260040161087890615507565b505b505050506130ba565b6002856004811115612b5157fe5b1415612d1b57612b5f614849565b604051634ce4436960e11b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906399c886d290612b99906000908890600401615757565b6101206040518083038186803b158015612bb257600080fd5b505af4158015612bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bea9190614f92565b8051604051630270f5c360e51b8152919250600091737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091612c29918591600401615765565b60606040518083038186803b158015612c4157600080fd5b505af4158015612c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c799190614b32565b50509050600083612c8e578260a00151612c9b565b6012546001600160a01b03165b9050612cac82828560200151614376565b612cc85760405162461bcd60e51b815260040161087890615487565b8415612d13576000612ceb8460e001518560c0015161429890919063ffffffff16565b9050612cf782826142f6565b612b3a5760405162461bcd60e51b815260040161087890615507565b5050506130ba565b6003856004811115612d2957fe5b1415612edc57612d376148a6565b60405163ac1ecdb360e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063ac1ecdb390612d71906000908890600401615757565b6101206040518083038186803b158015612d8a57600080fd5b505af4158015612d9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dc29190614d51565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091612e0491859190600401615765565b60606040518083038186803b158015612e1c57600080fd5b505af4158015612e30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e549190614b32565b9250925050600084612e6a578360a00151612e77565b6012546001600160a01b03165b9050612e9d8460200151612e8b5783612e8d565b825b8286604001518760800151614486565b612eb95760405162461bcd60e51b815260040161087890615487565b8515612b3a576000612b108560e001518660c0015161429890919063ffffffff16565b6004856004811115612eea57fe5b14156130ba57612ef86148a6565b6040516311c8197f60e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906311c8197f90612f32906000908890600401615757565b6101206040518083038186803b158015612f4b57600080fd5b505af4158015612f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f839190614d51565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091612fc591859190600401615765565b60606040518083038186803b158015612fdd57600080fd5b505af4158015612ff1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130159190614b32565b925092505060008461302b578360a00151613038565b6012546001600160a01b03165b905061304c8460200151612e8b5783612e8d565b6130685760405162461bcd60e51b815260040161087890615487565b85156130b557600061308b8560e001518660c0015161429890919063ffffffff16565b905061309782826142f6565b6130b35760405162461bcd60e51b815260040161087890615507565b505b505050505b610a246000846145a6565b8051604051630270f5c360e51b81526000918291829182918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb8609161310a91859190600401615765565b60606040518083038186803b15801561312257600080fd5b505af4158015613136573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061315a9190614b32565b60208901516040516306c5d9cf60e41b8152939850919650945060009173c82938b53e0e190459ba4e3502bf26f19476018391636c5d9cf0916131a5916010918a9190600401615584565b60206040518083038186803b1580156131bd57600080fd5b505af41580156131d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f5919061508a565b60408089015190516306c5d9cf60e41b815291925060009173c82938b53e0e190459ba4e3502bf26f19476018391636c5d9cf09161323b916010918a9190600401615584565b60206040518083038186803b15801561325357600080fd5b505af4158015613267573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061328b919061508a565b9050866001600160a01b031663caeba2176040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156132c857600080fd5b505af11580156132dc573d6000803e3d6000fd5b505050506132f38789610100015188888686613431565b9799969850949694959350505050565b63ffffffff8116600090815260096020526040808220548151630240bc6b60e21b81529151839283926001600160a01b031691630902f1ac91600480820192606092909190829003018186803b15801561335c57600080fd5b505afa158015613370573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133949190615037565b506001600160701b031691506001600160701b0316915081600014806133b8575080155b806133c1575085155b156133d1576000925050506128eb565b60006133ef826133e985670de0b6b3a7640000614298565b906145c7565b905060006134226103e861341c6134068b86614622565b6133e96103e86134168e89614638565b90614298565b906128b6565b90961115979650505050505050565b600080600080735a92a3615c547a18bf46b20cffa10f9c0db5ea466355776b778b88886040518463ffffffff1660e01b81526004016134729392919061532b565b604080518083038186803b15801561348957600080fd5b505af415801561349d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c191906150a2565b9150915081600014806134d2575080155b156134e4578585935093505050613594565b6134ef888b846135bd565b6134fa878b836135bd565b6040516335313c2160e11b81526001600160a01b038b1690636a62784290613526908c90600401615245565b602060405180830381600087803b15801561354057600080fd5b505af1158015613554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613578919061508a565b5061358386836128b6565b935061358f85826128b6565b925050505b965096945050505050565b81156135b0576135b08486846135bd565b8015610a2457610a248386835b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b6020831061363a5780518252601f19909201916020918201910161361b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461369c576040519150601f19603f3d011682016040523d82523d6000602084013e6136a1565b606091505b50915091508180156136cf5750805115806136cf57508080602001905160208110156136cc57600080fd5b50515b610a24576040805162461bcd60e51b8152602060048201526012602482015271151217d514905394d1915497d1905253115160721b604482015290519081900360640190fd5b600080611d9e838460020154600101614647565b60005a9050613736614905565b60405163a81df10f60e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063a81df10f9061376e9060009060040161557b565b6101806040518083038186803b15801561378757600080fd5b505af415801561379b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bf9190614e3b565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb8609161380191859190600401615765565b60606040518083038186803b15801561381957600080fd5b505af415801561382d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138519190614b32565b6001600160a01b038082166000908152600a602052604080822054928516825281205493965091945090925060609130916138a5916138999190610ded9062010fe0906128f2565b610140880151906128b6565b604051630814494760e41b906138bf908990602401615779565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516138fd9190615226565b60006040518083038160008787f1925050503d806000811461393b576040519150601f19603f3d011682016040523d82523d6000602084013e613940565b606091505b50909250905060018261396f5761396c866101000151868860200151878a604001518b60e00151614131565b90505b806139835761397e600061468e565b61398d565b61398d60006146e1565b6000806139ab8861014001518961012001518b8b6101000151614706565b915091508415156000600201547ff0cc99aeb224e65869630a14e23683d20b9c535c00427b50024ce8b6b21d35c38685856040516139eb93929190615357565b60405180910390a3505050505050505050565b60005a9050613a0b614849565b6040516313ed2f6160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e906313ed2f6190613a439060009060040161557b565b6101206040518083038186803b158015613a5c57600080fd5b505af4158015613a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a949190614f92565b8051604051630270f5c360e51b8152919250600091737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091613ad3918591600401615765565b60606040518083038186803b158015613aeb57600080fd5b505af4158015613aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b239190614b32565b5090915060009050606030613b4b613b4062010fe061d6d86128f2565b60e0870151906128b6565b60405163059bab1160e51b90613b65908890602401615819565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613ba39190615226565b60006040518083038160008787f1925050503d8060008114613be1576040519150601f19603f3d011682016040523d82523d6000602084013e613be6565b606091505b509092509050600182613c0957613c06848660a001518760200151614376565b90505b80613c1d57613c18600061468e565b613c27565b613c2760006146e1565b600080613c428760e001518860c001518a8a60a00151614706565b915091508415156000600201547ff0cc99aeb224e65869630a14e23683d20b9c535c00427b50024ce8b6b21d35c3868585604051613c8293929190615357565b60405180910390a35050505050505050565b60005a9050613ca16148a6565b604051632e9d30e160e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e90632e9d30e190613cd99060009060040161557b565b6101206040518083038186803b158015613cf257600080fd5b505af4158015613d06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d2a9190614d51565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb86091613d6c91859190600401615765565b60606040518083038186803b158015613d8457600080fd5b505af4158015613d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dbc9190614b32565b925092505060006060306001600160a01b0316613e1c613e116000600a0160008960200151613deb5788613ded565b875b6001600160a01b0316815260208101919091526040016000205462010fe0906128f2565b60e0880151906128b6565b604051637cb45e1560e11b90613e3690899060240161556c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613e749190615226565b60006040518083038160008787f1925050503d8060008114613eb2576040519150601f19603f3d011682016040523d82523d6000602084013e613eb7565b606091505b509092509050600182613eef57613eec8660200151613ed65785613ed8565b845b8760a0015188604001518960800151614486565b90505b80613f0357613efe600061468e565b613f0d565b613f0d60006146e1565b6000806139ab8860e001518960c001518b8b60a00151614706565b60005a9050613f356148a6565b60405163a1ba139560e01b8152737218d567b671e36c4e6b3257b8919196cf68ff5e9063a1ba139590613f6d9060009060040161557b565b6101206040518083038186803b158015613f8657600080fd5b505af4158015613f9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fbe9190614d51565b8051604051630270f5c360e51b81529192506000918291737218d567b671e36c4e6b3257b8919196cf68ff5e91634e1eb8609161400091859190600401615765565b60606040518083038186803b15801561401857600080fd5b505af415801561402c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140509190614b32565b925092505060006060306001600160a01b031661407f613e116000600a0160008960200151613deb5788613ded565b60405163c35930c360e01b90613e3690899060240161556c565b81830381848211156141295760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156140ee5781810151838201526020016140d6565b50505050905090810190601f16801561411b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b6001600160a01b038381166000908152600a6020526040808220549288168252812054909182916060913091614166916128f2565b604051633ed76f1760e01b9061418a908d908d908d908d908d908d90602401615272565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516141c89190615226565b60006040518083038160008787f1925050503d8060008114614206576040519150601f19603f3d011682016040523d82523d6000602084013e61420b565b606091505b50915091508161428c57876001600160a01b0316896001600160a01b031660008051602061595d833981519152898460405161424892919061588f565b60405180910390a3856001600160a01b0316896001600160a01b031660008051602061595d833981519152878460405161428392919061588f565b60405180910390a35b50979650505050505050565b60008115806142b3575050808202828282816142b057fe5b04145b61293c576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4d554c5f4f564552464c4f5760881b604482015290519081900360640190fd5b6000816143055750600161293c565b6040516001600160a01b0384169083156108fc029084906000818181858888f193505050509050801515836001600160a01b03167fdbef2fc26e7694e7a1c5a4801b1ad144136d149cf76f310a780689b4087f0ffe84604051614368919061557b565b60405180910390a392915050565b600081614385575060016128eb565b60006060306001600160a01b031661d6d863c9cd976060e01b88888860006040516024016143b694939291906152ac565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516143f49190615226565b60006040518083038160008787f1925050503d8060008114614432576040519150601f19603f3d011682016040523d82523d6000602084013e614437565b606091505b50915091508161447d57856001600160a01b0316856001600160a01b031660008051602061595d833981519152868460405161447492919061588f565b60405180910390a35b50949350505050565b6000826144955750600161459e565b6001600160a01b0385166000908152600a6020526040808220549051606091309163e5b1be6560e01b906144d3908b908b908b908b906024016152ac565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516145119190615226565b60006040518083038160008787f1925050503d806000811461454f576040519150601f19603f3d011682016040523d82523d6000602084013e614554565b606091505b50915091508161459a57866001600160a01b0316866001600160a01b031660008051602061595d833981519152878460405161459192919061588f565b60405180910390a35b5090505b949350505050565b60009081526003909101602052604081208181556001810182905560020155565b600080821161460e576040805162461bcd60e51b815260206004820152600e60248201526d534d5f4449565f42595f5a45524f60901b604482015290519081900360640190fd5b600082848161461957fe5b04949350505050565b600081831061463157816128eb565b5090919050565b600081831161463157816128eb565b60008181526003830160205260408120805482919060ff81169061467590610100900463ffffffff1661479a565b92506146838160ff166147d9565b935050509250929050565b600281015460009081526003820160205260409020805465010000000000900460ff16156146bd5760036146c0565b60025b815460ff91909116650100000000000265ff00000000001990911617905550565b6002808201546000908152600390920160205260408220828155600181018390550155565b600080806147148787614298565b905061472b610e74610ded613908815a8a906128b6565b925060006147508261474b6000600601548761429890919063ffffffff16565b614622565b905061475c82826128b6565b925061476833826142f6565b6147845760405162461bcd60e51b815260040161087890615507565b61478e85846142f6565b50505094509492505050565b600063ffffffff82811614156147b35750600019610ac1565b63ffffffff82166147c657506000610ac1565b5063ffffffff8116635fee57f001919050565b600060018214156147ec57506001610ac1565b60028214156147fd57506002610ac1565b600382141561480e57506004610ac1565b600482141561481f57506004610ac1565b600582141561483057506003610ac1565b600682141561484157506003610ac1565b506000919050565b604051806101200160405280600063ffffffff16815260200160008152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b604051806101200160405280600063ffffffff168152602001600015158152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b604051806101800160405280600063ffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b8035610ac181615917565b8051610ac181615917565b8035610ac18161592f565b8051610ac18161592f565b60006101208083850312156149b6578182fd5b6149bf816158c7565b9150506149cb82614b00565b81526149d96020830161498d565b602082015260408201356040820152606082013560608201526149fe6080830161498d565b6080820152614a0f60a08301614977565b60a082015260c082013560c082015260e082013560e082015261010080830135818301525092915050565b6000610120808385031215614a4d578182fd5b614a56816158c7565b915050614a6282614b0b565b8152614a7060208301614998565b60208201526040820151604082015260608201516060820152614a9560808301614998565b6080820152614aa660a08301614982565b60a082015260c082015160c082015260e082015160e082015261010080830151818301525092915050565b60006101208284031215614ae3578081fd5b50919050565b80516001600160701b0381168114610ac157600080fd5b8035610ac18161594a565b8051610ac18161594a565b600060208284031215614b27578081fd5b81356128eb81615917565b600080600060608486031215614b46578182fd5b8351614b5181615917565b6020850151909350614b6281615917565b6040850151909250614b7381615917565b809150509250925092565b600080600060608486031215614b92578081fd5b8335614b9d81615917565b92506020840135614bad81615917565b929592945050506040919091013590565b60008060008060008060c08789031215614bd6578384fd5b8635614be181615917565b95506020870135614bf181615917565b9450604087013593506060870135614c0881615917565b92506080870135915060a0870135614c1f8161592f565b809150509295509295509295565b60008060008060808587031215614c42578182fd5b8435614c4d81615917565b93506020850135614c5d81615917565b9250604085013591506060850135614c748161592f565b939692955090935050565b600080600060608486031215614c93578081fd5b8335614c9e81615917565b92506020840135614cae8161593d565b91506040840135614b738161592f565b60008060408385031215614cd0578182fd5b8235614cdb81615917565b946020939093013593505050565b600060208284031215614cfa578081fd5b8151600681106128eb578182fd5b60008060408385031215614d1a578182fd5b8251614d258161593d565b6020939093015192949293505050565b60006101208284031215614d47578081fd5b6128eb83836149a3565b60006101208284031215614d63578081fd5b6128eb8383614a3a565b60006101208284031215614d7f578081fd5b6128eb8383614ad1565b6000610180808385031215614d9c578182fd5b614da5816158c7565b9050614db083614b00565b81526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c0820152614dfa60e0840161498d565b60e0820152610100614e0d818501614977565b9082015261012083810135908201526101408084013590820152610160928301359281019290925250919050565b6000610180808385031215614e4e578182fd5b614e57816158c7565b9050614e6283614b0b565b81526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c0820152614eac60e08401614998565b60e0820152610100614ebf818501614982565b9082015261012083810151908201526101408084015190820152610160928301519281019290925250919050565b60006101a08284031215614ae3578081fd5b6000610120808385031215614f12578182fd5b614f1b816158c7565b9050614f2683614b00565b8152602083013560208201526040830135604082015260608301356060820152614f526080840161498d565b6080820152614f6360a08401614977565b60a082015260c083013560c082015260e083013560e08201526101008084013581830152508091505092915050565b6000610120808385031215614fa5578182fd5b614fae816158c7565b9050614fb983614b0b565b8152602083015160208201526040830151604082015260608301516060820152614fe560808401614998565b6080820152614ff660a08401614982565b60a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b60006101408284031215614ae3578081fd5b60008060006060848603121561504b578081fd5b61505484614ae9565b925061506260208501614ae9565b91506040840151614b738161594a565b600060208284031215615083578081fd5b5035919050565b60006020828403121561509b578081fd5b5051919050565b600080604083850312156150b4578182fd5b505080516020909101519092909150565b6001600160a01b03169052565b15159052565b600081518084526150f08160208601602086016158eb565b601f01601f19169290920160200192915050565b6005811061510e57fe5b9052565b63ffffffff81511682526020810151151560208301526040810151604083015260608101516060830152608081015161514e60808401826150d2565b5060a081015161516160a08401826150c5565b5060c0818101519083015260e0808201519083015261010090810151910152565b803561518d81615917565b6001600160a01b0316825260208101356151a681615917565b6151b360208401826150c5565b5060408101356040830152606081013560608301526151d46080820161498d565b6151e160808401826150d2565b506151ee60a08201614977565b6151fb60a08401826150c5565b5060c0818101359083015260e0808201359083015261010090810135910152565b63ffffffff169052565b600082516152388184602087016158eb565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0396871681529486166020860152604085019390935293166060830152608082019290925290151560a082015260c00190565b6001600160a01b0394851681529290931660208301526040820152901515606082015260800190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b03841681526060810161531b6020830185615104565b8215156040830152949350505050565b6001600160a01b039390931683526020830191909152604082015260600190565b901515815260200190565b60006060825261536a60608301866150d8565b60208301949094525060400152919050565b602081016006831061538a57fe5b91905290565b6040810161539e8285615104565b8260208301529392505050565b602080825260099082015268125117d313d0d2d15160ba1b604082015260600190565b6020808252601d908201527f49445f494e53554646494349454e545f4f55545055545f414d4f554e54000000604082015260600190565b602080825260159082015274125117d3d491115497d393d517d15610d151511151605a1b604082015260600190565b60208082526015908201527449445f494e56414c49445f4f524445525f5459504560581b604082015260600190565b6020808252600a9082015269125117d156141254915160b21b604082015260600190565b60208082526010908201526f125117d4915195539117d1905253115160821b604082015260600190565b6020808252600c908201526b24a22fa327a92124a22222a760a11b604082015260600190565b602080825260169082015275125117d25394d551919250d251539517d05353d5539560521b604082015260600190565b602080825260149082015273125117d1551217d4915195539117d1905253115160621b604082015260600190565b6020808252601c908201527f49445f494e53554646494349454e545f494e5055545f414d4f554e5400000000604082015260600190565b610120810161293c8284615112565b90815260200190565b9283526001600160a01b03919091166020830152604082015260600190565b83815261016081016155b86020830185615182565b82610140830152949350505050565b8381526101e081016155e4602083016155df86614977565b6150c5565b6155f060208501614977565b6155fd60408401826150c5565b506040840135606083015260608401356080830152608084013560a083015260a084013560c083015260c084013560e083015261010060e08501358184015261564781860161498d565b9050610120615658818501836150d2565b615663818701614977565b915050610140615675818501836150c5565b61016091508086013582850152506101808186013581850152808601356101a08501525050826101c0830152949350505050565b82815261016081016156c1602083016155df85614977565b6156cd60208401614977565b6156da60408401826150c5565b506040830135606083015260608301356080830152608083013560a083015261570560a0840161498d565b61571260c08401826150d2565b5061571f60c08401614977565b61572c60e08401826150c5565b5061010060e08401358184015261012081850135818501528085013561014085015250509392505050565b918252602082015260400190565b91825263ffffffff16602082015260400190565b60006101808201905061578d82845161521c565b6020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e08301516157db60e08401826150d2565b50610100808401516157ef828501826150c5565b50506101208381015190830152610140808401519083015261016092830151929091019190915290565b60006101208201905063ffffffff835116825260208301516020830152604083015160408301526060830151606083015260808301511515608083015260a083015161586860a08401826150c5565b5060c083015160c083015260e083015160e083015261010080840151818401525092915050565b60008382526040602083015261459e60408301846150d8565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff811182821017156158e357fe5b604052919050565b60005b838110156159065781810151838201526020016158ee565b8381111561164f5750506000910152565b6001600160a01b038116811461592c57600080fd5b50565b801515811461592c57600080fd5b6005811061592c57600080fd5b63ffffffff8116811461592c57600080fdfe786212e89f390a4c768f3b935b85e0ec2561a24b6f48cda3c4b48a996b211592a2646970667358221220f18653046a066186c9c793dfac645bbc6f5193a5321321ce8223f880e84f465f64736f6c63430007050033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000673662e97b05e001816c380ba5a628d2e29f55d1000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000008971dc0105a22e54d81593af02167fc82af935e3
-----Decoded View---------------
Arg [0] : _factory (address): 0x673662e97B05e001816c380bA5a628D2E29f55D1
Arg [1] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [2] : _bot (address): 0x8971Dc0105a22e54D81593AF02167FC82AF935E3
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000673662e97b05e001816c380ba5a628d2e29f55d1
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [2] : 0000000000000000000000008971dc0105a22e54d81593af02167fc82af935e3
Libraries Used
TokenShares : 0xc82938b53e0e190459ba4e3502bf26f194760183AddLiquidity : 0x5a92a3615c547a18bf46b20cffa10f9c0db5ea46
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.