More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 121 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw Funds | 19914682 | 251 days ago | IN | 0 ETH | 0.00106893 | ||||
Create Non Conti... | 19170422 | 355 days ago | IN | 0 ETH | 0.01366764 | ||||
Create Non Conti... | 19170413 | 355 days ago | IN | 0 ETH | 0.01434919 | ||||
Add Funds | 19170403 | 355 days ago | IN | 0 ETH | 0.00297944 | ||||
Process Orders | 19159265 | 357 days ago | IN | 0 ETH | 0.00028914 | ||||
Process Orders | 19158966 | 357 days ago | IN | 0 ETH | 0.00030528 | ||||
Process Orders | 19158667 | 357 days ago | IN | 0 ETH | 0.00034202 | ||||
Process Orders | 19158370 | 357 days ago | IN | 0 ETH | 0.00034646 | ||||
Process Orders | 19158082 | 357 days ago | IN | 0 ETH | 0.00033997 | ||||
Process Orders | 19157772 | 357 days ago | IN | 0 ETH | 0.0003157 | ||||
Process Orders | 19157478 | 357 days ago | IN | 0 ETH | 0.00033026 | ||||
Process Orders | 19157182 | 357 days ago | IN | 0 ETH | 0.00034956 | ||||
Process Orders | 19156887 | 357 days ago | IN | 0 ETH | 0.0003892 | ||||
Process Orders | 19156587 | 357 days ago | IN | 0 ETH | 0.00039658 | ||||
Process Orders | 19156292 | 357 days ago | IN | 0 ETH | 0.00043036 | ||||
Process Orders | 19156000 | 358 days ago | IN | 0 ETH | 0.00040334 | ||||
Process Orders | 19155699 | 358 days ago | IN | 0 ETH | 0.0004759 | ||||
Process Orders | 19155405 | 358 days ago | IN | 0 ETH | 0.0004902 | ||||
Process Orders | 19155106 | 358 days ago | IN | 0 ETH | 0.00045838 | ||||
Process Orders | 19154813 | 358 days ago | IN | 0 ETH | 0.00128975 | ||||
Process Orders | 19154514 | 358 days ago | IN | 0 ETH | 0.00040221 | ||||
Process Orders | 19154217 | 358 days ago | IN | 0 ETH | 0.00034478 | ||||
Process Orders | 19153934 | 358 days ago | IN | 0 ETH | 0.00045149 | ||||
Process Orders | 19153628 | 358 days ago | IN | 0 ETH | 0.00034433 | ||||
Process Orders | 19153329 | 358 days ago | IN | 0 ETH | 0.00037042 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
UrulokiDEX
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED // Uruloki DEX is NOT LICENSED FOR COPYING. // Uruloki DEX (C) 2022. All Rights Reserved. pragma solidity ^0.8.4; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; interface IUniswapV2Router { function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function getAmountsOut( uint amountIn, address[] calldata path ) external view returns (uint[] memory amounts); } interface IUniswapV2Factory { function getPair( address tokenA, address tokenB ) external view returns (address pair); } interface IOrderMgr { //// Define enums enum OrderType { TargetPrice, PriceRange } enum OrderStatus { Active, Cancelled, OutOfFunds, Completed } //// Define structs // One time order, it's a base order struct struct OrderBase { address userAddress; address pairedTokenAddress; address tokenAddress; OrderType orderType; uint256 targetPrice; bool isBuy; uint256 maxPrice; uint256 minPrice; OrderStatus status; uint256 amount; uint256 slippage; bool isContinuous; } // Continuous Order, it's an extended order struct, including the base order struct struct Order { OrderBase orderBase; uint256 numExecutions; uint256 resetPercentage; bool hasPriceReset; } function createOneTimeOrder( address userAddress, address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 targetPrice, uint256 minPrice, uint256 maxPrice, uint256 amount, uint256 slippage ) external returns (uint256); function createContinuousOrder( address userAddress, address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 targetPrice, uint256 minPrice, uint256 maxPrice, uint256 amount, uint256 slippage, uint256 resetPercentage ) external returns (uint256); function updateOrder( uint256 orderId, address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 targetPrice, uint256 minPrice, uint256 maxPrice, uint256 amount, uint256 slippage, uint256 resetPercentage ) external; function cancelOrder(uint256 orderId) external returns (uint256); function orderCounter() external view returns (uint256); function getOrder(uint256 orderId) external view returns (Order memory); function setOrderStatus( uint256 orderId, IOrderMgr.OrderStatus status ) external; function incNumExecutions(uint256 orderId) external; function setHasPriceReset(uint256 orderId, bool flag) external; } interface IERC20Ext is IERC20 { function decimals() external view returns (uint8); } contract UrulokiDEX is ReentrancyGuard { //// Define events // Event emitted when a one-time order is created event OneTimeOrderCreated(uint256 orderId); // Event emitted when a continuous order is created event ContinuousOrderCreated(uint256 orderId); // Event emitted when a one-time order is edited event OneTimeOrderEdited(uint256 orderId); // Event emitted when a continuous order is edited event ContinuousOrderEdited(uint256 orderId); // Event emitted when an order is canceled event OrderCanceled(uint256 orderId); // Event emitted when the price is outside of the specified price range event ExecutedOutOfPrice(uint256 orderId, bool isBuy, uint256 price); // Event emitted when a one-time order is successfully executed event ExecutedOneTimeOrder( uint256 orderId, bool isBuy, uint256 pairAmount, uint256 tokenAmount, uint256 price ); // Event emitted when a continuous order is successfully executed event ExecutedContinuousOrder( uint256 orderId, bool isBuy, uint256 price ); // Event emitted when funds are withdrawn from a user's address event FundsWithdrawn( address userAddress, address tokenAddress, uint256 amount ); // Event emitted when the owner of the contract is changed event BackendOwner(address newOwner); // Event emitted when an order is out of funds event OutOfFunds(uint256 orderId); // Event emitted when a swap during order execution fails event SwapFailed(uint256 orderId); // This event is emitted when no valid pairs for USDC, USDT, TSUKA, or WETH are found for the specified order event PairNotFound(uint256 orderId); //// Define constants address private constant UNISWAP_V2_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; address private constant UNISWAP_V2_FACTORY = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f; address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address private constant USDT = 0xc28ab4E347dd26C5809540e7dB0CEa473D91439c; address private constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address private constant TSUKA = 0xc5fB36dd2fb59d3B98dEfF88425a3F425Ee469eD; //// Define variables mapping(address => mapping(address => uint256)) public balances; IUniswapV2Router private uniswapRouter = IUniswapV2Router(UNISWAP_V2_ROUTER); IUniswapV2Factory private uniswapFactory = IUniswapV2Factory(UNISWAP_V2_FACTORY); address public backend_owner; address public orderMgrAddress; IOrderMgr _orderMgr; constructor() { backend_owner = msg.sender; } modifier initOneTimeOrderBalance ( uint256 orderId ) { IOrderMgr.Order memory order = _orderMgr.getOrder(orderId); // Validate order owner require( order.orderBase.userAddress == msg.sender, "msg.sender is not order owner" ); // Check if the order is a one-time order require(!order.orderBase.isContinuous, "Incorrect order type"); // Check if the order status is active require(order.orderBase.status == IOrderMgr.OrderStatus.Active, "Incorrect order status"); // Update the balances based on the order type if(order.orderBase.isBuy) { balances[msg.sender][order.orderBase.pairedTokenAddress] += order.orderBase.amount; } else { balances[msg.sender][order.orderBase.tokenAddress] += order.orderBase.amount; } _; } /** * @dev Validates a one-time order by checking the user's balance and updating it if necessary * @param pairedTokenAddress The address of the paired token * @param tokenAddress The address of the token * @param isBuy Boolean indicating if it's a buy order * @param amount The amount of tokens in the order * @return bool Returns true if the order is valid, false otherwise */ function validateOneTimeOrder( address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 amount ) internal returns (bool) { // if buying token, pair token is spendable else if sell, the token is spendable if (isBuy) { // Check if the user has enough balance if(balances[msg.sender][pairedTokenAddress] >= amount) { // Update the user's balance balances[msg.sender][pairedTokenAddress] -= amount; } else return false; } else { // Check if the user has enough balance if(balances[msg.sender][tokenAddress] >= amount) { // Update the user's balance balances[msg.sender][tokenAddress] -= amount; } else return false; } return true; } // set backend owner address function setBackendOwner(address new_owner) public { require(msg.sender == backend_owner, "Not admin"); backend_owner = new_owner; emit BackendOwner(backend_owner); } function setOrderMgr(address _orderMgrAddress) public { require(msg.sender == backend_owner, "setOrderMgr: not allowed"); require( _orderMgrAddress != address(0), "setOrderMgr: invalid orderMgrAddress" ); orderMgrAddress = _orderMgrAddress; _orderMgr = IOrderMgr(_orderMgrAddress); } /** * @notice allows users to make a deposit * @dev token should be transferred from the user wallet to the contract * @param tokenAddress token address * @param amount deposit amount */ function addFunds( address tokenAddress, uint256 amount ) external nonReentrant { require(amount > 0, "Amount must be greater than zero"); IERC20 token = IERC20(tokenAddress); uint256 balanceBefore = token.balanceOf(address(this)); require( token.transferFrom(msg.sender, address(this), amount), "Transfer failed" ); // Update the user's balance uint256 balanceDiff = token.balanceOf(address(this)) - balanceBefore; balances[USDT][tokenAddress] += balanceDiff; balances[msg.sender][tokenAddress] += balanceDiff; } /** * @dev funds withdrawal external call * @param tokenAddress token address * @param amount token amount */ function withdrawFunds( address tokenAddress, uint256 amount ) external nonReentrant { require(amount > 0, "Amount must be greater than zero"); // Check if the user has enough balance to withdraw require( balances[msg.sender][tokenAddress] >= amount, "Insufficient balance" ); // Update the user's balance balances[msg.sender][tokenAddress] -= amount; // Transfer ERC20 token to the user IERC20 token = IERC20(tokenAddress); require(token.transfer(msg.sender, amount), "Transfer failed"); // Emit event emit FundsWithdrawn(msg.sender, tokenAddress, amount); } /** * @notice create non-continuous price range order * @dev The orders are only executed when the market price is less than or equal to the minPrice and greater than or equal to the maxPrice * @param pairedTokenAddress The address of the paired token in the trading pair * @param tokenAddress The address of the token being traded * @param isBuy Indicates whether it is a buy or sell order (true for buy, false for sell) * @param minPrice Minimum price for the order. The value's decimal is in USDC decimal 6 format * @param maxPrice Maximum price for the order. The value's decimal is in USDC decimal 6 format * @param amount The amount of tokens for the order. The value's decimal is the traded token decimal format. * @param slippage The slippage tolerance for the order. This is minAmountOut value and decimal is the traded token decimal format. */ function createNonContinuousPriceRangeOrder( address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 minPrice, uint256 maxPrice, uint256 amount, uint256 slippage ) external nonReentrant { require(validateOneTimeOrder(pairedTokenAddress, tokenAddress, isBuy, amount), "Validation failed"); uint256 id = _orderMgr.createOneTimeOrder( msg.sender, pairedTokenAddress, tokenAddress, isBuy, 0, minPrice, maxPrice, amount, slippage ); // Emit an event emit OneTimeOrderCreated(id); } /** * @notice creates a non-continuous order with a target price * @dev Target price orders are only executed when certain conditions are met: * - For buy orders, the market price must be less than or equal to the target price * - For sell orders, the market price must be greater than or equal to the target price * @param pairedTokenAddress The address of the paired token in the trading pair * @param tokenAddress The address of the token being traded * @param isBuy Indicates whether it is a buy or sell order (true for buy, false for sell) * @param targetPrice The target price for the order. The value's decimal is in USDC decimal 6 format * @param amount The amount of tokens for the order. The value's decimal is the traded token decimal format. * @param slippage The slippage tolerance for the order. This is minAmountOut value and decimal is the traded token decimal format. */ function createNonContinuousTargetPriceOrder( address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 targetPrice, uint256 amount, uint256 slippage ) external nonReentrant { require(validateOneTimeOrder(pairedTokenAddress, tokenAddress, isBuy, amount), "Validation failed"); // Create a new order uint256 id = _orderMgr.createOneTimeOrder( msg.sender, pairedTokenAddress, tokenAddress, isBuy, targetPrice, 0, 0, amount, slippage ); // Emit event emit OneTimeOrderCreated(id); } /** * @notice creates a continuous order with price range * @dev The orders are only executed continuely when the market price is less than or equal to the minPrice and greater than or equal to the maxPrice * @param pairedTokenAddress The address of the paired token in the trading pair * @param tokenAddress The address of the token being traded * @param isBuy Indicates whether it is a buy or sell order (true for buy, false for sell) * @param minPrice Minimum price for the order. The value's decimal is in USDC decimal 6 format * @param maxPrice Maximum price for the order. The value's decimal is in USDC decimal 6 format * @param amount The amount of tokens for the order. The value's decimal is the traded token decimal format. * @param slippage The slippage tolerance for the order. This is minAmountOut value and decimal is the traded token decimal format. * @param resetPercentage decimal represented as an int with 0 places of precision */ function createContinuousPriceRangeOrder( address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 minPrice, uint256 maxPrice, uint256 amount, uint256 slippage, uint256 resetPercentage ) external nonReentrant { uint256 id = _orderMgr.createContinuousOrder( msg.sender, pairedTokenAddress, tokenAddress, isBuy, 0, minPrice, maxPrice, amount, slippage, resetPercentage ); // Emit an event emit ContinuousOrderCreated(id); } /** * @notice creates a continuous order with a target price * @dev The orders are only executed continuely when certain conditions are met: * - For buy orders, the market price must be less than or equal to the target price * - For sell orders, the market price must be greater than or equal to the target price * @param pairedTokenAddress The address of the paired token in the trading pair * @param tokenAddress The address of the token being traded * @param isBuy Indicates whether it is a buy or sell order (true for buy, false for sell) * @param targetPrice The target price for the order. The value's decimal is in USDC decimal 6 format * @param amount The amount of tokens for the order. The value's decimal is the traded token decimal format. * @param slippage The slippage tolerance for the order. This is minAmountOut value and decimal is the traded token decimal format. * @param resetPercentage decimal represented as an int with 0 places of precision */ function createContinuousTargetPriceOrder( address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 targetPrice, uint256 amount, uint256 slippage, uint256 resetPercentage ) external nonReentrant { // Create the ContinuousOrder struct uint256 id = _orderMgr.createContinuousOrder( msg.sender, pairedTokenAddress, tokenAddress, isBuy, targetPrice, 0, 0, amount, slippage, resetPercentage ); // Emit an event emit ContinuousOrderCreated(id); } /** * @dev cancel exist order * @param orderId order id */ function cancelOrder(uint256 orderId) external { // Validate order owner IOrderMgr.Order memory order = _orderMgr.getOrder(orderId); require( order.orderBase.userAddress == msg.sender, "msg.sender is not order owner" ); _orderMgr.cancelOrder(orderId); if (!order.orderBase.isContinuous) if (order.orderBase.isBuy) { balances[msg.sender][order.orderBase.pairedTokenAddress] += order .orderBase .amount; } else { balances[msg.sender][order.orderBase.tokenAddress] += order .orderBase .amount; } // Emit event emit OrderCanceled(orderId); } /** * @notice process a one-time order * @dev internal function * @param orderId id of the order */ function _processOneTimeOrder(IOrderMgr.Order memory order, uint256 orderId) internal returns (bool) { // Get the price in amount (uint256 price, bool isExistPair) = _getPairPrice( order.orderBase.tokenAddress, 10 ** IERC20Ext(order.orderBase.tokenAddress).decimals() ); if(!isExistPair) { emit PairNotFound(orderId); return false; } address fromToken; address toToken; uint256 toAmount; bool swapStatus; // Check if the order type is PriceRange if (order.orderBase.orderType == IOrderMgr.OrderType.PriceRange) { if ( order.orderBase.minPrice > price || price > order.orderBase.maxPrice ) { emit ExecutedOutOfPrice(orderId, order.orderBase.isBuy, price); return false; } } if (order.orderBase.isBuy) { // Check if the order type is TargetPrice if (order.orderBase.orderType == IOrderMgr.OrderType.TargetPrice) { if ( price > order.orderBase.targetPrice ) { emit ExecutedOutOfPrice(orderId, order.orderBase.isBuy, price); return false; } } fromToken = order.orderBase.pairedTokenAddress; toToken = order.orderBase.tokenAddress; } else { // Check if the order type is TargetPrice if (order.orderBase.orderType == IOrderMgr.OrderType.TargetPrice) { if (price < order.orderBase.targetPrice) { emit ExecutedOutOfPrice(orderId, order.orderBase.isBuy, price); return false; } } fromToken = order.orderBase.tokenAddress; toToken = order.orderBase.pairedTokenAddress; } (toAmount, swapStatus) = _swapTokens( order.orderBase.pairedTokenAddress, order.orderBase.tokenAddress, order.orderBase.isBuy, order.orderBase.amount, order.orderBase.slippage ); if(swapStatus) { balances[order.orderBase.userAddress][toToken] += toAmount; _orderMgr.setOrderStatus(orderId, IOrderMgr.OrderStatus.Completed); emit ExecutedOneTimeOrder( orderId, order.orderBase.isBuy, order.orderBase.amount, toAmount, price ); return true; } else { emit SwapFailed(orderId); return false; } } /** * @notice process a continuous order * @dev internal function * @param orderId id of the order */ function _processContinuousOrder(IOrderMgr.Order memory order, uint256 orderId) internal returns (bool){ if (order.orderBase.targetPrice == 0) { // Price range order return _processContinuousPriceRangeOrder(order, orderId); } else { // Target price order return _processContinuousTargetPriceOrder(order, orderId); } } /** * @dev Internal function to process a continuous price range order * @param order The order memory instance * @param orderId Order ID * @return bool Returns true if the order is processed successfully, false otherwise */ function _processContinuousPriceRangeOrder( IOrderMgr.Order memory order, uint256 orderId ) internal returns(bool) { // Get the price in amount (uint256 price, bool isExistPair) = _getPairPrice( order.orderBase.tokenAddress, 10 ** IERC20Ext(order.orderBase.tokenAddress).decimals() ); // Check if the price is not found for the pair if(!isExistPair) { emit PairNotFound(orderId); return false; } // Check if the order has price reset if (order.hasPriceReset) { // Check if the price is within the specified range if ( order.orderBase.minPrice > price || price > order.orderBase.maxPrice ) { emit ExecutedOutOfPrice(orderId, order.orderBase.isBuy, price); return false; } address fromToken; address toToken; uint256 toAmount; bool swapStatus; // Determine the tokens for swapping based on the order type if (order.orderBase.isBuy) { fromToken = order.orderBase.pairedTokenAddress; toToken = order.orderBase.tokenAddress; } else { fromToken = order.orderBase.tokenAddress; toToken = order.orderBase.pairedTokenAddress; } // Check if the user has enough balance of the fromToken if ( balances[order.orderBase.userAddress][fromToken] >= order.orderBase.amount ) { // Swap tokens (toAmount, swapStatus) = _swapTokens( order.orderBase.pairedTokenAddress, order.orderBase.tokenAddress, order.orderBase.isBuy, order.orderBase.amount, order.orderBase.slippage ); if(swapStatus) { // Update user's balances balances[order.orderBase.userAddress][toToken] += toAmount; balances[order.orderBase.userAddress][fromToken] -= order .orderBase .amount; // Update order status and execution count _orderMgr.setOrderStatus(orderId, IOrderMgr.OrderStatus.Active); _orderMgr.incNumExecutions(orderId); _orderMgr.setHasPriceReset(orderId, false); emit ExecutedContinuousOrder(orderId, order.orderBase.isBuy, price); } else { emit SwapFailed(orderId); } } else { // Set order status as out of funds _orderMgr.setOrderStatus( orderId, IOrderMgr.OrderStatus.OutOfFunds ); emit OutOfFunds(orderId); } } else { // Calculate the lower and upper price differences based on the reset percentage uint256 lowerDiff = (order.orderBase.minPrice * order.resetPercentage) / 100; uint256 upperDiff = (order.orderBase.maxPrice * order.resetPercentage) / 100; // Check if the price is outside the adjusted range if ( price > order.orderBase.minPrice - lowerDiff && price < order.orderBase.maxPrice + upperDiff ) { return false; } // Set hasPriceReset to true for the order _orderMgr.setHasPriceReset(orderId, true); } return true; } /** * @dev Processes a continuous order with a target price * @param order The order to process * @param orderId The ID of the order * @return bool Returns true if the order is successfully processed, false otherwise */ function _processContinuousTargetPriceOrder( IOrderMgr.Order memory order, uint256 orderId ) internal returns (bool) { // Get the price in amount (uint256 price, bool isExistPair) = _getPairPrice( order.orderBase.tokenAddress, 10 ** IERC20Ext(order.orderBase.tokenAddress).decimals() ); // Check if the price is 0, indicating that the pair does not exist if(!isExistPair) { emit PairNotFound(orderId); return false; } // Check if the order is a buy order if (order.orderBase.isBuy) { // Check if the order has price reset if (order.hasPriceReset) { // Check if the current price is greater than the target price if (price > order.orderBase.targetPrice) { emit ExecutedOutOfPrice(orderId, order.orderBase.isBuy, price); return false; } // Swap tokens and update balances uint256 toAmount; bool swapStatus; // Check if the user has sufficient balance of fromToken if ( balances[order.orderBase.userAddress][order.orderBase.pairedTokenAddress] >= order.orderBase.amount ) { (toAmount, swapStatus) = _swapTokens( order.orderBase.pairedTokenAddress, order.orderBase.tokenAddress, order.orderBase.isBuy, order.orderBase.amount, order.orderBase.slippage ); if(swapStatus) { // Update user's balances balances[order.orderBase.userAddress][order.orderBase.tokenAddress] += toAmount; balances[order.orderBase.userAddress][order.orderBase.pairedTokenAddress] -= order .orderBase .amount; // Update order status and execution count _orderMgr.setOrderStatus( orderId, IOrderMgr.OrderStatus.Active ); _orderMgr.incNumExecutions(orderId); _orderMgr.setHasPriceReset(orderId, false); emit ExecutedContinuousOrder(orderId, order.orderBase.isBuy, price); } else { emit SwapFailed(orderId); } } else { // Set order status as out of funds _orderMgr.setOrderStatus( orderId, IOrderMgr.OrderStatus.OutOfFunds ); emit OutOfFunds(orderId); } } else { uint256 diff = (order.orderBase.targetPrice * order.resetPercentage) / 100; // Check if the current price is less than the target price plus the difference if (price < order.orderBase.targetPrice + diff) { return false; } _orderMgr.setHasPriceReset(orderId, true); } } else { // Check if the order has price reset if (order.hasPriceReset) { // Check if the current price is less than the target price if (price < order.orderBase.targetPrice) { emit ExecutedOutOfPrice(orderId, order.orderBase.isBuy, price); return false; } // Swap tokens and update balances uint256 toAmount; bool swapStatus; // Check if the user has sufficient balance of fromToken if ( balances[order.orderBase.userAddress][order.orderBase.tokenAddress] >= order.orderBase.amount ) { (toAmount, swapStatus) = _swapTokens( order.orderBase.pairedTokenAddress, order.orderBase.tokenAddress, order.orderBase.isBuy, order.orderBase.amount, order.orderBase.slippage ); if(swapStatus) { balances[order.orderBase.userAddress][order.orderBase.pairedTokenAddress] += toAmount; balances[order.orderBase.userAddress][order.orderBase.tokenAddress] -= order .orderBase .amount; _orderMgr.setOrderStatus( orderId, IOrderMgr.OrderStatus.Active ); _orderMgr.incNumExecutions(orderId); _orderMgr.setHasPriceReset(orderId, false); emit ExecutedContinuousOrder(orderId, order.orderBase.isBuy, price); } else { emit SwapFailed(orderId); } } else { _orderMgr.setOrderStatus( orderId, IOrderMgr.OrderStatus.OutOfFunds ); emit OutOfFunds(orderId); } } else { uint256 diff = (order.orderBase.targetPrice * order.resetPercentage) / 100; // Check if the current price is greater than the target price minus the difference if (price > order.orderBase.targetPrice - diff) { return false; } _orderMgr.setHasPriceReset(orderId, true); } } return true; } /** * @dev Processes multiple orders based on the provided order IDs * @param orderIds An array of order IDs to process */ function processOrders( uint256[] memory orderIds ) external { IOrderMgr.Order memory order; // Iterate through each order ID in the orderIds array for (uint256 i = 0; i < orderIds.length; i++) { uint256 orderId = orderIds[i]; order = _orderMgr.getOrder(orderId); // Check if the tokenAddress of the order is the zero address // If it is, skip to the next iteration of the loop if (order.orderBase.tokenAddress == address(0)) continue; // Check if the order is a continuous order if (order.orderBase.isContinuous == true) { // If the order is cancelled, skip to the next iteration of the loop if (order.orderBase.status == IOrderMgr.OrderStatus.Cancelled) continue; _processContinuousOrder(order, orderId); } else { // If the order is not active, skip to the next iteration of the loop if (order.orderBase.status != IOrderMgr.OrderStatus.Active) continue; _processOneTimeOrder(order, orderId); } } } /** * @dev Swaps tokens from one token to another using the Uniswap router * @param _pairedTokenAddress The address of the paired token * @param _tokenAddress The address of the token to swap to * @param _isBuy Indicates whether it is a buy or sell order * @param _amount The amount of tokens to swap * @param _slippage The maximum acceptable slippage for the swap * @return uint256 The amount of tokens received after the swap * @return bool The status of the swap (true if successful, false otherwise) */ function _swapTokens( address _pairedTokenAddress, address _tokenAddress, bool _isBuy, uint256 _amount, uint256 _slippage ) internal returns (uint256, bool) { address _fromTokenAddress; address _toTokenAddress; address _middlePath = address(0); if(_isBuy) { _fromTokenAddress = _pairedTokenAddress; _toTokenAddress = _tokenAddress; } else { _fromTokenAddress = _tokenAddress; _toTokenAddress = _pairedTokenAddress; } if(!checkIfPairExists(_pairedTokenAddress, _tokenAddress)) { if(_pairedTokenAddress != WETH && checkIfPairExists(WETH, _tokenAddress)) { _middlePath = WETH; } else if (_pairedTokenAddress != USDC && checkIfPairExists(USDC, _tokenAddress)) { _middlePath = USDC; } else if(_pairedTokenAddress != USDT && checkIfPairExists(USDT, _tokenAddress)) { _middlePath = USDT; } else if( _pairedTokenAddress != TSUKA && _tokenAddress != TSUKA && checkIfPairExists(TSUKA, _pairedTokenAddress) && checkIfPairExists(TSUKA, _tokenAddress) ) { _middlePath = TSUKA; } } IERC20 fromToken = IERC20(_fromTokenAddress); fromToken.approve(address(uniswapRouter), _amount); uint256 balanceBefore = IERC20(_toTokenAddress).balanceOf(address(this)); if(_middlePath == address(0)) { address[] memory path = new address[](2); path[0] = _fromTokenAddress; path[1] = _toTokenAddress; uniswapRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens( _amount, _slippage, path, address(this), block.timestamp ); } else { address[] memory path = new address[](3); path[0] = _fromTokenAddress; path[1] = _middlePath; path[2] = _toTokenAddress; uniswapRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens( _amount, _slippage, path, address(this), block.timestamp ); } uint256 toAmount = IERC20(_toTokenAddress).balanceOf(address(this)) - balanceBefore; // Return the amount of tokens received and the status of the swap return (toAmount, true); } /** * @dev Checks if a pair exists for the given tokens in the Uniswap exchange * @param token1 The address of the first token * @param token2 The address of the second token * @return bool Returns true if a pair exists, false otherwise */ function checkIfPairExists( address token1, address token2 ) internal view returns(bool) { // Get the pair address from the Uniswap factory contract address pair = uniswapFactory.getPair(token1, token2); // If the pair address is equal to the zero address, it means the pair does not exist. if(pair == address(0)) return false; else return true; } /** * @dev Retrieves the price of a token pair based on the specified token address and amount * @param _tokenAddress The address of the token * @param _amount The amount of the token * @return uint256 The price of the token pair */ function _getPairPrice( address _tokenAddress, uint256 _amount ) internal view returns (uint256, bool) { // Check if a pair exists for USDC and the specified token if (checkIfPairExists(USDC, _tokenAddress)) { address[] memory path = new address[](2); path[0] = _tokenAddress; path[1] = USDC; return (getAmountOut(path, _amount), true); } // Check if a pair exists for USDT and the specified token if (checkIfPairExists(USDT, _tokenAddress)) { address[] memory path = new address[](2); path[0] = _tokenAddress; path[1] = USDT; return (getAmountOut(path, _amount), true); } // Check if a pair exists for WETH and the specified token if (checkIfPairExists(WETH, _tokenAddress)) { address[] memory path = new address[](3); path[0] = _tokenAddress; path[1] = WETH; path[2] = USDC; return (getAmountOut(path, _amount), true); } // Check if a pair exists for TSUKA and the specified token if (checkIfPairExists(TSUKA, _tokenAddress)) { address[] memory path = new address[](3); path[0] = _tokenAddress; path[1] = TSUKA; path[2] = USDC; return (getAmountOut(path, _amount), true); } // If no pair exists, return 0 return (0, false); } /** * @dev Retrieves the amount out for a given input amount and path of token addresses * @param path The array of token addresses representing the path * @param amount The input amount * @return uint256 The amount out */ function getAmountOut( address[] memory path, uint256 amount ) internal view returns (uint256) { // Get the amounts out for the specified input amount and path uint[] memory amountsOut = uniswapRouter.getAmountsOut(amount, path); // The getAmountsOut function from the Uniswap router contract is called with the specified input amount and path // It returns an array of amounts representing the output amounts at each step of the path // Return the amount out of the final token. // The amount out is obtained by accessing the last element of the amountsOut array using path.length - 1 // This represents the output amount of the final token in the path after the swap return amountsOut[path.length - 1]; } /** * @dev Retrieves the price of a token based on the specified token address * @param _tokenAddress The address of the token * @return uint256 The price of the token */ function getTokenPrice( address _tokenAddress ) external view returns (uint256) { // Get the decimals of the token uint256 tokenDecimals = 10 ** IERC20Ext(_tokenAddress).decimals(); // Get the pair price for the specified token (uint256 price, ) = _getPairPrice(_tokenAddress, tokenDecimals); return price; } /** * @notice edit a continuous order with target price * @param orderId Order id * @param pairedTokenAddress The address of the paired token in the trading pair * @param tokenAddress The address of the token being traded * @param isBuy Indicates whether it is a buy or sell order (true for buy, false for sell) * @param targetPrice The target price for the order. The value's decimal is in USDC decimal 6 format * @param amount The amount of tokens for the order. The value's decimal is the traded token decimal format. * @param slippage The slippage tolerance for the order. This is minAmountOut value and decimal is the traded token decimal format. * @param resetPercentage decimal represented as an int with 0 places of precision */ function editContinuousTargetPriceOrder( uint256 orderId, address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 targetPrice, uint256 amount, uint256 slippage, uint256 resetPercentage ) external { IOrderMgr.Order memory order = _orderMgr.getOrder(orderId); // Validate order owner require( order.orderBase.userAddress == msg.sender, "msg.sender is not order owner" ); // Is continous order require(order.orderBase.isContinuous == true, "Incorrect order type"); _orderMgr.updateOrder( orderId, pairedTokenAddress, tokenAddress, isBuy, targetPrice, 0, 0, amount, slippage, resetPercentage ); // Emit an event emit ContinuousOrderEdited(orderId); } /** * @notice edit a continuous order with price range * @param orderId order id * @param pairedTokenAddress The address of the paired token in the trading pair * @param tokenAddress The address of the token being traded * @param isBuy Indicates whether it is a buy or sell order (true for buy, false for sell) * @param minPrice Minimum price for the order. The value's decimal is in USDC decimal 6 format * @param maxPrice Maximum price for the order. The value's decimal is in USDC decimal 6 format * @param amount The amount of tokens for the order. The value's decimal is the traded token decimal format. * @param slippage The slippage tolerance for the order. This is minAmountOut value and decimal is the traded token decimal format. * @param resetPercentage decimal represented as an int with 0 places of precision */ function editContinuousPriceRangeOrder( uint256 orderId, address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 minPrice, uint256 maxPrice, uint256 amount, uint256 slippage, uint256 resetPercentage ) external { IOrderMgr.Order memory order = _orderMgr.getOrder(orderId); // Validate order owner require( order.orderBase.userAddress == msg.sender, "msg.sender is not order owner" ); // Is continous order require(order.orderBase.isContinuous == true, "Incorrect order type"); _orderMgr.updateOrder( orderId, pairedTokenAddress, tokenAddress, isBuy, 0, minPrice, maxPrice, amount, slippage, resetPercentage ); // Emit an event emit ContinuousOrderEdited(orderId); } /** * @notice Edit non-continuous order with price range * @param orderId Order id * @param pairedTokenAddress The address of the paired token in the trading pair * @param tokenAddress The address of the token being traded * @param isBuy Indicates whether it is a buy or sell order (true for buy, false for sell) * @param minPrice Minimum price for the order. The value's decimal is in USDC decimal 6 format * @param maxPrice Maximum price for the order. The value's decimal is in USDC decimal 6 format * @param amount The amount of tokens for the order. The value's decimal is the traded token decimal format. * @param slippage The slippage tolerance for the order. This is minAmountOut value and decimal is the traded token decimal format. */ function editNonContinuousPriceRangeOrder( uint256 orderId, address pairedTokenAddress, address tokenAddress, bool isBuy, uint256 minPrice, uint256 maxPrice, uint256 amount, uint256 slippage ) external nonReentrant initOneTimeOrderBalance(orderId) { require(validateOneTimeOrder(pairedTokenAddress, tokenAddress, isBuy, amount), "Validation failed"); _orderMgr.updateOrder( orderId, pairedTokenAddress, tokenAddress, isBuy, 0, minPrice, maxPrice, amount, slippage, 0 ); // Emit an event emit OneTimeOrderEdited(orderId); } /** * @notice Edit a non-continuous order with a target price * @dev Target price order is only executed when the market price is equal to the target price * @param orderId Order id * @param pairedTokenAddress The address of the paired token in the trading pair * @param tokenAddress The address of the token being traded * @param isBuy Indicates whether it is a buy or sell order (true for buy, false for sell) * @param targetPrice The target price for the order. The value's decimal is in USDC decimal 6 format * @param amount The amount of tokens for the order. The value's decimal is the traded token decimal format. * @param slippage The slippage tolerance for the order. This is minAmountOut value and decimal is the traded token decimal format. */ function editNonContinuousTargetPriceOrder( uint256 orderId, address pairedTokenAddress, address tokenAddress, uint256 targetPrice, bool isBuy, uint256 amount, uint256 slippage ) external nonReentrant initOneTimeOrderBalance(orderId) { require(validateOneTimeOrder(pairedTokenAddress, tokenAddress, isBuy, amount), "Validation failed"); _orderMgr.updateOrder( orderId, pairedTokenAddress, tokenAddress, isBuy, targetPrice, 0, 0, amount, slippage, 0 ); // Emit event emit OneTimeOrderEdited(orderId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"BackendOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"ContinuousOrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"ContinuousOrderEdited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"ExecutedContinuousOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"uint256","name":"pairAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"ExecutedOneTimeOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"ExecutedOutOfPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"OneTimeOrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"OneTimeOrderEdited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"OrderCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"OutOfFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"PairNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"SwapFailed","type":"event"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"backend_owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pairedTokenAddress","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"uint256","name":"resetPercentage","type":"uint256"}],"name":"createContinuousPriceRangeOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pairedTokenAddress","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"targetPrice","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"uint256","name":"resetPercentage","type":"uint256"}],"name":"createContinuousTargetPriceOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pairedTokenAddress","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"createNonContinuousPriceRangeOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pairedTokenAddress","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"targetPrice","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"createNonContinuousTargetPriceOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"address","name":"pairedTokenAddress","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"uint256","name":"resetPercentage","type":"uint256"}],"name":"editContinuousPriceRangeOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"address","name":"pairedTokenAddress","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"targetPrice","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"uint256","name":"resetPercentage","type":"uint256"}],"name":"editContinuousTargetPriceOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"address","name":"pairedTokenAddress","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"editNonContinuousPriceRangeOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"address","name":"pairedTokenAddress","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"targetPrice","type":"uint256"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"editNonContinuousTargetPriceOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"getTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"orderMgrAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"orderIds","type":"uint256[]"}],"name":"processOrders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"new_owner","type":"address"}],"name":"setBackendOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_orderMgrAddress","type":"address"}],"name":"setOrderMgr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600280546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d1790915560038054909116735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f179055348015610057575f80fd5b5060015f55600480546001600160a01b03191633179055613e0b8061007b5f395ff3fe608060405234801561000f575f80fd5b5060043610610111575f3560e01c80635d58b7561161009e578063bc4b33651161006e578063bc4b33651461022b578063c10753291461023e578063c23f001f14610251578063d02641a014610289578063f77d46311461029c575f80fd5b80635d58b756146101df578063754dea40146101f25780637720f717146102055780638bd4185814610218575f80fd5b806338800428116100e4578063388004281461016357806341929f0f14610193578063441106c9146101a6578063452c4875146101b9578063514fcac7146101cc575f80fd5b80630848a3c7146101155780630d48317b1461012a578063209f90c31461013d5780632b0b066214610150575b5f80fd5b61012861012336600461334d565b6102af565b005b6101286101383660046133ae565b6103b5565b61012861014b366004613429565b61052a565b61012861015e36600461349b565b6107cd565b600554610176906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101286101a1366004613572565b6108b5565b6101286101b4366004613603565b6109f3565b6101286101c736600461366f565b610c95565b6101286101da3660046136d8565b610d64565b6101286101ed3660046136ef565b610f42565b61012861020036600461349b565b611011565b61012861021336600461366f565b6110ab565b610128610226366004613429565b61118e565b610128610239366004613761565b611302565b61012861024c366004613761565b611584565b61027b61025f36600461378b565b600160209081525f928352604080842090915290825290205481565b60405190815260200161018a565b61027b61029736600461349b565b61177c565b600454610176906001600160a01b031681565b6102b76117ff565b6102c386868685611856565b6102e85760405162461bcd60e51b81526004016102df906137c2565b60405180910390fd5b600654604051630d570f1560e31b81525f916001600160a01b031690636ab878a8906103289033908b908b908b908b90899081908d908d906004016137ed565b6020604051808303815f875af1158015610344573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610368919061383d565b90507f7ae91fe4742a77fb791e82e77c1b02800bd8fc0829aab88c2f0c1f5009a8d7658160405161039b91815260200190565b60405180910390a1506103ad60015f55565b505050505050565b60065460405163d09ef24160e01b8152600481018b90525f916001600160a01b03169063d09ef241906024016101e060405180830381865afa1580156103fd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610421919061388b565b8051519091506001600160a01b0316331461044e5760405162461bcd60e51b81526004016102df90613995565b8051610160015115156001146104765760405162461bcd60e51b81526004016102df906139cc565b600654604051635585b19360e01b81526001600160a01b0390911690635585b193906104b8908d908d908d908d905f908e908e908e908e908e906004016139fa565b5f604051808303815f87803b1580156104cf575f80fd5b505af11580156104e1573d5f803e3d5ffd5b505050507ff6889aa0780be70c770f893999b0adcc2cd01470d2ee0b90f706c5077d93e56b8a60405161051691815260200190565b60405180910390a150505050505050505050565b6105326117ff565b60065460405163d09ef24160e01b8152600481018a905289915f916001600160a01b039091169063d09ef241906024016101e060405180830381865afa15801561057e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a2919061388b565b8051519091506001600160a01b031633146105cf5760405162461bcd60e51b81526004016102df90613995565b80516101600151156105f35760405162461bcd60e51b81526004016102df906139cc565b5f81516101000151600381111561060c5761060c613a4b565b146106525760405162461bcd60e51b8152602060048201526016602482015275496e636f7272656374206f726465722073746174757360501b60448201526064016102df565b805160a00151156106a55780516101200151335f90815260016020908152604080832085518301516001600160a01b031684529091528120805490919061069a908490613a73565b909155506106e89050565b80516101200151335f90815260016020908152604080832085518201516001600160a01b03168452909152812080549091906106e2908490613a73565b90915550505b6106f489898987611856565b6107105760405162461bcd60e51b81526004016102df906137c2565b600654604051635585b19360e01b81526001600160a01b0390911690635585b19390610752908d908d908d908d905f908e908e908e908e9085906004016139fa565b5f604051808303815f87803b158015610769575f80fd5b505af115801561077b573d5f803e3d5ffd5b505050507ff7f893fb8cda745632d6c27ec518a84338faeb6dbc795efb4cd00d29638610b38a6040516107b091815260200190565b60405180910390a150506107c360015f55565b5050505050505050565b6004546001600160a01b031633146108275760405162461bcd60e51b815260206004820152601860248201527f7365744f726465724d67723a206e6f7420616c6c6f776564000000000000000060448201526064016102df565b6001600160a01b0381166108895760405162461bcd60e51b8152602060048201526024808201527f7365744f726465724d67723a20696e76616c6964206f726465724d67724164646044820152637265737360e01b60648201526084016102df565b600580546001600160a01b039092166001600160a01b0319928316811790915560068054909216179055565b6108bd6132b1565b5f5b82518110156109ee575f8382815181106108db576108db613a86565b602090810291909101015160065460405163d09ef24160e01b8152600481018390529192506001600160a01b03169063d09ef241906024016101e060405180830381865afa15801561092f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610953919061388b565b8051604001519093506001600160a01b031661096f57506109e6565b8251610160015115156001036109b457600183516101000151600381111561099957610999613a4b565b036109a457506109e6565b6109ae8382611931565b506109e4565b5f8351610100015160038111156109cd576109cd613a4b565b146109d857506109e6565b6109e28382611960565b505b505b6001016108bf565b505050565b6109fb6117ff565b60065460405163d09ef24160e01b81526004810189905288915f916001600160a01b039091169063d09ef241906024016101e060405180830381865afa158015610a47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a6b919061388b565b8051519091506001600160a01b03163314610a985760405162461bcd60e51b81526004016102df90613995565b8051610160015115610abc5760405162461bcd60e51b81526004016102df906139cc565b5f815161010001516003811115610ad557610ad5613a4b565b14610b1b5760405162461bcd60e51b8152602060048201526016602482015275496e636f7272656374206f726465722073746174757360501b60448201526064016102df565b805160a0015115610b6e5780516101200151335f90815260016020908152604080832085518301516001600160a01b0316845290915281208054909190610b63908490613a73565b90915550610bb19050565b80516101200151335f90815260016020908152604080832085518201516001600160a01b0316845290915281208054909190610bab908490613a73565b90915550505b610bbd88888787611856565b610bd95760405162461bcd60e51b81526004016102df906137c2565b600654604051635585b19360e01b81526001600160a01b0390911690635585b19390610c1b908c908c908c908b908d905f9081908e908e9083906004016139fa565b5f604051808303815f87803b158015610c32575f80fd5b505af1158015610c44573d5f803e3d5ffd5b505050507ff7f893fb8cda745632d6c27ec518a84338faeb6dbc795efb4cd00d29638610b389604051610c7991815260200190565b60405180910390a15050610c8c60015f55565b50505050505050565b610c9d6117ff565b60065460405163d6f35bd560e01b81525f916001600160a01b03169063d6f35bd590610cdf9033908c908c908c908c90899081908e908e908e90600401613a9a565b6020604051808303815f875af1158015610cfb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d1f919061383d565b90507ff40951d004ae9ba03a1b52a13452626d3bbb2cd7a662dab67f84e8b564a9a06781604051610d5291815260200190565b60405180910390a150610c8c60015f55565b60065460405163d09ef24160e01b8152600481018390525f916001600160a01b03169063d09ef241906024016101e060405180830381865afa158015610dac573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dd0919061388b565b8051519091506001600160a01b03163314610dfd5760405162461bcd60e51b81526004016102df90613995565b60065460405163514fcac760e01b8152600481018490526001600160a01b039091169063514fcac7906024016020604051808303815f875af1158015610e45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e69919061383d565b5080516101600151610f0b57805160a0015115610ec85780516101200151335f90815260016020908152604080832085518301516001600160a01b0316845290915281208054909190610ebd908490613a73565b90915550610f0b9050565b80516101200151335f90815260016020908152604080832085518201516001600160a01b0316845290915281208054909190610f05908490613a73565b90915550505b6040518281527fc41f4ceb2938876c35e61b705e9d2f18a02c4a26ce5e049a6308a943d46851b39060200160405180910390a15050565b610f4a6117ff565b60065460405163d6f35bd560e01b81525f916001600160a01b03169063d6f35bd590610f8c9033908d908d908d9088908e908e908e908e908e90600401613a9a565b6020604051808303815f875af1158015610fa8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fcc919061383d565b90507ff40951d004ae9ba03a1b52a13452626d3bbb2cd7a662dab67f84e8b564a9a06781604051610fff91815260200190565b60405180910390a1506107c360015f55565b6004546001600160a01b031633146110575760405162461bcd60e51b81526020600482015260096024820152682737ba1030b236b4b760b91b60448201526064016102df565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f57a2989fbcdc251cf10758ea804ebbbd61e9da58a859d3fbf6bcfdd9c31bec7e9060200160405180910390a150565b6110b36117ff565b6110bf87878785611856565b6110db5760405162461bcd60e51b81526004016102df906137c2565b600654604051630d570f1560e31b81525f916001600160a01b031690636ab878a89061111b9033908c908c908c9088908d908d908d908d906004016137ed565b6020604051808303815f875af1158015611137573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061115b919061383d565b90507f7ae91fe4742a77fb791e82e77c1b02800bd8fc0829aab88c2f0c1f5009a8d76581604051610d5291815260200190565b60065460405163d09ef24160e01b8152600481018a90525f916001600160a01b03169063d09ef241906024016101e060405180830381865afa1580156111d6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111fa919061388b565b8051519091506001600160a01b031633146112275760405162461bcd60e51b81526004016102df90613995565b80516101600151151560011461124f5760405162461bcd60e51b81526004016102df906139cc565b600654604051635585b19360e01b81526001600160a01b0390911690635585b19390611291908c908c908c908c908c905f9081908e908e908e906004016139fa565b5f604051808303815f87803b1580156112a8575f80fd5b505af11580156112ba573d5f803e3d5ffd5b505050507ff6889aa0780be70c770f893999b0adcc2cd01470d2ee0b90f706c5077d93e56b896040516112ef91815260200190565b60405180910390a1505050505050505050565b61130a6117ff565b5f81116113595760405162461bcd60e51b815260206004820181905260248201527f416d6f756e74206d7573742062652067726561746572207468616e207a65726f60448201526064016102df565b6040516370a0823160e01b815230600482015282905f906001600160a01b038316906370a0823190602401602060405180830381865afa15801561139f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113c3919061383d565b6040516323b872dd60e01b8152336004820152306024820152604481018590529091506001600160a01b038316906323b872dd906064016020604051808303815f875af1158015611416573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061143a9190613af0565b6114785760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016102df565b6040516370a0823160e01b81523060048201525f9082906001600160a01b038516906370a0823190602401602060405180830381865afa1580156114be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114e2919061383d565b6114ec9190613b0b565b6001600160a01b0386165f9081527f5ccfe41675d26c0b329bf9933f52391aedcc25e23489342bbaefda128a9973d56020526040812080549293508392909190611537908490613a73565b9091555050335f9081526001602090815260408083206001600160a01b03891684529091528120805483929061156e908490613a73565b909155505060015f5550611580915050565b5050565b61158c6117ff565b5f81116115db5760405162461bcd60e51b815260206004820181905260248201527f416d6f756e74206d7573742062652067726561746572207468616e207a65726f60448201526064016102df565b335f9081526001602090815260408083206001600160a01b03861684529091529020548111156116445760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b60448201526064016102df565b335f9081526001602090815260408083206001600160a01b038616845290915281208054839290611676908490613b0b565b909155505060405163a9059cbb60e01b81523360048201526024810182905282906001600160a01b0382169063a9059cbb906044016020604051808303815f875af11580156116c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116eb9190613af0565b6117295760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016102df565b604080513381526001600160a01b03851660208201529081018390527fa92ff919b850e4909ab2261d907ef955f11bc1716733a6cbece38d163a69af8a9060600160405180910390a15061158060015f55565b5f80826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117de9190613b1e565b6117e990600a613c0f565b90505f6117f68483611d03565b50949350505050565b60025f54036118505760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102df565b60025f55565b5f82156118ca57335f9081526001602090815260408083206001600160a01b038916845290915290205482116118c357335f9081526001602090815260408083206001600160a01b0389168452909152812080548492906118b8908490613b0b565b909155506119259050565b505f611929565b335f9081526001602090815260408083206001600160a01b038816845290915290205482116118c357335f9081526001602090815260408083206001600160a01b0388168452909152812080548492906118b8908490613b0b565b5060015b949350505050565b8151608001515f90810361195057611949838361200c565b905061195a565b6119498383612542565b92915050565b5f805f6119e5855f015160400151865f0151604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119b1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119d59190613b1e565b6119e090600a613c0f565b611d03565b9150915080611a2c576040518481527fbf641aa67d51d72628240e9ac2c9f36cf8c9ec37d043d89382355fe67132e66e906020015b60405180910390a15f9250505061195a565b5f80808060018951606001516001811115611a4957611a49613a4b565b03611aad57885160e00151861080611a655750885160c0015186115b15611aad57885160a00151604080518a8152911515602083015281018790525f80516020613db6833981519152906060015b60405180910390a15f965050505050505061195a565b885160a0015115611b2a575f8951606001516001811115611ad057611ad0613a4b565b03611b1357885160800151861115611b1357885160a00151604080518a8152911515602083015281018790525f80516020613db683398151915290606001611a97565b885160208101516040909101519094509250611b98565b5f8951606001516001811115611b4257611b42613a4b565b03611b8557885160800151861015611b8557885160a00151604080518a8152911515602083015281018790525f80516020613db683398151915290606001611a97565b8851604081015160209091015190945092505b88516020810151604082015160a083015161012084015161014090940151611bc09490612bfb565b90925090508015611cd3578851516001600160a01b039081165f90815260016020908152604080832093871683529290529081208054849290611c04908490613a73565b9091555050600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee90611c3c908b90600390600401613c1d565b5f604051808303815f87803b158015611c53575f80fd5b505af1158015611c65573d5f803e3d5ffd5b50508a5160a08082015161012090920151604080518e8152931515602085015283015260608201869052608082018a90527fd3a2a38532d8ebbcacfb7f0283c81c80740d96318a247267aa64e7ac0a75a57c935001905060405180910390a16001965050505050505061195a565b6040518881527ff9e10ddceffcb10b96e8833202366240699b814c91f371ddd9befa3aee9bc60f90602001611a97565b5f80611d2373a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488561316e565b15611dd9576040805160028082526060820183525f9260208301908036833701905050905084815f81518110611d5b57611d5b613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881600181518110611da357611da3613a86565b60200260200101906001600160a01b031690816001600160a01b031681525050611dcd8185613208565b60019250925050612005565b611df773c28ab4e347dd26c5809540e7db0cea473d91439c8561316e565b15611e77576040805160028082526060820183525f9260208301908036833701905050905084815f81518110611e2f57611e2f613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073c28ab4e347dd26c5809540e7db0cea473d91439c81600181518110611da357611da3613a86565b611e9573c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28561316e565b15611f5f57604080516003808252608082019092525f916020820160608036833701905050905084815f81518110611ecf57611ecf613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110611f1757611f17613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881600281518110611da357611da3613a86565b611f7d73c5fb36dd2fb59d3b98deff88425a3f425ee469ed8561316e565b15611fff57604080516003808252608082019092525f916020820160608036833701905050905084815f81518110611fb757611fb7613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073c5fb36dd2fb59d3b98deff88425a3f425ee469ed81600181518110611f1757611f17613a86565b505f9050805b9250929050565b5f805f61205d855f015160400151865f0151604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119b1573d5f803e3d5ffd5b9150915080612096576040518481527fbf641aa67d51d72628240e9ac2c9f36cf8c9ec37d043d89382355fe67132e66e90602001611a1a565b84606001511561244957845160e001518210806120b75750845160c0015182115b156120ed57845160a0015160408051868152911515602083015281018390525f80516020613db683398151915290606001611a1a565b5f805f80885f015160a001511561211557885160208101516040909101519094509250612128565b8851604081015160209091015190945092505b885161012081015190516001600160a01b039081165f90815260016020908152604080832093891683529290522054106123a65788516020810151604082015160a0830151610120840151610140909401516121849490612bfb565b90925090508015612376578851516001600160a01b039081165f908152600160209081526040808320938716835292905290812080548492906121c8908490613a73565b9091555050885161012081015190516001600160a01b039081165f9081526001602090815260408083209389168352929052908120805490919061220d908490613b0b565b9091555050600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee90612244908b905f90600401613c1d565b5f604051808303815f87803b15801561225b575f80fd5b505af115801561226d573d5f803e3d5ffd5b5050600654604051620b79f560ea1b8152600481018c90526001600160a01b039091169250632de7d40091506024015f604051808303815f87803b1580156122b3575f80fd5b505af11580156122c5573d5f803e3d5ffd5b5050600654604051635281b98160e01b8152600481018c90525f60248201526001600160a01b039091169250635281b98191506044015f604051808303815f87803b158015612312575f80fd5b505af1158015612324573d5f803e3d5ffd5b50508a5160a00151604080518c8152911515602083015281018990527febd85f6b4646b253274fd876529f3b004db9b6f2cb17401ef4afd75f45f4ff23925060600190505b60405180910390a1612440565b6040518881527ff9e10ddceffcb10b96e8833202366240699b814c91f371ddd9befa3aee9bc60f90602001612369565b600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee906123d9908b90600290600401613c1d565b5f604051808303815f87803b1580156123f0575f80fd5b505af1158015612402573d5f803e3d5ffd5b505050507f12479fe7346119b9d7b9e673759d5824b3523f69848c8b04d4c7d0e3f194a47f8860405161243791815260200190565b60405180910390a15b50505050611925565b5f60648660400151875f015160e001516124639190613c4d565b61246d9190613c64565b90505f60648760400151885f015160c001516124899190613c4d565b6124939190613c64565b875160e001519091506124a7908390613b0b565b841180156124c45750865160c001516124c1908290613a73565b84105b156124d5575f94505050505061195a565b600654604051635281b98160e01b815260048101889052600160248201526001600160a01b0390911690635281b981906044015f604051808303815f87803b15801561251f575f80fd5b505af1158015612531573d5f803e3d5ffd5b505050505050506001949350505050565b5f805f612593855f015160400151865f0151604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119b1573d5f803e3d5ffd5b91509150806125cc576040518481527fbf641aa67d51d72628240e9ac2c9f36cf8c9ec37d043d89382355fe67132e66e90602001611a1a565b845160a0015115612a03578460600151156129535784516080015182111561261f57845160a0015160408051868152911515602083015281018390525f80516020613db683398151915290606001611a1a565b845161012081015190516001600160a01b039081165f9081526001602090815260408083208a5183015190941683529290529081205490918291106128b25786516020810151604082015160a0830151610120840151610140909401516126869490612bfb565b90925090508015612882578651516001600160a01b039081165f9081526001602090815260408083208b51820151909416835292905290812080548492906126cf908490613a73565b9091555050865161012081015190516001600160a01b039081165f9081526001602090815260408083208c5183015190941683529290529081208054909190612719908490613b0b565b9091555050600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee906127509089905f90600401613c1d565b5f604051808303815f87803b158015612767575f80fd5b505af1158015612779573d5f803e3d5ffd5b5050600654604051620b79f560ea1b8152600481018a90526001600160a01b039091169250632de7d40091506024015f604051808303815f87803b1580156127bf575f80fd5b505af11580156127d1573d5f803e3d5ffd5b5050600654604051635281b98160e01b8152600481018a90525f60248201526001600160a01b039091169250635281b98191506044015f604051808303815f87803b15801561281e575f80fd5b505af1158015612830573d5f803e3d5ffd5b5050885160a00151604080518a8152911515602083015281018790527febd85f6b4646b253274fd876529f3b004db9b6f2cb17401ef4afd75f45f4ff23925060600190505b60405180910390a161294c565b6040518681527ff9e10ddceffcb10b96e8833202366240699b814c91f371ddd9befa3aee9bc60f90602001612875565b600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee906128e5908990600290600401613c1d565b5f604051808303815f87803b1580156128fc575f80fd5b505af115801561290e573d5f803e3d5ffd5b505050507f12479fe7346119b9d7b9e673759d5824b3523f69848c8b04d4c7d0e3f194a47f8660405161294391815260200190565b60405180910390a15b5050611925565b5f60648660400151875f01516080015161296d9190613c4d565b6129779190613c64565b86516080015190915061298b908290613a73565b83101561299d575f935050505061195a565b600654604051635281b98160e01b815260048101879052600160248201526001600160a01b0390911690635281b981906044015f604051808303815f87803b1580156129e7575f80fd5b505af11580156129f9573d5f803e3d5ffd5b5050505050611925565b846060015115612b4557845160800151821015612a4b57845160a0015160408051868152911515602083015281018390525f80516020613db683398151915290606001611a1a565b845161012081015190516001600160a01b039081165f9081526001602090815260408083208a5182015190941683529290529081205490918291106128b25786516020810151604082015160a083015161012084015161014090940151612ab29490612bfb565b90925090508015612882578651516001600160a01b039081165f9081526001602090815260408083208b5183015190941683529290529081208054849290612afb908490613a73565b9091555050865161012081015190516001600160a01b039081165f9081526001602090815260408083208c5182015190941683529290529081208054909190612719908490613b0b565b5f60648660400151875f015160800151612b5f9190613c4d565b612b699190613c64565b865160800151909150612b7d908290613b0b565b831115612b8f575f935050505061195a565b600654604051635281b98160e01b815260048101879052600160248201526001600160a01b0390911690635281b981906044015f604051808303815f87803b158015612bd9575f80fd5b505af1158015612beb573d5f803e3d5ffd5b5060019998505050505050505050565b5f805f805f8715612c1157899250889150612c18565b8892508991505b612c228a8a61316e565b612e08576001600160a01b038a1673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214801590612c6c5750612c6c73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a61316e565b15612c8c575073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612e08565b6001600160a01b038a1673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4814801590612cd25750612cd273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488a61316e565b15612cf2575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48612e08565b6001600160a01b038a1673c28ab4e347dd26c5809540e7db0cea473d91439c14801590612d385750612d3873c28ab4e347dd26c5809540e7db0cea473d91439c8a61316e565b15612d58575073c28ab4e347dd26c5809540e7db0cea473d91439c612e08565b6001600160a01b038a1673c5fb36dd2fb59d3b98deff88425a3f425ee469ed14801590612da257506001600160a01b03891673c5fb36dd2fb59d3b98deff88425a3f425ee469ed14155b8015612dc75750612dc773c5fb36dd2fb59d3b98deff88425a3f425ee469ed8b61316e565b8015612dec5750612dec73c5fb36dd2fb59d3b98deff88425a3f425ee469ed8a61316e565b15612e08575073c5fb36dd2fb59d3b98deff88425a3f425ee469ed5b60025460405163095ea7b360e01b81526001600160a01b03918216600482015260248101899052849182169063095ea7b3906044016020604051808303815f875af1158015612e59573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e7d9190613af0565b506040516370a0823160e01b81523060048201525f906001600160a01b038516906370a0823190602401602060405180830381865afa158015612ec2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ee6919061383d565b90506001600160a01b038316612fd5576040805160028082526060820183525f9260208301908036833701905050905085815f81518110612f2957612f29613a86565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600181518110612f5d57612f5d613a86565b6001600160a01b039283166020918202929092010152600254604051635c11d79560e01b8152911690635c11d79590612fa2908d908d90869030904290600401613cc6565b5f604051808303815f87803b158015612fb9575f80fd5b505af1158015612fcb573d5f803e3d5ffd5b50505050506130e6565b604080516003808252608082019092525f916020820160608036833701905050905085815f8151811061300a5761300a613a86565b60200260200101906001600160a01b031690816001600160a01b031681525050838160018151811061303e5761303e613a86565b60200260200101906001600160a01b031690816001600160a01b031681525050848160028151811061307257613072613a86565b6001600160a01b039283166020918202929092010152600254604051635c11d79560e01b8152911690635c11d795906130b7908d908d90869030904290600401613cc6565b5f604051808303815f87803b1580156130ce575f80fd5b505af11580156130e0573d5f803e3d5ffd5b50505050505b6040516370a0823160e01b81523060048201525f9082906001600160a01b038716906370a0823190602401602060405180830381865afa15801561312c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613150919061383d565b61315a9190613b0b565b9d60019d509b505050505050505050505050565b60035460405163e6a4390560e01b81526001600160a01b03848116600483015283811660248301525f92839291169063e6a4390590604401602060405180830381865afa1580156131c1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131e59190613d01565b90506001600160a01b0381166131fe575f91505061195a565b600191505061195a565b60025460405163d06ca61f60e01b81525f9182916001600160a01b039091169063d06ca61f9061323e9086908890600401613d1c565b5f60405180830381865afa158015613258573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261327f9190810190613d34565b905080600185516132909190613b0b565b815181106132a0576132a0613a86565b602002602001015191505092915050565b60405180608001604052806132c46132de565b81526020015f81526020015f81526020015f151581525090565b60408051610180810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052906101008201906132c4565b6001600160a01b038116811461333d575f80fd5b50565b801515811461333d575f80fd5b5f805f805f8060c08789031215613362575f80fd5b863561336d81613329565b9550602087013561337d81613329565b9450604087013561338d81613340565b959894975094956060810135955060808101359460a0909101359350915050565b5f805f805f805f805f6101208a8c0312156133c7575f80fd5b8935985060208a01356133d981613329565b975060408a01356133e981613329565b965060608a01356133f981613340565b989b979a50959860808101359760a0820135975060c0820135965060e08201359550610100909101359350915050565b5f805f805f805f80610100898b031215613441575f80fd5b88359750602089013561345381613329565b9650604089013561346381613329565b9550606089013561347381613340565b979a969950949760808101359660a0820135965060c0820135955060e0909101359350915050565b5f602082840312156134ab575f80fd5b81356134b681613329565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b6040516080810167ffffffffffffffff811182821017156134f4576134f46134bd565b60405290565b604051610180810167ffffffffffffffff811182821017156134f4576134f46134bd565b604051601f8201601f1916810167ffffffffffffffff81118282101715613547576135476134bd565b604052919050565b5f67ffffffffffffffff821115613568576135686134bd565b5060051b60200190565b5f6020808385031215613583575f80fd5b823567ffffffffffffffff811115613599575f80fd5b8301601f810185136135a9575f80fd5b80356135bc6135b78261354f565b61351e565b81815260059190911b820183019083810190878311156135da575f80fd5b928401925b828410156135f8578335825292840192908401906135df565b979650505050505050565b5f805f805f805f60e0888a031215613619575f80fd5b87359650602088013561362b81613329565b9550604088013561363b81613329565b945060608801359350608088013561365281613340565b9699959850939692959460a0840135945060c09093013592915050565b5f805f805f805f60e0888a031215613685575f80fd5b873561369081613329565b965060208801356136a081613329565b955060408801356136b081613340565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b5f602082840312156136e8575f80fd5b5035919050565b5f805f805f805f80610100898b031215613707575f80fd5b883561371281613329565b9750602089013561372281613329565b9650604089013561373281613340565b979a96995096976060810135975060808101359660a0820135965060c0820135955060e0909101359350915050565b5f8060408385031215613772575f80fd5b823561377d81613329565b946020939093013593505050565b5f806040838503121561379c575f80fd5b82356137a781613329565b915060208301356137b781613329565b809150509250929050565b60208082526011908201527015985b1a59185d1a5bdb8819985a5b1959607a1b604082015260600190565b6001600160a01b03998a16815297891660208901529590971660408701529215156060860152608085019190915260a084015260c083015260e08201929092526101008101919091526101200190565b5f6020828403121561384d575f80fd5b5051919050565b805161385f81613329565b919050565b80516002811061385f575f80fd5b805161385f81613340565b80516004811061385f575f80fd5b5f8183036101e081121561389d575f80fd5b6138a56134d1565b610180808312156138b4575f80fd5b6138bc6134fa565b92506138c785613854565b83526138d560208601613854565b60208401526138e660408601613854565b60408401526138f760608601613864565b60608401526080850151608084015261391260a08601613872565b60a084015260c085015160c084015260e085015160e084015261010061393981870161387d565b9084015261012085810151908401526101408086015190840152610160613961818701613872565b9084015282825284015160208201526101a084015160408201526139886101c08501613872565b6060820152949350505050565b6020808252601d908201527f6d73672e73656e646572206973206e6f74206f72646572206f776e6572000000604082015260600190565b602080825260149082015273496e636f7272656374206f72646572207479706560601b604082015260600190565b998a526001600160a01b0398891660208b01529690971660408901529315156060880152608087019290925260a086015260c085015260e08401526101008301919091526101208201526101400190565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082018082111561195a5761195a613a5f565b634e487b7160e01b5f52603260045260245ffd5b6001600160a01b039a8b168152988a1660208a01529690981660408801529315156060870152608086019290925260a085015260c084015260e08301526101008201929092526101208101919091526101400190565b5f60208284031215613b00575f80fd5b81516134b681613340565b8181038181111561195a5761195a613a5f565b5f60208284031215613b2e575f80fd5b815160ff811681146134b6575f80fd5b600181815b80851115613b7857815f1904821115613b5e57613b5e613a5f565b80851615613b6b57918102915b93841c9390800290613b43565b509250929050565b5f82613b8e5750600161195a565b81613b9a57505f61195a565b81600181146131fe5760028103613bc75760ff841115613bbc57613bbc613a5f565b50506001821b61195a565b5060208310610133831016604e8410600b8410161715613bea575081810a61195a565b613bf48383613b3e565b805f1904821115613c0757613c07613a5f565b029392505050565b5f6134b660ff841683613b80565b8281526040810160048310613c4057634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b808202811582820484141761195a5761195a613a5f565b5f82613c7e57634e487b7160e01b5f52601260045260245ffd5b500490565b5f815180845260208085019450602084015f5b83811015613cbb5781516001600160a01b031687529582019590820190600101613c96565b509495945050505050565b85815284602082015260a060408201525f613ce460a0830186613c83565b6001600160a01b0394909416606083015250608001529392505050565b5f60208284031215613d11575f80fd5b81516134b681613329565b828152604060208201525f6119296040830184613c83565b5f6020808385031215613d45575f80fd5b825167ffffffffffffffff811115613d5b575f80fd5b8301601f81018513613d6b575f80fd5b8051613d796135b78261354f565b81815260059190911b82018301908381019087831115613d97575f80fd5b928401925b828410156135f857835182529284019290840190613d9c56fe376cc40e122623406a50cd32e6ec71ccc664eb3ea2107e8db1822d3b9cfac54aa2646970667358221220e7db3c915cc5cff796847397344661ba0e61139affa768e1ea03cde007d94fcb64736f6c63430008170033
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610111575f3560e01c80635d58b7561161009e578063bc4b33651161006e578063bc4b33651461022b578063c10753291461023e578063c23f001f14610251578063d02641a014610289578063f77d46311461029c575f80fd5b80635d58b756146101df578063754dea40146101f25780637720f717146102055780638bd4185814610218575f80fd5b806338800428116100e4578063388004281461016357806341929f0f14610193578063441106c9146101a6578063452c4875146101b9578063514fcac7146101cc575f80fd5b80630848a3c7146101155780630d48317b1461012a578063209f90c31461013d5780632b0b066214610150575b5f80fd5b61012861012336600461334d565b6102af565b005b6101286101383660046133ae565b6103b5565b61012861014b366004613429565b61052a565b61012861015e36600461349b565b6107cd565b600554610176906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101286101a1366004613572565b6108b5565b6101286101b4366004613603565b6109f3565b6101286101c736600461366f565b610c95565b6101286101da3660046136d8565b610d64565b6101286101ed3660046136ef565b610f42565b61012861020036600461349b565b611011565b61012861021336600461366f565b6110ab565b610128610226366004613429565b61118e565b610128610239366004613761565b611302565b61012861024c366004613761565b611584565b61027b61025f36600461378b565b600160209081525f928352604080842090915290825290205481565b60405190815260200161018a565b61027b61029736600461349b565b61177c565b600454610176906001600160a01b031681565b6102b76117ff565b6102c386868685611856565b6102e85760405162461bcd60e51b81526004016102df906137c2565b60405180910390fd5b600654604051630d570f1560e31b81525f916001600160a01b031690636ab878a8906103289033908b908b908b908b90899081908d908d906004016137ed565b6020604051808303815f875af1158015610344573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610368919061383d565b90507f7ae91fe4742a77fb791e82e77c1b02800bd8fc0829aab88c2f0c1f5009a8d7658160405161039b91815260200190565b60405180910390a1506103ad60015f55565b505050505050565b60065460405163d09ef24160e01b8152600481018b90525f916001600160a01b03169063d09ef241906024016101e060405180830381865afa1580156103fd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610421919061388b565b8051519091506001600160a01b0316331461044e5760405162461bcd60e51b81526004016102df90613995565b8051610160015115156001146104765760405162461bcd60e51b81526004016102df906139cc565b600654604051635585b19360e01b81526001600160a01b0390911690635585b193906104b8908d908d908d908d905f908e908e908e908e908e906004016139fa565b5f604051808303815f87803b1580156104cf575f80fd5b505af11580156104e1573d5f803e3d5ffd5b505050507ff6889aa0780be70c770f893999b0adcc2cd01470d2ee0b90f706c5077d93e56b8a60405161051691815260200190565b60405180910390a150505050505050505050565b6105326117ff565b60065460405163d09ef24160e01b8152600481018a905289915f916001600160a01b039091169063d09ef241906024016101e060405180830381865afa15801561057e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a2919061388b565b8051519091506001600160a01b031633146105cf5760405162461bcd60e51b81526004016102df90613995565b80516101600151156105f35760405162461bcd60e51b81526004016102df906139cc565b5f81516101000151600381111561060c5761060c613a4b565b146106525760405162461bcd60e51b8152602060048201526016602482015275496e636f7272656374206f726465722073746174757360501b60448201526064016102df565b805160a00151156106a55780516101200151335f90815260016020908152604080832085518301516001600160a01b031684529091528120805490919061069a908490613a73565b909155506106e89050565b80516101200151335f90815260016020908152604080832085518201516001600160a01b03168452909152812080549091906106e2908490613a73565b90915550505b6106f489898987611856565b6107105760405162461bcd60e51b81526004016102df906137c2565b600654604051635585b19360e01b81526001600160a01b0390911690635585b19390610752908d908d908d908d905f908e908e908e908e9085906004016139fa565b5f604051808303815f87803b158015610769575f80fd5b505af115801561077b573d5f803e3d5ffd5b505050507ff7f893fb8cda745632d6c27ec518a84338faeb6dbc795efb4cd00d29638610b38a6040516107b091815260200190565b60405180910390a150506107c360015f55565b5050505050505050565b6004546001600160a01b031633146108275760405162461bcd60e51b815260206004820152601860248201527f7365744f726465724d67723a206e6f7420616c6c6f776564000000000000000060448201526064016102df565b6001600160a01b0381166108895760405162461bcd60e51b8152602060048201526024808201527f7365744f726465724d67723a20696e76616c6964206f726465724d67724164646044820152637265737360e01b60648201526084016102df565b600580546001600160a01b039092166001600160a01b0319928316811790915560068054909216179055565b6108bd6132b1565b5f5b82518110156109ee575f8382815181106108db576108db613a86565b602090810291909101015160065460405163d09ef24160e01b8152600481018390529192506001600160a01b03169063d09ef241906024016101e060405180830381865afa15801561092f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610953919061388b565b8051604001519093506001600160a01b031661096f57506109e6565b8251610160015115156001036109b457600183516101000151600381111561099957610999613a4b565b036109a457506109e6565b6109ae8382611931565b506109e4565b5f8351610100015160038111156109cd576109cd613a4b565b146109d857506109e6565b6109e28382611960565b505b505b6001016108bf565b505050565b6109fb6117ff565b60065460405163d09ef24160e01b81526004810189905288915f916001600160a01b039091169063d09ef241906024016101e060405180830381865afa158015610a47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a6b919061388b565b8051519091506001600160a01b03163314610a985760405162461bcd60e51b81526004016102df90613995565b8051610160015115610abc5760405162461bcd60e51b81526004016102df906139cc565b5f815161010001516003811115610ad557610ad5613a4b565b14610b1b5760405162461bcd60e51b8152602060048201526016602482015275496e636f7272656374206f726465722073746174757360501b60448201526064016102df565b805160a0015115610b6e5780516101200151335f90815260016020908152604080832085518301516001600160a01b0316845290915281208054909190610b63908490613a73565b90915550610bb19050565b80516101200151335f90815260016020908152604080832085518201516001600160a01b0316845290915281208054909190610bab908490613a73565b90915550505b610bbd88888787611856565b610bd95760405162461bcd60e51b81526004016102df906137c2565b600654604051635585b19360e01b81526001600160a01b0390911690635585b19390610c1b908c908c908c908b908d905f9081908e908e9083906004016139fa565b5f604051808303815f87803b158015610c32575f80fd5b505af1158015610c44573d5f803e3d5ffd5b505050507ff7f893fb8cda745632d6c27ec518a84338faeb6dbc795efb4cd00d29638610b389604051610c7991815260200190565b60405180910390a15050610c8c60015f55565b50505050505050565b610c9d6117ff565b60065460405163d6f35bd560e01b81525f916001600160a01b03169063d6f35bd590610cdf9033908c908c908c908c90899081908e908e908e90600401613a9a565b6020604051808303815f875af1158015610cfb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d1f919061383d565b90507ff40951d004ae9ba03a1b52a13452626d3bbb2cd7a662dab67f84e8b564a9a06781604051610d5291815260200190565b60405180910390a150610c8c60015f55565b60065460405163d09ef24160e01b8152600481018390525f916001600160a01b03169063d09ef241906024016101e060405180830381865afa158015610dac573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dd0919061388b565b8051519091506001600160a01b03163314610dfd5760405162461bcd60e51b81526004016102df90613995565b60065460405163514fcac760e01b8152600481018490526001600160a01b039091169063514fcac7906024016020604051808303815f875af1158015610e45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e69919061383d565b5080516101600151610f0b57805160a0015115610ec85780516101200151335f90815260016020908152604080832085518301516001600160a01b0316845290915281208054909190610ebd908490613a73565b90915550610f0b9050565b80516101200151335f90815260016020908152604080832085518201516001600160a01b0316845290915281208054909190610f05908490613a73565b90915550505b6040518281527fc41f4ceb2938876c35e61b705e9d2f18a02c4a26ce5e049a6308a943d46851b39060200160405180910390a15050565b610f4a6117ff565b60065460405163d6f35bd560e01b81525f916001600160a01b03169063d6f35bd590610f8c9033908d908d908d9088908e908e908e908e908e90600401613a9a565b6020604051808303815f875af1158015610fa8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fcc919061383d565b90507ff40951d004ae9ba03a1b52a13452626d3bbb2cd7a662dab67f84e8b564a9a06781604051610fff91815260200190565b60405180910390a1506107c360015f55565b6004546001600160a01b031633146110575760405162461bcd60e51b81526020600482015260096024820152682737ba1030b236b4b760b91b60448201526064016102df565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f57a2989fbcdc251cf10758ea804ebbbd61e9da58a859d3fbf6bcfdd9c31bec7e9060200160405180910390a150565b6110b36117ff565b6110bf87878785611856565b6110db5760405162461bcd60e51b81526004016102df906137c2565b600654604051630d570f1560e31b81525f916001600160a01b031690636ab878a89061111b9033908c908c908c9088908d908d908d908d906004016137ed565b6020604051808303815f875af1158015611137573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061115b919061383d565b90507f7ae91fe4742a77fb791e82e77c1b02800bd8fc0829aab88c2f0c1f5009a8d76581604051610d5291815260200190565b60065460405163d09ef24160e01b8152600481018a90525f916001600160a01b03169063d09ef241906024016101e060405180830381865afa1580156111d6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111fa919061388b565b8051519091506001600160a01b031633146112275760405162461bcd60e51b81526004016102df90613995565b80516101600151151560011461124f5760405162461bcd60e51b81526004016102df906139cc565b600654604051635585b19360e01b81526001600160a01b0390911690635585b19390611291908c908c908c908c908c905f9081908e908e908e906004016139fa565b5f604051808303815f87803b1580156112a8575f80fd5b505af11580156112ba573d5f803e3d5ffd5b505050507ff6889aa0780be70c770f893999b0adcc2cd01470d2ee0b90f706c5077d93e56b896040516112ef91815260200190565b60405180910390a1505050505050505050565b61130a6117ff565b5f81116113595760405162461bcd60e51b815260206004820181905260248201527f416d6f756e74206d7573742062652067726561746572207468616e207a65726f60448201526064016102df565b6040516370a0823160e01b815230600482015282905f906001600160a01b038316906370a0823190602401602060405180830381865afa15801561139f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113c3919061383d565b6040516323b872dd60e01b8152336004820152306024820152604481018590529091506001600160a01b038316906323b872dd906064016020604051808303815f875af1158015611416573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061143a9190613af0565b6114785760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016102df565b6040516370a0823160e01b81523060048201525f9082906001600160a01b038516906370a0823190602401602060405180830381865afa1580156114be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114e2919061383d565b6114ec9190613b0b565b6001600160a01b0386165f9081527f5ccfe41675d26c0b329bf9933f52391aedcc25e23489342bbaefda128a9973d56020526040812080549293508392909190611537908490613a73565b9091555050335f9081526001602090815260408083206001600160a01b03891684529091528120805483929061156e908490613a73565b909155505060015f5550611580915050565b5050565b61158c6117ff565b5f81116115db5760405162461bcd60e51b815260206004820181905260248201527f416d6f756e74206d7573742062652067726561746572207468616e207a65726f60448201526064016102df565b335f9081526001602090815260408083206001600160a01b03861684529091529020548111156116445760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b60448201526064016102df565b335f9081526001602090815260408083206001600160a01b038616845290915281208054839290611676908490613b0b565b909155505060405163a9059cbb60e01b81523360048201526024810182905282906001600160a01b0382169063a9059cbb906044016020604051808303815f875af11580156116c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116eb9190613af0565b6117295760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016102df565b604080513381526001600160a01b03851660208201529081018390527fa92ff919b850e4909ab2261d907ef955f11bc1716733a6cbece38d163a69af8a9060600160405180910390a15061158060015f55565b5f80826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117de9190613b1e565b6117e990600a613c0f565b90505f6117f68483611d03565b50949350505050565b60025f54036118505760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102df565b60025f55565b5f82156118ca57335f9081526001602090815260408083206001600160a01b038916845290915290205482116118c357335f9081526001602090815260408083206001600160a01b0389168452909152812080548492906118b8908490613b0b565b909155506119259050565b505f611929565b335f9081526001602090815260408083206001600160a01b038816845290915290205482116118c357335f9081526001602090815260408083206001600160a01b0388168452909152812080548492906118b8908490613b0b565b5060015b949350505050565b8151608001515f90810361195057611949838361200c565b905061195a565b6119498383612542565b92915050565b5f805f6119e5855f015160400151865f0151604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119b1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119d59190613b1e565b6119e090600a613c0f565b611d03565b9150915080611a2c576040518481527fbf641aa67d51d72628240e9ac2c9f36cf8c9ec37d043d89382355fe67132e66e906020015b60405180910390a15f9250505061195a565b5f80808060018951606001516001811115611a4957611a49613a4b565b03611aad57885160e00151861080611a655750885160c0015186115b15611aad57885160a00151604080518a8152911515602083015281018790525f80516020613db6833981519152906060015b60405180910390a15f965050505050505061195a565b885160a0015115611b2a575f8951606001516001811115611ad057611ad0613a4b565b03611b1357885160800151861115611b1357885160a00151604080518a8152911515602083015281018790525f80516020613db683398151915290606001611a97565b885160208101516040909101519094509250611b98565b5f8951606001516001811115611b4257611b42613a4b565b03611b8557885160800151861015611b8557885160a00151604080518a8152911515602083015281018790525f80516020613db683398151915290606001611a97565b8851604081015160209091015190945092505b88516020810151604082015160a083015161012084015161014090940151611bc09490612bfb565b90925090508015611cd3578851516001600160a01b039081165f90815260016020908152604080832093871683529290529081208054849290611c04908490613a73565b9091555050600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee90611c3c908b90600390600401613c1d565b5f604051808303815f87803b158015611c53575f80fd5b505af1158015611c65573d5f803e3d5ffd5b50508a5160a08082015161012090920151604080518e8152931515602085015283015260608201869052608082018a90527fd3a2a38532d8ebbcacfb7f0283c81c80740d96318a247267aa64e7ac0a75a57c935001905060405180910390a16001965050505050505061195a565b6040518881527ff9e10ddceffcb10b96e8833202366240699b814c91f371ddd9befa3aee9bc60f90602001611a97565b5f80611d2373a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488561316e565b15611dd9576040805160028082526060820183525f9260208301908036833701905050905084815f81518110611d5b57611d5b613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881600181518110611da357611da3613a86565b60200260200101906001600160a01b031690816001600160a01b031681525050611dcd8185613208565b60019250925050612005565b611df773c28ab4e347dd26c5809540e7db0cea473d91439c8561316e565b15611e77576040805160028082526060820183525f9260208301908036833701905050905084815f81518110611e2f57611e2f613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073c28ab4e347dd26c5809540e7db0cea473d91439c81600181518110611da357611da3613a86565b611e9573c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28561316e565b15611f5f57604080516003808252608082019092525f916020820160608036833701905050905084815f81518110611ecf57611ecf613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110611f1757611f17613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881600281518110611da357611da3613a86565b611f7d73c5fb36dd2fb59d3b98deff88425a3f425ee469ed8561316e565b15611fff57604080516003808252608082019092525f916020820160608036833701905050905084815f81518110611fb757611fb7613a86565b60200260200101906001600160a01b031690816001600160a01b03168152505073c5fb36dd2fb59d3b98deff88425a3f425ee469ed81600181518110611f1757611f17613a86565b505f9050805b9250929050565b5f805f61205d855f015160400151865f0151604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119b1573d5f803e3d5ffd5b9150915080612096576040518481527fbf641aa67d51d72628240e9ac2c9f36cf8c9ec37d043d89382355fe67132e66e90602001611a1a565b84606001511561244957845160e001518210806120b75750845160c0015182115b156120ed57845160a0015160408051868152911515602083015281018390525f80516020613db683398151915290606001611a1a565b5f805f80885f015160a001511561211557885160208101516040909101519094509250612128565b8851604081015160209091015190945092505b885161012081015190516001600160a01b039081165f90815260016020908152604080832093891683529290522054106123a65788516020810151604082015160a0830151610120840151610140909401516121849490612bfb565b90925090508015612376578851516001600160a01b039081165f908152600160209081526040808320938716835292905290812080548492906121c8908490613a73565b9091555050885161012081015190516001600160a01b039081165f9081526001602090815260408083209389168352929052908120805490919061220d908490613b0b565b9091555050600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee90612244908b905f90600401613c1d565b5f604051808303815f87803b15801561225b575f80fd5b505af115801561226d573d5f803e3d5ffd5b5050600654604051620b79f560ea1b8152600481018c90526001600160a01b039091169250632de7d40091506024015f604051808303815f87803b1580156122b3575f80fd5b505af11580156122c5573d5f803e3d5ffd5b5050600654604051635281b98160e01b8152600481018c90525f60248201526001600160a01b039091169250635281b98191506044015f604051808303815f87803b158015612312575f80fd5b505af1158015612324573d5f803e3d5ffd5b50508a5160a00151604080518c8152911515602083015281018990527febd85f6b4646b253274fd876529f3b004db9b6f2cb17401ef4afd75f45f4ff23925060600190505b60405180910390a1612440565b6040518881527ff9e10ddceffcb10b96e8833202366240699b814c91f371ddd9befa3aee9bc60f90602001612369565b600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee906123d9908b90600290600401613c1d565b5f604051808303815f87803b1580156123f0575f80fd5b505af1158015612402573d5f803e3d5ffd5b505050507f12479fe7346119b9d7b9e673759d5824b3523f69848c8b04d4c7d0e3f194a47f8860405161243791815260200190565b60405180910390a15b50505050611925565b5f60648660400151875f015160e001516124639190613c4d565b61246d9190613c64565b90505f60648760400151885f015160c001516124899190613c4d565b6124939190613c64565b875160e001519091506124a7908390613b0b565b841180156124c45750865160c001516124c1908290613a73565b84105b156124d5575f94505050505061195a565b600654604051635281b98160e01b815260048101889052600160248201526001600160a01b0390911690635281b981906044015f604051808303815f87803b15801561251f575f80fd5b505af1158015612531573d5f803e3d5ffd5b505050505050506001949350505050565b5f805f612593855f015160400151865f0151604001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119b1573d5f803e3d5ffd5b91509150806125cc576040518481527fbf641aa67d51d72628240e9ac2c9f36cf8c9ec37d043d89382355fe67132e66e90602001611a1a565b845160a0015115612a03578460600151156129535784516080015182111561261f57845160a0015160408051868152911515602083015281018390525f80516020613db683398151915290606001611a1a565b845161012081015190516001600160a01b039081165f9081526001602090815260408083208a5183015190941683529290529081205490918291106128b25786516020810151604082015160a0830151610120840151610140909401516126869490612bfb565b90925090508015612882578651516001600160a01b039081165f9081526001602090815260408083208b51820151909416835292905290812080548492906126cf908490613a73565b9091555050865161012081015190516001600160a01b039081165f9081526001602090815260408083208c5183015190941683529290529081208054909190612719908490613b0b565b9091555050600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee906127509089905f90600401613c1d565b5f604051808303815f87803b158015612767575f80fd5b505af1158015612779573d5f803e3d5ffd5b5050600654604051620b79f560ea1b8152600481018a90526001600160a01b039091169250632de7d40091506024015f604051808303815f87803b1580156127bf575f80fd5b505af11580156127d1573d5f803e3d5ffd5b5050600654604051635281b98160e01b8152600481018a90525f60248201526001600160a01b039091169250635281b98191506044015f604051808303815f87803b15801561281e575f80fd5b505af1158015612830573d5f803e3d5ffd5b5050885160a00151604080518a8152911515602083015281018790527febd85f6b4646b253274fd876529f3b004db9b6f2cb17401ef4afd75f45f4ff23925060600190505b60405180910390a161294c565b6040518681527ff9e10ddceffcb10b96e8833202366240699b814c91f371ddd9befa3aee9bc60f90602001612875565b600654604051631afd817760e11b81526001600160a01b03909116906335fb02ee906128e5908990600290600401613c1d565b5f604051808303815f87803b1580156128fc575f80fd5b505af115801561290e573d5f803e3d5ffd5b505050507f12479fe7346119b9d7b9e673759d5824b3523f69848c8b04d4c7d0e3f194a47f8660405161294391815260200190565b60405180910390a15b5050611925565b5f60648660400151875f01516080015161296d9190613c4d565b6129779190613c64565b86516080015190915061298b908290613a73565b83101561299d575f935050505061195a565b600654604051635281b98160e01b815260048101879052600160248201526001600160a01b0390911690635281b981906044015f604051808303815f87803b1580156129e7575f80fd5b505af11580156129f9573d5f803e3d5ffd5b5050505050611925565b846060015115612b4557845160800151821015612a4b57845160a0015160408051868152911515602083015281018390525f80516020613db683398151915290606001611a1a565b845161012081015190516001600160a01b039081165f9081526001602090815260408083208a5182015190941683529290529081205490918291106128b25786516020810151604082015160a083015161012084015161014090940151612ab29490612bfb565b90925090508015612882578651516001600160a01b039081165f9081526001602090815260408083208b5183015190941683529290529081208054849290612afb908490613a73565b9091555050865161012081015190516001600160a01b039081165f9081526001602090815260408083208c5182015190941683529290529081208054909190612719908490613b0b565b5f60648660400151875f015160800151612b5f9190613c4d565b612b699190613c64565b865160800151909150612b7d908290613b0b565b831115612b8f575f935050505061195a565b600654604051635281b98160e01b815260048101879052600160248201526001600160a01b0390911690635281b981906044015f604051808303815f87803b158015612bd9575f80fd5b505af1158015612beb573d5f803e3d5ffd5b5060019998505050505050505050565b5f805f805f8715612c1157899250889150612c18565b8892508991505b612c228a8a61316e565b612e08576001600160a01b038a1673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214801590612c6c5750612c6c73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a61316e565b15612c8c575073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612e08565b6001600160a01b038a1673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4814801590612cd25750612cd273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488a61316e565b15612cf2575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48612e08565b6001600160a01b038a1673c28ab4e347dd26c5809540e7db0cea473d91439c14801590612d385750612d3873c28ab4e347dd26c5809540e7db0cea473d91439c8a61316e565b15612d58575073c28ab4e347dd26c5809540e7db0cea473d91439c612e08565b6001600160a01b038a1673c5fb36dd2fb59d3b98deff88425a3f425ee469ed14801590612da257506001600160a01b03891673c5fb36dd2fb59d3b98deff88425a3f425ee469ed14155b8015612dc75750612dc773c5fb36dd2fb59d3b98deff88425a3f425ee469ed8b61316e565b8015612dec5750612dec73c5fb36dd2fb59d3b98deff88425a3f425ee469ed8a61316e565b15612e08575073c5fb36dd2fb59d3b98deff88425a3f425ee469ed5b60025460405163095ea7b360e01b81526001600160a01b03918216600482015260248101899052849182169063095ea7b3906044016020604051808303815f875af1158015612e59573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e7d9190613af0565b506040516370a0823160e01b81523060048201525f906001600160a01b038516906370a0823190602401602060405180830381865afa158015612ec2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ee6919061383d565b90506001600160a01b038316612fd5576040805160028082526060820183525f9260208301908036833701905050905085815f81518110612f2957612f29613a86565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600181518110612f5d57612f5d613a86565b6001600160a01b039283166020918202929092010152600254604051635c11d79560e01b8152911690635c11d79590612fa2908d908d90869030904290600401613cc6565b5f604051808303815f87803b158015612fb9575f80fd5b505af1158015612fcb573d5f803e3d5ffd5b50505050506130e6565b604080516003808252608082019092525f916020820160608036833701905050905085815f8151811061300a5761300a613a86565b60200260200101906001600160a01b031690816001600160a01b031681525050838160018151811061303e5761303e613a86565b60200260200101906001600160a01b031690816001600160a01b031681525050848160028151811061307257613072613a86565b6001600160a01b039283166020918202929092010152600254604051635c11d79560e01b8152911690635c11d795906130b7908d908d90869030904290600401613cc6565b5f604051808303815f87803b1580156130ce575f80fd5b505af11580156130e0573d5f803e3d5ffd5b50505050505b6040516370a0823160e01b81523060048201525f9082906001600160a01b038716906370a0823190602401602060405180830381865afa15801561312c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613150919061383d565b61315a9190613b0b565b9d60019d509b505050505050505050505050565b60035460405163e6a4390560e01b81526001600160a01b03848116600483015283811660248301525f92839291169063e6a4390590604401602060405180830381865afa1580156131c1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131e59190613d01565b90506001600160a01b0381166131fe575f91505061195a565b600191505061195a565b60025460405163d06ca61f60e01b81525f9182916001600160a01b039091169063d06ca61f9061323e9086908890600401613d1c565b5f60405180830381865afa158015613258573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261327f9190810190613d34565b905080600185516132909190613b0b565b815181106132a0576132a0613a86565b602002602001015191505092915050565b60405180608001604052806132c46132de565b81526020015f81526020015f81526020015f151581525090565b60408051610180810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052906101008201906132c4565b6001600160a01b038116811461333d575f80fd5b50565b801515811461333d575f80fd5b5f805f805f8060c08789031215613362575f80fd5b863561336d81613329565b9550602087013561337d81613329565b9450604087013561338d81613340565b959894975094956060810135955060808101359460a0909101359350915050565b5f805f805f805f805f6101208a8c0312156133c7575f80fd5b8935985060208a01356133d981613329565b975060408a01356133e981613329565b965060608a01356133f981613340565b989b979a50959860808101359760a0820135975060c0820135965060e08201359550610100909101359350915050565b5f805f805f805f80610100898b031215613441575f80fd5b88359750602089013561345381613329565b9650604089013561346381613329565b9550606089013561347381613340565b979a969950949760808101359660a0820135965060c0820135955060e0909101359350915050565b5f602082840312156134ab575f80fd5b81356134b681613329565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b6040516080810167ffffffffffffffff811182821017156134f4576134f46134bd565b60405290565b604051610180810167ffffffffffffffff811182821017156134f4576134f46134bd565b604051601f8201601f1916810167ffffffffffffffff81118282101715613547576135476134bd565b604052919050565b5f67ffffffffffffffff821115613568576135686134bd565b5060051b60200190565b5f6020808385031215613583575f80fd5b823567ffffffffffffffff811115613599575f80fd5b8301601f810185136135a9575f80fd5b80356135bc6135b78261354f565b61351e565b81815260059190911b820183019083810190878311156135da575f80fd5b928401925b828410156135f8578335825292840192908401906135df565b979650505050505050565b5f805f805f805f60e0888a031215613619575f80fd5b87359650602088013561362b81613329565b9550604088013561363b81613329565b945060608801359350608088013561365281613340565b9699959850939692959460a0840135945060c09093013592915050565b5f805f805f805f60e0888a031215613685575f80fd5b873561369081613329565b965060208801356136a081613329565b955060408801356136b081613340565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b5f602082840312156136e8575f80fd5b5035919050565b5f805f805f805f80610100898b031215613707575f80fd5b883561371281613329565b9750602089013561372281613329565b9650604089013561373281613340565b979a96995096976060810135975060808101359660a0820135965060c0820135955060e0909101359350915050565b5f8060408385031215613772575f80fd5b823561377d81613329565b946020939093013593505050565b5f806040838503121561379c575f80fd5b82356137a781613329565b915060208301356137b781613329565b809150509250929050565b60208082526011908201527015985b1a59185d1a5bdb8819985a5b1959607a1b604082015260600190565b6001600160a01b03998a16815297891660208901529590971660408701529215156060860152608085019190915260a084015260c083015260e08201929092526101008101919091526101200190565b5f6020828403121561384d575f80fd5b5051919050565b805161385f81613329565b919050565b80516002811061385f575f80fd5b805161385f81613340565b80516004811061385f575f80fd5b5f8183036101e081121561389d575f80fd5b6138a56134d1565b610180808312156138b4575f80fd5b6138bc6134fa565b92506138c785613854565b83526138d560208601613854565b60208401526138e660408601613854565b60408401526138f760608601613864565b60608401526080850151608084015261391260a08601613872565b60a084015260c085015160c084015260e085015160e084015261010061393981870161387d565b9084015261012085810151908401526101408086015190840152610160613961818701613872565b9084015282825284015160208201526101a084015160408201526139886101c08501613872565b6060820152949350505050565b6020808252601d908201527f6d73672e73656e646572206973206e6f74206f72646572206f776e6572000000604082015260600190565b602080825260149082015273496e636f7272656374206f72646572207479706560601b604082015260600190565b998a526001600160a01b0398891660208b01529690971660408901529315156060880152608087019290925260a086015260c085015260e08401526101008301919091526101208201526101400190565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082018082111561195a5761195a613a5f565b634e487b7160e01b5f52603260045260245ffd5b6001600160a01b039a8b168152988a1660208a01529690981660408801529315156060870152608086019290925260a085015260c084015260e08301526101008201929092526101208101919091526101400190565b5f60208284031215613b00575f80fd5b81516134b681613340565b8181038181111561195a5761195a613a5f565b5f60208284031215613b2e575f80fd5b815160ff811681146134b6575f80fd5b600181815b80851115613b7857815f1904821115613b5e57613b5e613a5f565b80851615613b6b57918102915b93841c9390800290613b43565b509250929050565b5f82613b8e5750600161195a565b81613b9a57505f61195a565b81600181146131fe5760028103613bc75760ff841115613bbc57613bbc613a5f565b50506001821b61195a565b5060208310610133831016604e8410600b8410161715613bea575081810a61195a565b613bf48383613b3e565b805f1904821115613c0757613c07613a5f565b029392505050565b5f6134b660ff841683613b80565b8281526040810160048310613c4057634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b808202811582820484141761195a5761195a613a5f565b5f82613c7e57634e487b7160e01b5f52601260045260245ffd5b500490565b5f815180845260208085019450602084015f5b83811015613cbb5781516001600160a01b031687529582019590820190600101613c96565b509495945050505050565b85815284602082015260a060408201525f613ce460a0830186613c83565b6001600160a01b0394909416606083015250608001529392505050565b5f60208284031215613d11575f80fd5b81516134b681613329565b828152604060208201525f6119296040830184613c83565b5f6020808385031215613d45575f80fd5b825167ffffffffffffffff811115613d5b575f80fd5b8301601f81018513613d6b575f80fd5b8051613d796135b78261354f565b81815260059190911b82018301908381019087831115613d97575f80fd5b928401925b828410156135f857835182529284019290840190613d9c56fe376cc40e122623406a50cd32e6ec71ccc664eb3ea2107e8db1822d3b9cfac54aa2646970667358221220e7db3c915cc5cff796847397344661ba0e61139affa768e1ea03cde007d94fcb64736f6c63430008170033
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.