Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- MasterNodes
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-09-26T15:32:38.603206Z
Contract source code
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface ISimplifiedGlobalFarm { function mintFarmingReward(address _localFarm) external; function getAllocationX1000(address _farm) external view returns (uint256); function getRewardPerSecond() external view returns (uint256); function getlastPayment(address _localFarmAddress) external view returns (uint256); function next_payment() external view returns (uint256); function rewardMintingAvailable(address _farm) external view returns (bool); function farmExists(address _farmAddress) external view returns (bool); function owner() external view returns (address); } interface IERC20 { function balanceOf(address who) external view returns (uint256); } /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256` * (`UintSet`) are supported. */ library EnumerableSet { struct AddressSet { // Storage of set values address[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (address => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { if (!contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. address lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Replace a current value from a set with the new value. * * Returns true if the value was replaced, and false if newValue already in set or currentValue is not in set */ function replace(AddressSet storage set, address currentValue, address newValue) internal returns (bool) { uint256 currentIndex = set._indexes[currentValue]; if (contains(set, newValue) || currentIndex == 0) { return false; } else { set._values[currentIndex - 1] = newValue; set._indexes[newValue] = currentIndex; delete set._indexes[currentValue]; return true; } } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns 1-based index of value in the set. O(1). */ function indexOf(AddressSet storage set, address value) internal view returns (uint256) { return set._indexes[value]; } /** * @dev Returns the number of values on the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } } // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove(address token, address to, uint value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); } function safeTransfer(address token, address to, uint value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); } function safeTransferFrom(address token, address from, address to, uint value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); } function safeTransferETH(address to, uint value) internal { (bool success,) = to.call{value:value}(new bytes(0)); require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); } } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable { address internal _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ /* constructor () { _owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } */ /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == msg.sender, "Ownable: caller is not the owner"); _; } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } contract MasterNodes is Ownable { using EnumerableSet for EnumerableSet.AddressSet; using TransferHelper for address; //EnumerableSet.AddressSet _userNodes; // Enumerable list of users authority addresses (should be different then Node owner wallet) //EnumerableSet.AddressSet _callistoNodes; // Enumerable list of Callisto Enterprise authority addresses(should be different then Node owner wallet) // BEGIN MAIN NET VALUES address constant public SOY_TOKEN = 0x9FaE2529863bD691B4A7171bDfCf33C7ebB10a65; address constant public CLOE_TOKEN = 0x1eAa43544dAa399b87EEcFcC6Fa579D5ea4A6187; address constant public globalFarm = 0x64Fa36ACD0d13472FD786B03afC9C52aD5FCf023; // minimum and maximum deposit amount uint256 constant public minCLO = 500000 ether; uint256 constant public maxCLO = 5000000 ether; uint256 constant public minCLOE = 150000 ether; uint256 constant public maxCLOE = 1500000 ether; uint256 constant public minSOY = 25000 ether; uint256 constant public maxSOY = 250000 ether; uint256 constant public inactiveUnlockTime = 14 days; // END MAIN NET VALUES /* // BEGIN TEST NET VALUES address constant public SOY_TOKEN = 0x4c20231BCc5dB8D805DB9197C84c8BA8287CbA92; address constant public CLOE_TOKEN = 0x3364AD23385E2e71756C4bb29B5E3480f312B368; address constant public globalFarm = 0x9F66541abc036503Ae074E1E28638b0Cb6165458; // minimum and maximum deposit amount uint256 constant public minCLO = 5 ether; uint256 constant public maxCLO = 50 ether; uint256 constant public minCLOE = 15 ether; uint256 constant public maxCLOE = 150 ether; uint256 constant public minSOY = 25 ether; uint256 constant public maxSOY = 250 ether; uint256 constant public inactiveUnlockTime = 1 hours; // END TEST NET VALUES */ // part of total reward (%) to split among master nodes belong to users uint256 public usersNodesRewardRatio; // Maximum number of nodes belong to users //uint256 public maxUserNodes; //uint256 public userInactiveNodes; // Maximum number of nodes belong to Callisto Enterprise //uint256 public maxCallistoNodes; //uint256 public callistoInactiveNodes; // Total deposited //uint256[3] public userDeposits; // 0 - CLO, 1 - CLOE, 2 - SOY // Callisto Enterprise nodes deposits //uint256[3] public callistoDeposits; // 0 - CLO, 1 - CLOE, 2 - SOY // reward ratio of 100 uint256[3] public ratio; // percent of total rewards per token type (0 - CLO, 1 - CLOE, 2 - SOY) uint256[3] public accumulatedRewardPerShare; // 0 - CLO, 1 - CLOE, 2 - SOY uint256 public lastRewardTimestamp; struct Details { EnumerableSet.AddressSet nodes; //list of authority addresses (should be different then Node owner wallet) uint256 maxNodes; uint256 inactiveNodes; uint256[3] totalDeposits; // 0 - CLO, 1 - CLOE, 2 - SOY } struct Node { address owner; // address of master node owner bool isActive; uint8 isUser; // master node can belong to users or to Callisto Enterprise (CE) uint256[3] balances; //0 - CLO, 1 - CLOE, 2 - SOY uint256[3] rewardPerShares; //0 - CLO, 1 - CLOE, 2 - SOY uint256 unlockTime; // time when user can withdraw collaterals if node isn't active string url; // authority URL } Details[2] private _details; // 0 - Callisto Enterprise nodes, 1 - users nodes mapping(address => Node) private _nodes; // nodes mapping(address => address) public authorityByOwner; // address(0) - empty, address(1) - belong to Callisto Enterprise, otherwise address of authority event SetRatios(uint256 _ratioCLO, uint256 _ratioCLOE, uint256 _ratioSOY, uint256 _usersNodesRewardRatio); event NodeAdded(address indexed authority, Node node); event NodeActivated(address indexed authority); event NodeDeactivated(address indexed authority); event NodeRemoved(address indexed authority); event RewardAdded(uint256 reward); event RescueERC20(address token, address to, uint256 value); function initialize() external { require(_owner == address(0), "Already initialized"); _owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); ratio[0] = 62; // CLO ratio 62% ratio[1] = 27; // CLOE ratio 27% ratio[2] = 11; // SOY ratio 11% usersNodesRewardRatio = 65; // rewards will be split by 65% to master nodes held by users and 35% to master nodes held by Callisto Enterprise emit SetRatios(ratio[0],ratio[1], ratio[2], usersNodesRewardRatio); _details[0].maxNodes = 11; // 11 nodes may belong to Callisto Enterprise _details[1].maxNodes = 10; // 10 nodes may belong to users } // add master node. If msg.sender is admin, then node belong to Callisto Enterprise otherwise node belong to user function addNode(uint256 amountCLOE, uint256 amountSOY, address authority, string calldata url) external payable { _checkAmounts(msg.value, amountCLOE, amountSOY); uint256 isUser; // If added by contract owner then it's Callisto Enterprise node. // All Callisto Enterprise nodes belong to contract owner if (owner() != msg.sender) { // user node require(authorityByOwner[msg.sender] == address(0), "User already has node"); isUser = 1; authorityByOwner[msg.sender] = authority; } require(_details[isUser].nodes.length() < _details[isUser].maxNodes, "All nodes added"); require(_details[isUser].nodes.contains(authority) == false, "Authority already added"); _details[isUser].inactiveNodes++; CLOE_TOKEN.safeTransferFrom(msg.sender, address(this), amountCLOE); SOY_TOKEN.safeTransferFrom(msg.sender, address(this), amountSOY); Node memory _node = Node({ owner: msg.sender, isActive: false, isUser: uint8(isUser), balances: [msg.value, amountCLOE, amountSOY], rewardPerShares: [uint256(0), 0, 0], unlockTime: block.timestamp + inactiveUnlockTime, url: url }); _nodes[authority] = _node; emit NodeAdded(authority, _node); if(isUser == 0) activateNode(authority); // automatically active Callisto Enterprise node } // activate node (authority) function activateNode (address authority) public onlyOwner{ update(); Node storage n = _nodes[authority]; require(n.owner != address(0) && !n.isActive, "wrong authority"); uint256 isUser = uint256(n.isUser); require(_details[isUser].nodes.length() < _details[isUser].maxNodes, "All nodes added"); require(_details[isUser].nodes.add(authority), "Authority already added"); _details[isUser].inactiveNodes--; // update total deposits _details[isUser].totalDeposits[0] += n.balances[0]; _details[isUser].totalDeposits[1] += n.balances[1]; _details[isUser].totalDeposits[2] += n.balances[2]; if (isUser == 1) n.rewardPerShares = accumulatedRewardPerShare; // save rewardPerShares only for users node n.isActive = true; emit NodeActivated(authority); } // deactivate node (authority) function deactivateNode (address authority) external { update(); Node storage n = _nodes[authority]; require(n.owner != address(0) && n.isActive, "wrong authority"); require(n.owner == msg.sender || owner() == msg.sender, "Only node or contract owner"); uint256 isUser = uint256(n.isUser); require(_details[isUser].nodes.remove(authority), "Authority not exist"); _details[isUser].inactiveNodes++; // update total deposits _details[isUser].totalDeposits[0] -= n.balances[0]; _details[isUser].totalDeposits[1] -= n.balances[1]; _details[isUser].totalDeposits[2] -= n.balances[2]; n.isActive = false; n.unlockTime = block.timestamp + inactiveUnlockTime; if (isUser == 1) _payRewards(n.owner); else _payRewards(owner()); emit NodeDeactivated(authority); } // remove deactivated node (authority) and receive collateral (allowed after unlock period) function removeNode (address authority) external { update(); Node storage n = _nodes[authority]; address nodeOwner = n.owner; require(nodeOwner != address(0) && !n.isActive, "wrong authority"); require(nodeOwner == msg.sender || owner() == msg.sender, "Only node or contract owner"); require(n.unlockTime <= block.timestamp, "Node is locked"); _details[uint(n.isUser)].inactiveNodes--; // remove node from inactive counter uint256 amountCLO = n.balances[0]; uint256 amountCLOE = n.balances[1]; uint256 amountSOY = n.balances[2]; delete _nodes[authority]; nodeOwner.safeTransferETH(amountCLO); CLOE_TOKEN.safeTransfer(nodeOwner, amountCLOE); SOY_TOKEN.safeTransfer(nodeOwner, amountSOY); emit NodeRemoved(authority); } // claim earned reward function claimReward() external { _payRewards(msg.sender); } function _payRewards(address user) internal { uint256 reward = getReward(user); if (reward != 0) SOY_TOKEN.safeTransfer(user, reward); } function _checkAmounts(uint256 amountCLO, uint256 amountCLOE,uint256 amountSOY) internal pure { require(amountCLO >= minCLO, "Not enough CLO"); require(amountCLOE >= minCLOE, "Not enough CLOE"); require(amountSOY >= minSOY, "Not enough SOY"); require(amountCLO <= maxCLO, "Too many CLO"); require(amountCLOE <= maxCLOE, "Too many CLOE"); require(amountSOY <= maxSOY, "Too many SOY"); } // get master node info by authority address function getNodeByAuthority(address authority) public view returns (Node memory) { return _nodes[authority]; } // get user's master node info by owner address function getUsersNodeByOwner(address owner) external view returns (Node memory node, address authority) { authority = authorityByOwner[owner]; node = _nodes[authority]; } // get all Callisto Enterprise nodes function getCallistoNodes() external view returns(Node[] memory nodes, address[] memory authorities) { uint256 nodeLength = _details[0].nodes.length(); authorities = new address[](nodeLength); nodes = new Node[](nodeLength); for (uint i = 0; i < nodeLength; i++) { authorities[i] = _details[0].nodes.at(i); nodes[i] = _nodes[authorities[i]]; } } // get master node info by Id, belongUsers = 1 if get node that belong to users function getNodeById(uint256 id, bool belongUsers) external view returns (Node memory node, address authority) { if (belongUsers) authority = _details[1].nodes.at(id); else authority = _details[0].nodes.at(id); node = _nodes[authority]; } // get number of nodes belong to Callisto Enterprise and users function getNumberOfNodes() external view returns (uint256 callistoNodes, uint256 usersNodes) { callistoNodes = _details[0].nodes.length(); usersNodes = _details[1].nodes.length(); } // get details (deposits). id = 0 for callisto nodes, 1 for users nodes function getDetails(uint256 id) external view returns(uint256 maxNodes, uint256 inactiveNodes, uint256[3] memory totalDeposits) { maxNodes = _details[id].maxNodes; inactiveNodes = _details[id].inactiveNodes; totalDeposits = _details[id].totalDeposits; } // Set reward ratios function setRatios(uint256 _ratioCLOE, uint256 _ratioSOY, uint256 _usersNodesRewardRatio) external onlyOwner { require(_ratioCLOE + _ratioSOY <= 100, "Total ratio > 100%"); ratio[0] = 100 - _ratioCLOE - _ratioSOY; // CLO ratio ratio[1] = _ratioCLOE; ratio[2] = _ratioSOY; require(_usersNodesRewardRatio <= 100, "Users ratio > 100%"); usersNodesRewardRatio = _usersNodesRewardRatio; emit SetRatios(ratio[0], _ratioCLOE, _ratioSOY, _usersNodesRewardRatio); } // farming functions function notifyRewardAmount(uint256 reward) external { require(msg.sender == globalFarm, "Only globalFarm"); if (lastRewardTimestamp == 0) { lastRewardTimestamp = block.timestamp; } emit RewardAdded(reward); } function getRewardPerSecond() public view returns (uint256) { return ISimplifiedGlobalFarm(globalFarm).getRewardPerSecond(); } function getAllocationX1000() public view returns (uint256) { return ISimplifiedGlobalFarm(globalFarm).getAllocationX1000(address(this)); } // get earned reward function getReward(address user) public view returns(uint256 reward) { address authority = authorityByOwner[user]; uint256 _reward = (block.timestamp - lastRewardTimestamp) * getRewardPerSecond() * getAllocationX1000() / 1000; if (authority != address(0)) { // user's node Node storage n = _nodes[authority]; if (n.isActive) { // reward available only for active nodes _reward = _reward * usersNodesRewardRatio / 100; for (uint256 i = 0; i < 3; i++) { uint256 r = _reward * ratio[i] / 100; uint256 acc = accumulatedRewardPerShare[i] + (r * 1e18 / _details[1].totalDeposits[i]); reward = reward + (n.balances[i] * (acc - n.rewardPerShares[i]) / 1e18); } } } else if (user == owner() && _details[0].nodes.length() != 0) { // callisto's node // contract owner receive reward from all nodes belong to Callisto Enterprise reward = _reward * (100 - usersNodesRewardRatio) / 100; } } // Update reward variables of this Local Farm to be up-to-date. function update() public { ISimplifiedGlobalFarm(globalFarm).mintFarmingReward(address(this)); if (block.timestamp <= lastRewardTimestamp) { return; } if (lastRewardTimestamp == 0) return; // start calculate reward from first minting uint256 multiplier = block.timestamp - lastRewardTimestamp; uint256 _reward = multiplier * getRewardPerSecond() * getAllocationX1000() / 1000; _reward = _reward * usersNodesRewardRatio / 100; // users' part of rewards for (uint256 i = 0; i < 3; i++) { uint256 r = _reward * ratio[i] / 100; // part of reward per token type uint256 deposit = _details[1].totalDeposits[i]; if (deposit != 0) accumulatedRewardPerShare[i] = accumulatedRewardPerShare[i] + (r * 1e18 / deposit); } lastRewardTimestamp = block.timestamp; } // Rescue ERC20 tokens function rescueERC20(address token, address to) external onlyOwner { uint256 value = IERC20(token).balanceOf(address(this)); if (token == CLOE_TOKEN) { value = value - _details[0].totalDeposits[1] - _details[1].totalDeposits[1]; } else if (token == SOY_TOKEN) { require( _details[0].totalDeposits[2] == 0 && _details[1].totalDeposits[2] == 0, "SOY in use" ); // allow rescue SOY token only if there is not SOY deposits } token.safeTransfer(to, value); emit RescueERC20(token, to, value); } }
Contract ABI
[{"type":"event","name":"NodeActivated","inputs":[{"type":"address","name":"authority","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"NodeAdded","inputs":[{"type":"address","name":"authority","internalType":"address","indexed":true},{"type":"tuple","name":"node","internalType":"struct MasterNodes.Node","indexed":false,"components":[{"type":"address","name":"owner","internalType":"address"},{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint8","name":"isUser","internalType":"uint8"},{"type":"uint256[3]","name":"balances","internalType":"uint256[3]"},{"type":"uint256[3]","name":"rewardPerShares","internalType":"uint256[3]"},{"type":"uint256","name":"unlockTime","internalType":"uint256"},{"type":"string","name":"url","internalType":"string"}]}],"anonymous":false},{"type":"event","name":"NodeDeactivated","inputs":[{"type":"address","name":"authority","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"NodeRemoved","inputs":[{"type":"address","name":"authority","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RescueERC20","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardAdded","inputs":[{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetRatios","inputs":[{"type":"uint256","name":"_ratioCLO","internalType":"uint256","indexed":false},{"type":"uint256","name":"_ratioCLOE","internalType":"uint256","indexed":false},{"type":"uint256","name":"_ratioSOY","internalType":"uint256","indexed":false},{"type":"uint256","name":"_usersNodesRewardRatio","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"CLOE_TOKEN","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"SOY_TOKEN","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"accumulatedRewardPerShare","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"activateNode","inputs":[{"type":"address","name":"authority","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"addNode","inputs":[{"type":"uint256","name":"amountCLOE","internalType":"uint256"},{"type":"uint256","name":"amountSOY","internalType":"uint256"},{"type":"address","name":"authority","internalType":"address"},{"type":"string","name":"url","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"authorityByOwner","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimReward","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deactivateNode","inputs":[{"type":"address","name":"authority","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getAllocationX1000","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"nodes","internalType":"struct MasterNodes.Node[]","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint8","name":"isUser","internalType":"uint8"},{"type":"uint256[3]","name":"balances","internalType":"uint256[3]"},{"type":"uint256[3]","name":"rewardPerShares","internalType":"uint256[3]"},{"type":"uint256","name":"unlockTime","internalType":"uint256"},{"type":"string","name":"url","internalType":"string"}]},{"type":"address[]","name":"authorities","internalType":"address[]"}],"name":"getCallistoNodes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"maxNodes","internalType":"uint256"},{"type":"uint256","name":"inactiveNodes","internalType":"uint256"},{"type":"uint256[3]","name":"totalDeposits","internalType":"uint256[3]"}],"name":"getDetails","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct MasterNodes.Node","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint8","name":"isUser","internalType":"uint8"},{"type":"uint256[3]","name":"balances","internalType":"uint256[3]"},{"type":"uint256[3]","name":"rewardPerShares","internalType":"uint256[3]"},{"type":"uint256","name":"unlockTime","internalType":"uint256"},{"type":"string","name":"url","internalType":"string"}]}],"name":"getNodeByAuthority","inputs":[{"type":"address","name":"authority","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"node","internalType":"struct MasterNodes.Node","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint8","name":"isUser","internalType":"uint8"},{"type":"uint256[3]","name":"balances","internalType":"uint256[3]"},{"type":"uint256[3]","name":"rewardPerShares","internalType":"uint256[3]"},{"type":"uint256","name":"unlockTime","internalType":"uint256"},{"type":"string","name":"url","internalType":"string"}]},{"type":"address","name":"authority","internalType":"address"}],"name":"getNodeById","inputs":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"bool","name":"belongUsers","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"callistoNodes","internalType":"uint256"},{"type":"uint256","name":"usersNodes","internalType":"uint256"}],"name":"getNumberOfNodes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"reward","internalType":"uint256"}],"name":"getReward","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRewardPerSecond","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"node","internalType":"struct MasterNodes.Node","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint8","name":"isUser","internalType":"uint8"},{"type":"uint256[3]","name":"balances","internalType":"uint256[3]"},{"type":"uint256[3]","name":"rewardPerShares","internalType":"uint256[3]"},{"type":"uint256","name":"unlockTime","internalType":"uint256"},{"type":"string","name":"url","internalType":"string"}]},{"type":"address","name":"authority","internalType":"address"}],"name":"getUsersNodeByOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"globalFarm","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"inactiveUnlockTime","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastRewardTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxCLO","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxCLOE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxSOY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minCLO","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minCLOE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minSOY","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"notifyRewardAmount","inputs":[{"type":"uint256","name":"reward","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"ratio","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeNode","inputs":[{"type":"address","name":"authority","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueERC20","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"address","name":"to","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRatios","inputs":[{"type":"uint256","name":"_ratioCLOE","internalType":"uint256"},{"type":"uint256","name":"_ratioSOY","internalType":"uint256"},{"type":"uint256","name":"_usersNodesRewardRatio","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"usersNodesRewardRatio","inputs":[]}]
Contract Creation Code
0x608060405234801561001057600080fd5b50613400806100206000396000f3fe60806040526004361061020e5760003560e01c8063b2b99ec911610118578063da5b4ee7116100a0578063ebd5f9e11161006f578063ebd5f9e114610610578063f2fde38b1461062e578063f8077fae1461064e578063fcceb25a14610664578063feac12001461068257600080fd5b8063da5b4ee7146105a5578063e173bd45146105ba578063e80233c6146105da578063ea5c285d146105fa57600080fd5b8063bbebdcc0116100e7578063bbebdcc0146104fa578063c00007b014610527578063c23bdaa714610547578063cdfdb7dc14610565578063d096a21b1461058557600080fd5b8063b2b99ec91461046c578063b81c806a1461048c578063b88a802f146104b6578063b93a89f7146104cb57600080fd5b80635d799f871161019b5780638129fc1c1161016a5780638129fc1c146103e95780638da5cb5b146103fe578063a2e620451461041c578063a9622dc514610431578063b199892a1461045957600080fd5b80635d799f871461035c578063658144551461037c57806370a1579e1461039c57806374d43ac4146103bb57600080fd5b80631e29653c116101e25780631e29653c1461029e57806336f3d514146102b35780633c6b16ab146102d25780634f3a1ff8146102f45780635b17f5061461033457600080fd5b80628df45414610213578063135e5d8914610246578063141e93be1461026957806318a75f5214610280575b600080fd5b34801561021f57600080fd5b5061023361022e366004612d66565b6106b8565b6040519081526020015b60405180910390f35b34801561025257600080fd5b5061025b6106cf565b60405161023d929190612e62565b34801561027557600080fd5b506102336212750081565b34801561028c57600080fd5b506102336934f086f3b33b6840000081565b3480156102aa57600080fd5b50610233610982565b3480156102bf57600080fd5b506102336a013da329b633647180000081565b3480156102de57600080fd5b506102f26102ed366004612d66565b6109fd565b005b34801561030057600080fd5b5061031c7364fa36acd0d13472fd786b03afc9c52ad5fcf02381565b6040516001600160a01b03909116815260200161023d565b34801561034057600080fd5b5061031c739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b34801561036857600080fd5b506102f2610377366004612f22565b610a9c565b34801561038857600080fd5b506102f2610397366004612f55565b610c5b565b3480156103a857600080fd5b506102336a0422ca8b0a00a42500000081565b3480156103c757600080fd5b506103db6103d6366004612f85565b610f35565b60405161023d929190612fb5565b3480156103f557600080fd5b506102f26110ce565b34801561040a57600080fd5b506000546001600160a01b031661031c565b34801561042857600080fd5b506102f26111c8565b34801561043d57600080fd5b5061031c731eaa43544daa399b87eecfcc6fa579d5ea4a618781565b6102f2610467366004612fdf565b611370565b34801561047857600080fd5b506102f2610487366004612f55565b611755565b34801561049857600080fd5b506104a16119b4565b6040805192835260208301919091520161023d565b3480156104c257600080fd5b506102f26119d6565b3480156104d757600080fd5b506104eb6104e6366004612d66565b6119e1565b60405161023d93929190613073565b34801561050657600080fd5b5061051a610515366004612f55565b611a7a565b60405161023d91906130b4565b34801561053357600080fd5b50610233610542366004612f55565b611be5565b34801561055357600080fd5b5061023369054b40b1f852bda0000081565b34801561057157600080fd5b506102f26105803660046130c7565b611dff565b34801561059157600080fd5b506103db6105a0366004612f55565b611f3c565b3480156105b157600080fd5b506102336120b4565b3480156105c657600080fd5b506102336105d5366004612d66565b612108565b3480156105e657600080fd5b506102f26105f5366004612f55565b612118565b34801561060657600080fd5b5061023360015481565b34801561061c57600080fd5b506102336969e10de76676d080000081565b34801561063a57600080fd5b506102f2610649366004612f55565b6123f6565b34801561065a57600080fd5b5061023360085481565b34801561067057600080fd5b50610233691fc3842bd1f071c0000081565b34801561068e57600080fd5b5061031c61069d366004612f55565b6018602052600090815260409020546001600160a01b031681565b600281600381106106c857600080fd5b0154905081565b60608060006106e36009825b600702015490565b90508067ffffffffffffffff8111156106fe576106fe613109565b604051908082528060200260200182016040528015610727578160200160208202803683370190505b5091508067ffffffffffffffff81111561074357610743613109565b60405190808252806020026020018201604052801561077c57816020015b610769612c43565b8152602001906001900390816107615790505b50925060005b8181101561097c5761079d81600960005b60070201906124ef565b8382815181106107af576107af6130f3565b60200260200101906001600160a01b031690816001600160a01b031681525050601760008483815181106107e5576107e56130f3565b6020908102919091018101516001600160a01b039081168352828201939093526040918201600020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b81548152602001906001019080831161085b57505050918352505060408051606081019182905260209092019190600484019060039082845b8154815260200190600101908083116108945750505050508152602001600782015481526020016008820180546108ca9061311f565b80601f01602080910402602001604051908101604052809291908181526020018280546108f69061311f565b80156109435780601f1061091857610100808354040283529160200191610943565b820191906000526020600020905b81548152906001019060200180831161092657829003601f168201915b50505050508152505084828151811061095e5761095e6130f3565b602002602001018190525080806109749061316f565b915050610782565b50509091565b60405163389bbbfd60e21b81523060048201526000907364fa36acd0d13472fd786b03afc9c52ad5fcf0239063e26eeff490602401602060405180830381865afa1580156109d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f89190613188565b905090565b337364fa36acd0d13472fd786b03afc9c52ad5fcf02314610a575760405162461bcd60e51b815260206004820152600f60248201526e4f6e6c7920676c6f62616c4661726d60881b60448201526064015b60405180910390fd5b600854600003610a6657426008555b6040518181527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a150565b33610aaf6000546001600160a01b031690565b6001600160a01b031614610ad55760405162461bcd60e51b8152600401610a4e906131a1565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b409190613188565b9050731eaa43544daa399b87eecfcc6fa579d5ea4a6186196001600160a01b03841601610b8857601554600e54610b7790836131d6565b610b8191906131d6565b9050610bf6565b739fae2529863bd691b4a7171bdfcf33c7ebb10a64196001600160a01b03841601610bf657600f54158015610bbd5750601654155b610bf65760405162461bcd60e51b815260206004820152600a602482015269534f5920696e2075736560b01b6044820152606401610a4e565b610c0a6001600160a01b0384168383612580565b604080516001600160a01b038086168252841660208201529081018290527f9b793652de97f04c5168920587bad4b1c6345295a8f5ad31c59ff946a26f91d2906060015b60405180910390a1505050565b610c636111c8565b6001600160a01b038082166000908152601760205260409020805490911615801590610c9757508054600160a01b900460ff165b610cb35760405162461bcd60e51b8152600401610a4e906131e9565b80546001600160a01b0316331480610ce4575033610cd96000546001600160a01b031690565b6001600160a01b0316145b610d305760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206e6f6465206f7220636f6e7472616374206f776e657200000000006044820152606401610a4e565b8054600160a81b900460ff16610d5d8360098360028110610d5357610d536130f3565b600702019061269b565b610d9f5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a1bdc9a5d1e481b9bdd08195e1a5cdd606a1b6044820152606401610a4e565b60098160028110610db257610db26130f3565b600702016003016000815480929190610dca9061316f565b9091555050600182015460098260028110610de757610de76130f3565b60070201600401600060038110610e0057610e006130f3565b016000828254610e1091906131d6565b90915550506001808301015460098260028110610e2f57610e2f6130f3565b60070201600401600160038110610e4857610e486130f3565b016000828254610e5891906131d6565b9091555050600382015460098260028110610e7557610e756130f3565b60070201600401600260038110610e8e57610e8e6130f3565b016000828254610e9e91906131d6565b9091555050815460ff60a01b19168255610ebb6212750042613212565b60078301556001819003610ee2578154610edd906001600160a01b03166127dd565b610efc565b610efc610ef76000546001600160a01b031690565b6127dd565b6040516001600160a01b038416907fd9957750e6343405c319eb99a4ec67fa11cfd66969318cbc71aa2d45fa53a34990600090a2505050565b610f3d612c43565b60008215610f5957610f528460096001610793565b9050610f69565b610f668460096000610793565b90505b6001600160a01b03818116600090815260176020908152604091829020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b815481526020019060010190808311610fd457505050918352505060408051606081019182905260209092019190600484019060039082845b81548152602001906001019080831161100d5750505050508152602001600782015481526020016008820180546110439061311f565b80601f016020809104026020016040519081016040528092919081815260200182805461106f9061311f565b80156110bc5780601f10611091576101008083540402835291602001916110bc565b820191906000526020600020905b81548152906001019060200180831161109f57829003601f168201915b50505050508152505091509250929050565b6000546001600160a01b03161561111d5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610a4e565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3603e6002819055601b6003819055600b6004819055604160018190556040805194855260208501939093529183015260608201527f9644b6174df1bd5bad31e571d2506445b44f89a0ec9f80f86ad150284c317b5a9060800160405180910390a1600b8055600a601255565b60405163032453f160e51b81523060048201527364fa36acd0d13472fd786b03afc9c52ad5fcf0239063648a7e2090602401600060405180830381600087803b15801561121457600080fd5b505af1158015611228573d6000803e3d6000fd5b50505050600854421161123757565b60085460000361124357565b60006008544261125391906131d6565b905060006103e8611262610982565b61126a6120b4565b6112749085613225565b61127e9190613225565b611288919061323c565b905060646001548261129a9190613225565b6112a4919061323c565b905060005b60038110156113675760006064600283600381106112c9576112c96130f3565b01546112d59085613225565b6112df919061323c565b90506000601483600381106112f6576112f66130f3565b015490508015611352578061131383670de0b6b3a7640000613225565b61131d919061323c565b60058460038110611330576113306130f3565b015461133c9190613212565b6005846003811061134f5761134f6130f3565b01555b5050808061135f9061316f565b9150506112a9565b50504260085550565b61137b348686612813565b6000336113906000546001600160a01b031690565b6001600160a01b03161461142857336000908152601860205260409020546001600160a01b0316156113fc5760405162461bcd60e51b81526020600482015260156024820152745573657220616c726561647920686173206e6f646560581b6044820152606401610a4e565b5033600090815260186020526040902080546001600160a01b0319166001600160a01b03851617905560015b6009816002811061143b5761143b6130f3565b6007020160020154611459600983600281106106db576106db6130f3565b106114985760405162461bcd60e51b815260206004820152600f60248201526e105b1b081b9bd9195cc81859191959608a1b6044820152606401610a4e565b6114d584600983600281106114af576114af6130f3565b60070201906001600160a01b031660009081526001919091016020526040902054151590565b1561151c5760405162461bcd60e51b8152602060048201526017602482015276105d5d1a1bdc9a5d1e48185b1c9958591e481859191959604a1b6044820152606401610a4e565b6009816002811061152f5761152f6130f3565b6007020160030160008154809291906115479061316f565b9091555061156d9050731eaa43544daa399b87eecfcc6fa579d5ea4a61873330896129d8565b61158d739fae2529863bd691b4a7171bdfcf33c7ebb10a653330886129d8565b60006040518060e00160405280336001600160a01b031681526020016000151581526020018360ff16815260200160405180606001604052803481526020018a81526020018981525081526020016040518060600160405280600081526020016000815260200160008152508152602001621275004261160d9190613212565b815260200185858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250506001600160a01b0380891682526017602090815260409283902085518154928701519487015160ff16600160a81b0260ff60a81b19951515600160a01b026001600160a81b031990941691909416179190911792909216178155606083015192935083929091506116c19060018301906003612c8d565b5060808201516116d79060048301906003612c8d565b5060a0820151600782015560c082015160088201906116f690826132a4565b50905050846001600160a01b03167fb6b552e59896e4d58bd65ecce8af2a09e960820e2a6876d694f15471430d5ca58260405161173391906130b4565b60405180910390a28160000361174c5761174c85612118565b50505050505050565b61175d6111c8565b6001600160a01b0380821660009081526017602052604090208054909116801580159061179357508154600160a01b900460ff16155b6117af5760405162461bcd60e51b8152600401610a4e906131e9565b6001600160a01b0381163314806117df5750336117d46000546001600160a01b031690565b6001600160a01b0316145b61182b5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206e6f6465206f7220636f6e7472616374206f776e657200000000006044820152606401610a4e565b42826007015411156118705760405162461bcd60e51b815260206004820152600e60248201526d139bd919481a5cc81b1bd8dad95960921b6044820152606401610a4e565b8154600990600160a81b900460ff166002811061188f5761188f6130f3565b6007020160030160008154809291906118a790613364565b90915550506001828101546002808501546003808701546001600160a01b038916600090815260176020526040812080546001600160b01b03191681559687018190559386018490559085018390556004850183905560058501839055600685018390556007850183905592939092916119246008830182612ccb565b5061193a90506001600160a01b03851684612b08565b611959731eaa43544daa399b87eecfcc6fa579d5ea4a61878584612580565b611978739fae2529863bd691b4a7171bdfcf33c7ebb10a658583612580565b6040516001600160a01b038716907fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b90600090a2505050505050565b6000806119c26009826106db565b91506119d0600960016106db565b90509091565b6119df336127dd565b565b6000806119ec612d08565b600984600281106119ff576119ff6130f3565b6007020160020154925060098460028110611a1c57611a1c6130f3565b6007020160030154915060098460028110611a3957611a396130f3565b604080516060810191829052926007929092029091016004019060039082845b815481526020019060010190808311611a5957505050505090509193909250565b611a82612c43565b6001600160a01b03828116600090815260176020908152604091829020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b815481526020019060010190808311611aed57505050918352505060408051606081019182905260209092019190600484019060039082845b815481526020019060010190808311611b26575050505050815260200160078201548152602001600882018054611b5c9061311f565b80601f0160208091040260200160405190810160405280929190818152602001828054611b889061311f565b8015611bd55780601f10611baa57610100808354040283529160200191611bd5565b820191906000526020600020905b815481529060010190602001808311611bb857829003601f168201915b5050505050815250509050919050565b6001600160a01b03808216600090815260186020526040812054909116816103e8611c0e610982565b611c166120b4565b600854611c2390426131d6565b611c2d9190613225565b611c379190613225565b611c41919061323c565b90506001600160a01b03821615611da4576001600160a01b03821660009081526017602052604090208054600160a01b900460ff1615611d9e57606460015483611c8b9190613225565b611c95919061323c565b915060005b6003811015611d9c576000606460028360038110611cba57611cba6130f3565b0154611cc69086613225565b611cd0919061323c565b9050600060148360038110611ce757611ce76130f3565b0154611cfb83670de0b6b3a7640000613225565b611d05919061323c565b60058460038110611d1857611d186130f3565b0154611d249190613212565b9050670de0b6b3a7640000846004018460038110611d4457611d446130f3565b0154611d5090836131d6565b856001018560038110611d6557611d656130f3565b0154611d719190613225565b611d7b919061323c565b611d859088613212565b965050508080611d949061316f565b915050611c9a565b505b50611df8565b6000546001600160a01b038581169116148015611dcb5750611dc8600960006106db565b15155b15611df85760646001546064611de191906131d6565b611deb9083613225565b611df5919061323c565b92505b5050919050565b33611e126000546001600160a01b031690565b6001600160a01b031614611e385760405162461bcd60e51b8152600401610a4e906131a1565b6064611e448385613212565b1115611e875760405162461bcd60e51b8152602060048201526012602482015271546f74616c20726174696f203e203130302560701b6044820152606401610a4e565b81611e938460646131d6565b611e9d91906131d6565b600255600383905560048290556064811115611ef05760405162461bcd60e51b8152602060048201526012602482015271557365727320726174696f203e203130302560701b6044820152606401610a4e565b600181905560025460408051918252602082018590528101839052606081018290527f9644b6174df1bd5bad31e571d2506445b44f89a0ec9f80f86ad150284c317b5a90608001610c4e565b611f44612c43565b6001600160a01b0382811660009081526018602090815260408083205484168084526017835292819020815160e0810183528154958616815260ff600160a01b87048116151594820194909452600160a81b909504909216848201528051606080820192839052939493840191600184019060039082845b815481526020019060010190808311611fbc57505050918352505060408051606081019182905260209092019190600484019060039082845b815481526020019060010190808311611ff557505050505081526020016007820154815260200160088201805461202b9061311f565b80601f01602080910402602001604051908101604052809291908181526020018280546120579061311f565b80156120a45780601f10612079576101008083540402835291602001916120a4565b820191906000526020600020905b81548152906001019060200180831161208757829003601f168201915b5050505050815250509150915091565b60007364fa36acd0d13472fd786b03afc9c52ad5fcf0236001600160a01b031663da5b4ee76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109d4573d6000803e3d6000fd5b600581600381106106c857600080fd5b3361212b6000546001600160a01b031690565b6001600160a01b0316146121515760405162461bcd60e51b8152600401610a4e906131a1565b6121596111c8565b6001600160a01b03808216600090815260176020526040902080549091161580159061218e57508054600160a01b900460ff16155b6121aa5760405162461bcd60e51b8152600401610a4e906131e9565b8054600160a81b900460ff16600981600281106121c9576121c96130f3565b60070201600201546121e7600983600281106106db576106db6130f3565b106122265760405162461bcd60e51b815260206004820152600f60248201526e105b1b081b9bd9195cc81859191959608a1b6044820152606401610a4e565b612247836009836002811061223d5761223d6130f3565b6007020190612bd1565b61228d5760405162461bcd60e51b8152602060048201526017602482015276105d5d1a1bdc9a5d1e48185b1c9958591e481859191959604a1b6044820152606401610a4e565b600981600281106122a0576122a06130f3565b6007020160030160008154809291906122b890613364565b90915550506001820154600982600281106122d5576122d56130f3565b600702016004016000600381106122ee576122ee6130f3565b0160008282546122fe9190613212565b9091555050600180830101546009826002811061231d5761231d6130f3565b60070201600401600160038110612336576123366130f3565b0160008282546123469190613212565b9091555050600382015460098260028110612363576123636130f3565b6007020160040160026003811061237c5761237c6130f3565b01600082825461238c9190613212565b909155505060018190036123ac576123aa6004830160056003612d26565b505b815460ff60a01b1916600160a01b1782556040516001600160a01b038416907f7dc8b937d2916b130743c447af3d771fa55e66b7393105150e2e635ac3e8726090600090a2505050565b336124096000546001600160a01b031690565b6001600160a01b03161461242f5760405162461bcd60e51b8152600401610a4e906131a1565b6001600160a01b0381166124945760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a4e565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b8154600090821061254d5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610a4e565b826000018281548110612562576125626130f3565b6000918252602090912001546001600160a01b031690505b92915050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916125dc919061337b565b6000604051808303816000865af19150503d8060008114612619576040519150601f19603f3d011682016040523d82523d6000602084013e61261e565b606091505b50915091508180156126485750805115806126485750808060200190518101906126489190613397565b6126945760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610a4e565b5050505050565b6001600160a01b038116600090815260018301602052604081205480156127d35760006126c96001836131d6565b85549091506000906126dd906001906131d6565b905060008660000182815481106126f6576126f66130f3565b60009182526020909120015487546001600160a01b0390911691508190889085908110612725576127256130f3565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055612759836001613212565b6001600160a01b03821660009081526001890160205260409020558654879080612785576127856133b4565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b038816825260018981019091526040822091909155945061257a9350505050565b600091505061257a565b60006127e882611be5565b9050801561280f5761280f739fae2529863bd691b4a7171bdfcf33c7ebb10a658383612580565b5050565b6969e10de76676d080000083101561285e5760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f75676820434c4f60901b6044820152606401610a4e565b691fc3842bd1f071c000008210156128aa5760405162461bcd60e51b815260206004820152600f60248201526e4e6f7420656e6f75676820434c4f4560881b6044820152606401610a4e565b69054b40b1f852bda000008110156128f55760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f75676820534f5960901b6044820152606401610a4e565b6a0422ca8b0a00a42500000083111561293f5760405162461bcd60e51b815260206004820152600c60248201526b546f6f206d616e7920434c4f60a01b6044820152606401610a4e565b6a013da329b633647180000082111561298a5760405162461bcd60e51b815260206004820152600d60248201526c546f6f206d616e7920434c4f4560981b6044820152606401610a4e565b6934f086f3b33b684000008111156129d35760405162461bcd60e51b815260206004820152600c60248201526b546f6f206d616e7920534f5960a01b6044820152606401610a4e565b505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612a3c919061337b565b6000604051808303816000865af19150503d8060008114612a79576040519150601f19603f3d011682016040523d82523d6000602084013e612a7e565b606091505b5091509150818015612aa8575080511580612aa8575080806020019051810190612aa89190613397565b612b005760405162461bcd60e51b8152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416044820152631253115160e21b6064820152608401610a4e565b505050505050565b604080516000808252602082019092526001600160a01b038416908390604051612b32919061337b565b60006040518083038185875af1925050503d8060008114612b6f576040519150601f19603f3d011682016040523d82523d6000602084013e612b74565b606091505b50509050806129d35760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b6064820152608401610a4e565b6001600160a01b0381166000908152600183016020526040812054612c3b57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b0386169081179091558554908252828601909352604090209190915561257a565b50600061257a565b6040805160e0810182526000808252602082018190529181019190915260608101612c6c612d08565b8152602001612c79612d08565b815260200160008152602001606081525090565b8260038101928215612cbb579160200282015b82811115612cbb578251825591602001919060010190612ca0565b50612cc7929150612d51565b5090565b508054612cd79061311f565b6000825580601f10612ce7575050565b601f016020900490600052602060002090810190612d059190612d51565b50565b60405180606001604052806003906020820280368337509192915050565b8260038101928215612cbb579182015b82811115612cbb578254825591600101919060010190612d36565b5b80821115612cc75760008155600101612d52565b600060208284031215612d7857600080fd5b5035919050565b8060005b6003811015612da2578151845260209384019390910190600101612d83565b50505050565b60005b83811015612dc3578181015183820152602001612dab565b50506000910152565b600061016060018060a01b03835116845260208301511515602085015260ff60408401511660408501526060830151612e086060860182612d7f565b506080830151612e1b60c0860182612d7f565b5060a083015161012085015260c083015181610140860152805180838701526101809250612e4f8184880160208501612da8565b601f01601f191694909401019392505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015612eb957605f19888703018552612ea7868351612dcc565b95509382019390820190600101612e8b565b50508584038187015286518085528782019482019350915060005b82811015612ef95784516001600160a01b031684529381019392810192600101612ed4565b5091979650505050505050565b80356001600160a01b0381168114612f1d57600080fd5b919050565b60008060408385031215612f3557600080fd5b612f3e83612f06565b9150612f4c60208401612f06565b90509250929050565b600060208284031215612f6757600080fd5b612f7082612f06565b9392505050565b8015158114612d0557600080fd5b60008060408385031215612f9857600080fd5b823591506020830135612faa81612f77565b809150509250929050565b604081526000612fc86040830185612dcc565b905060018060a01b03831660208301529392505050565b600080600080600060808688031215612ff757600080fd5b853594506020860135935061300e60408701612f06565b9250606086013567ffffffffffffffff8082111561302b57600080fd5b818801915088601f83011261303f57600080fd5b81358181111561304e57600080fd5b89602082850101111561306057600080fd5b9699959850939650602001949392505050565b838152602080820184905260a0820190604083018460005b60038110156130a85781518352918301919083019060010161308b565b50505050949350505050565b602081526000612f706020830184612dcc565b6000806000606084860312156130dc57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061313357607f821691505b60208210810361315357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60006001820161318157613181613159565b5060010190565b60006020828403121561319a57600080fd5b5051919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b8181038181111561257a5761257a613159565b6020808252600f908201526e77726f6e6720617574686f7269747960881b604082015260600190565b8082018082111561257a5761257a613159565b808202811582820484141761257a5761257a613159565b60008261325957634e487b7160e01b600052601260045260246000fd5b500490565b601f8211156129d357600081815260208120601f850160051c810160208610156132855750805b601f850160051c820191505b81811015612b0057828155600101613291565b815167ffffffffffffffff8111156132be576132be613109565b6132d2816132cc845461311f565b8461325e565b602080601f83116001811461330757600084156132ef5750858301515b600019600386901b1c1916600185901b178555612b00565b600085815260208120601f198616915b8281101561333657888601518255948401946001909101908401613317565b50858210156133545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008161337357613373613159565b506000190190565b6000825161338d818460208701612da8565b9190910192915050565b6000602082840312156133a957600080fd5b8151612f7081612f77565b634e487b7160e01b600052603160045260246000fdfea264697066735822122093bc778fae5e69cb491bb0bd26470c5dbb848829ebad2ee4cb3243d537de9f4d64736f6c63430008110033
Deployed ByteCode
0x60806040526004361061020e5760003560e01c8063b2b99ec911610118578063da5b4ee7116100a0578063ebd5f9e11161006f578063ebd5f9e114610610578063f2fde38b1461062e578063f8077fae1461064e578063fcceb25a14610664578063feac12001461068257600080fd5b8063da5b4ee7146105a5578063e173bd45146105ba578063e80233c6146105da578063ea5c285d146105fa57600080fd5b8063bbebdcc0116100e7578063bbebdcc0146104fa578063c00007b014610527578063c23bdaa714610547578063cdfdb7dc14610565578063d096a21b1461058557600080fd5b8063b2b99ec91461046c578063b81c806a1461048c578063b88a802f146104b6578063b93a89f7146104cb57600080fd5b80635d799f871161019b5780638129fc1c1161016a5780638129fc1c146103e95780638da5cb5b146103fe578063a2e620451461041c578063a9622dc514610431578063b199892a1461045957600080fd5b80635d799f871461035c578063658144551461037c57806370a1579e1461039c57806374d43ac4146103bb57600080fd5b80631e29653c116101e25780631e29653c1461029e57806336f3d514146102b35780633c6b16ab146102d25780634f3a1ff8146102f45780635b17f5061461033457600080fd5b80628df45414610213578063135e5d8914610246578063141e93be1461026957806318a75f5214610280575b600080fd5b34801561021f57600080fd5b5061023361022e366004612d66565b6106b8565b6040519081526020015b60405180910390f35b34801561025257600080fd5b5061025b6106cf565b60405161023d929190612e62565b34801561027557600080fd5b506102336212750081565b34801561028c57600080fd5b506102336934f086f3b33b6840000081565b3480156102aa57600080fd5b50610233610982565b3480156102bf57600080fd5b506102336a013da329b633647180000081565b3480156102de57600080fd5b506102f26102ed366004612d66565b6109fd565b005b34801561030057600080fd5b5061031c7364fa36acd0d13472fd786b03afc9c52ad5fcf02381565b6040516001600160a01b03909116815260200161023d565b34801561034057600080fd5b5061031c739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b34801561036857600080fd5b506102f2610377366004612f22565b610a9c565b34801561038857600080fd5b506102f2610397366004612f55565b610c5b565b3480156103a857600080fd5b506102336a0422ca8b0a00a42500000081565b3480156103c757600080fd5b506103db6103d6366004612f85565b610f35565b60405161023d929190612fb5565b3480156103f557600080fd5b506102f26110ce565b34801561040a57600080fd5b506000546001600160a01b031661031c565b34801561042857600080fd5b506102f26111c8565b34801561043d57600080fd5b5061031c731eaa43544daa399b87eecfcc6fa579d5ea4a618781565b6102f2610467366004612fdf565b611370565b34801561047857600080fd5b506102f2610487366004612f55565b611755565b34801561049857600080fd5b506104a16119b4565b6040805192835260208301919091520161023d565b3480156104c257600080fd5b506102f26119d6565b3480156104d757600080fd5b506104eb6104e6366004612d66565b6119e1565b60405161023d93929190613073565b34801561050657600080fd5b5061051a610515366004612f55565b611a7a565b60405161023d91906130b4565b34801561053357600080fd5b50610233610542366004612f55565b611be5565b34801561055357600080fd5b5061023369054b40b1f852bda0000081565b34801561057157600080fd5b506102f26105803660046130c7565b611dff565b34801561059157600080fd5b506103db6105a0366004612f55565b611f3c565b3480156105b157600080fd5b506102336120b4565b3480156105c657600080fd5b506102336105d5366004612d66565b612108565b3480156105e657600080fd5b506102f26105f5366004612f55565b612118565b34801561060657600080fd5b5061023360015481565b34801561061c57600080fd5b506102336969e10de76676d080000081565b34801561063a57600080fd5b506102f2610649366004612f55565b6123f6565b34801561065a57600080fd5b5061023360085481565b34801561067057600080fd5b50610233691fc3842bd1f071c0000081565b34801561068e57600080fd5b5061031c61069d366004612f55565b6018602052600090815260409020546001600160a01b031681565b600281600381106106c857600080fd5b0154905081565b60608060006106e36009825b600702015490565b90508067ffffffffffffffff8111156106fe576106fe613109565b604051908082528060200260200182016040528015610727578160200160208202803683370190505b5091508067ffffffffffffffff81111561074357610743613109565b60405190808252806020026020018201604052801561077c57816020015b610769612c43565b8152602001906001900390816107615790505b50925060005b8181101561097c5761079d81600960005b60070201906124ef565b8382815181106107af576107af6130f3565b60200260200101906001600160a01b031690816001600160a01b031681525050601760008483815181106107e5576107e56130f3565b6020908102919091018101516001600160a01b039081168352828201939093526040918201600020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b81548152602001906001019080831161085b57505050918352505060408051606081019182905260209092019190600484019060039082845b8154815260200190600101908083116108945750505050508152602001600782015481526020016008820180546108ca9061311f565b80601f01602080910402602001604051908101604052809291908181526020018280546108f69061311f565b80156109435780601f1061091857610100808354040283529160200191610943565b820191906000526020600020905b81548152906001019060200180831161092657829003601f168201915b50505050508152505084828151811061095e5761095e6130f3565b602002602001018190525080806109749061316f565b915050610782565b50509091565b60405163389bbbfd60e21b81523060048201526000907364fa36acd0d13472fd786b03afc9c52ad5fcf0239063e26eeff490602401602060405180830381865afa1580156109d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f89190613188565b905090565b337364fa36acd0d13472fd786b03afc9c52ad5fcf02314610a575760405162461bcd60e51b815260206004820152600f60248201526e4f6e6c7920676c6f62616c4661726d60881b60448201526064015b60405180910390fd5b600854600003610a6657426008555b6040518181527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a150565b33610aaf6000546001600160a01b031690565b6001600160a01b031614610ad55760405162461bcd60e51b8152600401610a4e906131a1565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b409190613188565b9050731eaa43544daa399b87eecfcc6fa579d5ea4a6186196001600160a01b03841601610b8857601554600e54610b7790836131d6565b610b8191906131d6565b9050610bf6565b739fae2529863bd691b4a7171bdfcf33c7ebb10a64196001600160a01b03841601610bf657600f54158015610bbd5750601654155b610bf65760405162461bcd60e51b815260206004820152600a602482015269534f5920696e2075736560b01b6044820152606401610a4e565b610c0a6001600160a01b0384168383612580565b604080516001600160a01b038086168252841660208201529081018290527f9b793652de97f04c5168920587bad4b1c6345295a8f5ad31c59ff946a26f91d2906060015b60405180910390a1505050565b610c636111c8565b6001600160a01b038082166000908152601760205260409020805490911615801590610c9757508054600160a01b900460ff165b610cb35760405162461bcd60e51b8152600401610a4e906131e9565b80546001600160a01b0316331480610ce4575033610cd96000546001600160a01b031690565b6001600160a01b0316145b610d305760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206e6f6465206f7220636f6e7472616374206f776e657200000000006044820152606401610a4e565b8054600160a81b900460ff16610d5d8360098360028110610d5357610d536130f3565b600702019061269b565b610d9f5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a1bdc9a5d1e481b9bdd08195e1a5cdd606a1b6044820152606401610a4e565b60098160028110610db257610db26130f3565b600702016003016000815480929190610dca9061316f565b9091555050600182015460098260028110610de757610de76130f3565b60070201600401600060038110610e0057610e006130f3565b016000828254610e1091906131d6565b90915550506001808301015460098260028110610e2f57610e2f6130f3565b60070201600401600160038110610e4857610e486130f3565b016000828254610e5891906131d6565b9091555050600382015460098260028110610e7557610e756130f3565b60070201600401600260038110610e8e57610e8e6130f3565b016000828254610e9e91906131d6565b9091555050815460ff60a01b19168255610ebb6212750042613212565b60078301556001819003610ee2578154610edd906001600160a01b03166127dd565b610efc565b610efc610ef76000546001600160a01b031690565b6127dd565b6040516001600160a01b038416907fd9957750e6343405c319eb99a4ec67fa11cfd66969318cbc71aa2d45fa53a34990600090a2505050565b610f3d612c43565b60008215610f5957610f528460096001610793565b9050610f69565b610f668460096000610793565b90505b6001600160a01b03818116600090815260176020908152604091829020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b815481526020019060010190808311610fd457505050918352505060408051606081019182905260209092019190600484019060039082845b81548152602001906001019080831161100d5750505050508152602001600782015481526020016008820180546110439061311f565b80601f016020809104026020016040519081016040528092919081815260200182805461106f9061311f565b80156110bc5780601f10611091576101008083540402835291602001916110bc565b820191906000526020600020905b81548152906001019060200180831161109f57829003601f168201915b50505050508152505091509250929050565b6000546001600160a01b03161561111d5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610a4e565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3603e6002819055601b6003819055600b6004819055604160018190556040805194855260208501939093529183015260608201527f9644b6174df1bd5bad31e571d2506445b44f89a0ec9f80f86ad150284c317b5a9060800160405180910390a1600b8055600a601255565b60405163032453f160e51b81523060048201527364fa36acd0d13472fd786b03afc9c52ad5fcf0239063648a7e2090602401600060405180830381600087803b15801561121457600080fd5b505af1158015611228573d6000803e3d6000fd5b50505050600854421161123757565b60085460000361124357565b60006008544261125391906131d6565b905060006103e8611262610982565b61126a6120b4565b6112749085613225565b61127e9190613225565b611288919061323c565b905060646001548261129a9190613225565b6112a4919061323c565b905060005b60038110156113675760006064600283600381106112c9576112c96130f3565b01546112d59085613225565b6112df919061323c565b90506000601483600381106112f6576112f66130f3565b015490508015611352578061131383670de0b6b3a7640000613225565b61131d919061323c565b60058460038110611330576113306130f3565b015461133c9190613212565b6005846003811061134f5761134f6130f3565b01555b5050808061135f9061316f565b9150506112a9565b50504260085550565b61137b348686612813565b6000336113906000546001600160a01b031690565b6001600160a01b03161461142857336000908152601860205260409020546001600160a01b0316156113fc5760405162461bcd60e51b81526020600482015260156024820152745573657220616c726561647920686173206e6f646560581b6044820152606401610a4e565b5033600090815260186020526040902080546001600160a01b0319166001600160a01b03851617905560015b6009816002811061143b5761143b6130f3565b6007020160020154611459600983600281106106db576106db6130f3565b106114985760405162461bcd60e51b815260206004820152600f60248201526e105b1b081b9bd9195cc81859191959608a1b6044820152606401610a4e565b6114d584600983600281106114af576114af6130f3565b60070201906001600160a01b031660009081526001919091016020526040902054151590565b1561151c5760405162461bcd60e51b8152602060048201526017602482015276105d5d1a1bdc9a5d1e48185b1c9958591e481859191959604a1b6044820152606401610a4e565b6009816002811061152f5761152f6130f3565b6007020160030160008154809291906115479061316f565b9091555061156d9050731eaa43544daa399b87eecfcc6fa579d5ea4a61873330896129d8565b61158d739fae2529863bd691b4a7171bdfcf33c7ebb10a653330886129d8565b60006040518060e00160405280336001600160a01b031681526020016000151581526020018360ff16815260200160405180606001604052803481526020018a81526020018981525081526020016040518060600160405280600081526020016000815260200160008152508152602001621275004261160d9190613212565b815260200185858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250506001600160a01b0380891682526017602090815260409283902085518154928701519487015160ff16600160a81b0260ff60a81b19951515600160a01b026001600160a81b031990941691909416179190911792909216178155606083015192935083929091506116c19060018301906003612c8d565b5060808201516116d79060048301906003612c8d565b5060a0820151600782015560c082015160088201906116f690826132a4565b50905050846001600160a01b03167fb6b552e59896e4d58bd65ecce8af2a09e960820e2a6876d694f15471430d5ca58260405161173391906130b4565b60405180910390a28160000361174c5761174c85612118565b50505050505050565b61175d6111c8565b6001600160a01b0380821660009081526017602052604090208054909116801580159061179357508154600160a01b900460ff16155b6117af5760405162461bcd60e51b8152600401610a4e906131e9565b6001600160a01b0381163314806117df5750336117d46000546001600160a01b031690565b6001600160a01b0316145b61182b5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206e6f6465206f7220636f6e7472616374206f776e657200000000006044820152606401610a4e565b42826007015411156118705760405162461bcd60e51b815260206004820152600e60248201526d139bd919481a5cc81b1bd8dad95960921b6044820152606401610a4e565b8154600990600160a81b900460ff166002811061188f5761188f6130f3565b6007020160030160008154809291906118a790613364565b90915550506001828101546002808501546003808701546001600160a01b038916600090815260176020526040812080546001600160b01b03191681559687018190559386018490559085018390556004850183905560058501839055600685018390556007850183905592939092916119246008830182612ccb565b5061193a90506001600160a01b03851684612b08565b611959731eaa43544daa399b87eecfcc6fa579d5ea4a61878584612580565b611978739fae2529863bd691b4a7171bdfcf33c7ebb10a658583612580565b6040516001600160a01b038716907fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b90600090a2505050505050565b6000806119c26009826106db565b91506119d0600960016106db565b90509091565b6119df336127dd565b565b6000806119ec612d08565b600984600281106119ff576119ff6130f3565b6007020160020154925060098460028110611a1c57611a1c6130f3565b6007020160030154915060098460028110611a3957611a396130f3565b604080516060810191829052926007929092029091016004019060039082845b815481526020019060010190808311611a5957505050505090509193909250565b611a82612c43565b6001600160a01b03828116600090815260176020908152604091829020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b815481526020019060010190808311611aed57505050918352505060408051606081019182905260209092019190600484019060039082845b815481526020019060010190808311611b26575050505050815260200160078201548152602001600882018054611b5c9061311f565b80601f0160208091040260200160405190810160405280929190818152602001828054611b889061311f565b8015611bd55780601f10611baa57610100808354040283529160200191611bd5565b820191906000526020600020905b815481529060010190602001808311611bb857829003601f168201915b5050505050815250509050919050565b6001600160a01b03808216600090815260186020526040812054909116816103e8611c0e610982565b611c166120b4565b600854611c2390426131d6565b611c2d9190613225565b611c379190613225565b611c41919061323c565b90506001600160a01b03821615611da4576001600160a01b03821660009081526017602052604090208054600160a01b900460ff1615611d9e57606460015483611c8b9190613225565b611c95919061323c565b915060005b6003811015611d9c576000606460028360038110611cba57611cba6130f3565b0154611cc69086613225565b611cd0919061323c565b9050600060148360038110611ce757611ce76130f3565b0154611cfb83670de0b6b3a7640000613225565b611d05919061323c565b60058460038110611d1857611d186130f3565b0154611d249190613212565b9050670de0b6b3a7640000846004018460038110611d4457611d446130f3565b0154611d5090836131d6565b856001018560038110611d6557611d656130f3565b0154611d719190613225565b611d7b919061323c565b611d859088613212565b965050508080611d949061316f565b915050611c9a565b505b50611df8565b6000546001600160a01b038581169116148015611dcb5750611dc8600960006106db565b15155b15611df85760646001546064611de191906131d6565b611deb9083613225565b611df5919061323c565b92505b5050919050565b33611e126000546001600160a01b031690565b6001600160a01b031614611e385760405162461bcd60e51b8152600401610a4e906131a1565b6064611e448385613212565b1115611e875760405162461bcd60e51b8152602060048201526012602482015271546f74616c20726174696f203e203130302560701b6044820152606401610a4e565b81611e938460646131d6565b611e9d91906131d6565b600255600383905560048290556064811115611ef05760405162461bcd60e51b8152602060048201526012602482015271557365727320726174696f203e203130302560701b6044820152606401610a4e565b600181905560025460408051918252602082018590528101839052606081018290527f9644b6174df1bd5bad31e571d2506445b44f89a0ec9f80f86ad150284c317b5a90608001610c4e565b611f44612c43565b6001600160a01b0382811660009081526018602090815260408083205484168084526017835292819020815160e0810183528154958616815260ff600160a01b87048116151594820194909452600160a81b909504909216848201528051606080820192839052939493840191600184019060039082845b815481526020019060010190808311611fbc57505050918352505060408051606081019182905260209092019190600484019060039082845b815481526020019060010190808311611ff557505050505081526020016007820154815260200160088201805461202b9061311f565b80601f01602080910402602001604051908101604052809291908181526020018280546120579061311f565b80156120a45780601f10612079576101008083540402835291602001916120a4565b820191906000526020600020905b81548152906001019060200180831161208757829003601f168201915b5050505050815250509150915091565b60007364fa36acd0d13472fd786b03afc9c52ad5fcf0236001600160a01b031663da5b4ee76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109d4573d6000803e3d6000fd5b600581600381106106c857600080fd5b3361212b6000546001600160a01b031690565b6001600160a01b0316146121515760405162461bcd60e51b8152600401610a4e906131a1565b6121596111c8565b6001600160a01b03808216600090815260176020526040902080549091161580159061218e57508054600160a01b900460ff16155b6121aa5760405162461bcd60e51b8152600401610a4e906131e9565b8054600160a81b900460ff16600981600281106121c9576121c96130f3565b60070201600201546121e7600983600281106106db576106db6130f3565b106122265760405162461bcd60e51b815260206004820152600f60248201526e105b1b081b9bd9195cc81859191959608a1b6044820152606401610a4e565b612247836009836002811061223d5761223d6130f3565b6007020190612bd1565b61228d5760405162461bcd60e51b8152602060048201526017602482015276105d5d1a1bdc9a5d1e48185b1c9958591e481859191959604a1b6044820152606401610a4e565b600981600281106122a0576122a06130f3565b6007020160030160008154809291906122b890613364565b90915550506001820154600982600281106122d5576122d56130f3565b600702016004016000600381106122ee576122ee6130f3565b0160008282546122fe9190613212565b9091555050600180830101546009826002811061231d5761231d6130f3565b60070201600401600160038110612336576123366130f3565b0160008282546123469190613212565b9091555050600382015460098260028110612363576123636130f3565b6007020160040160026003811061237c5761237c6130f3565b01600082825461238c9190613212565b909155505060018190036123ac576123aa6004830160056003612d26565b505b815460ff60a01b1916600160a01b1782556040516001600160a01b038416907f7dc8b937d2916b130743c447af3d771fa55e66b7393105150e2e635ac3e8726090600090a2505050565b336124096000546001600160a01b031690565b6001600160a01b03161461242f5760405162461bcd60e51b8152600401610a4e906131a1565b6001600160a01b0381166124945760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a4e565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b8154600090821061254d5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610a4e565b826000018281548110612562576125626130f3565b6000918252602090912001546001600160a01b031690505b92915050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916125dc919061337b565b6000604051808303816000865af19150503d8060008114612619576040519150601f19603f3d011682016040523d82523d6000602084013e61261e565b606091505b50915091508180156126485750805115806126485750808060200190518101906126489190613397565b6126945760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610a4e565b5050505050565b6001600160a01b038116600090815260018301602052604081205480156127d35760006126c96001836131d6565b85549091506000906126dd906001906131d6565b905060008660000182815481106126f6576126f66130f3565b60009182526020909120015487546001600160a01b0390911691508190889085908110612725576127256130f3565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055612759836001613212565b6001600160a01b03821660009081526001890160205260409020558654879080612785576127856133b4565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b038816825260018981019091526040822091909155945061257a9350505050565b600091505061257a565b60006127e882611be5565b9050801561280f5761280f739fae2529863bd691b4a7171bdfcf33c7ebb10a658383612580565b5050565b6969e10de76676d080000083101561285e5760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f75676820434c4f60901b6044820152606401610a4e565b691fc3842bd1f071c000008210156128aa5760405162461bcd60e51b815260206004820152600f60248201526e4e6f7420656e6f75676820434c4f4560881b6044820152606401610a4e565b69054b40b1f852bda000008110156128f55760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f75676820534f5960901b6044820152606401610a4e565b6a0422ca8b0a00a42500000083111561293f5760405162461bcd60e51b815260206004820152600c60248201526b546f6f206d616e7920434c4f60a01b6044820152606401610a4e565b6a013da329b633647180000082111561298a5760405162461bcd60e51b815260206004820152600d60248201526c546f6f206d616e7920434c4f4560981b6044820152606401610a4e565b6934f086f3b33b684000008111156129d35760405162461bcd60e51b815260206004820152600c60248201526b546f6f206d616e7920534f5960a01b6044820152606401610a4e565b505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612a3c919061337b565b6000604051808303816000865af19150503d8060008114612a79576040519150601f19603f3d011682016040523d82523d6000602084013e612a7e565b606091505b5091509150818015612aa8575080511580612aa8575080806020019051810190612aa89190613397565b612b005760405162461bcd60e51b8152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416044820152631253115160e21b6064820152608401610a4e565b505050505050565b604080516000808252602082019092526001600160a01b038416908390604051612b32919061337b565b60006040518083038185875af1925050503d8060008114612b6f576040519150601f19603f3d011682016040523d82523d6000602084013e612b74565b606091505b50509050806129d35760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b6064820152608401610a4e565b6001600160a01b0381166000908152600183016020526040812054612c3b57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b0386169081179091558554908252828601909352604090209190915561257a565b50600061257a565b6040805160e0810182526000808252602082018190529181019190915260608101612c6c612d08565b8152602001612c79612d08565b815260200160008152602001606081525090565b8260038101928215612cbb579160200282015b82811115612cbb578251825591602001919060010190612ca0565b50612cc7929150612d51565b5090565b508054612cd79061311f565b6000825580601f10612ce7575050565b601f016020900490600052602060002090810190612d059190612d51565b50565b60405180606001604052806003906020820280368337509192915050565b8260038101928215612cbb579182015b82811115612cbb578254825591600101919060010190612d36565b5b80821115612cc75760008155600101612d52565b600060208284031215612d7857600080fd5b5035919050565b8060005b6003811015612da2578151845260209384019390910190600101612d83565b50505050565b60005b83811015612dc3578181015183820152602001612dab565b50506000910152565b600061016060018060a01b03835116845260208301511515602085015260ff60408401511660408501526060830151612e086060860182612d7f565b506080830151612e1b60c0860182612d7f565b5060a083015161012085015260c083015181610140860152805180838701526101809250612e4f8184880160208501612da8565b601f01601f191694909401019392505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015612eb957605f19888703018552612ea7868351612dcc565b95509382019390820190600101612e8b565b50508584038187015286518085528782019482019350915060005b82811015612ef95784516001600160a01b031684529381019392810192600101612ed4565b5091979650505050505050565b80356001600160a01b0381168114612f1d57600080fd5b919050565b60008060408385031215612f3557600080fd5b612f3e83612f06565b9150612f4c60208401612f06565b90509250929050565b600060208284031215612f6757600080fd5b612f7082612f06565b9392505050565b8015158114612d0557600080fd5b60008060408385031215612f9857600080fd5b823591506020830135612faa81612f77565b809150509250929050565b604081526000612fc86040830185612dcc565b905060018060a01b03831660208301529392505050565b600080600080600060808688031215612ff757600080fd5b853594506020860135935061300e60408701612f06565b9250606086013567ffffffffffffffff8082111561302b57600080fd5b818801915088601f83011261303f57600080fd5b81358181111561304e57600080fd5b89602082850101111561306057600080fd5b9699959850939650602001949392505050565b838152602080820184905260a0820190604083018460005b60038110156130a85781518352918301919083019060010161308b565b50505050949350505050565b602081526000612f706020830184612dcc565b6000806000606084860312156130dc57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061313357607f821691505b60208210810361315357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60006001820161318157613181613159565b5060010190565b60006020828403121561319a57600080fd5b5051919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b8181038181111561257a5761257a613159565b6020808252600f908201526e77726f6e6720617574686f7269747960881b604082015260600190565b8082018082111561257a5761257a613159565b808202811582820484141761257a5761257a613159565b60008261325957634e487b7160e01b600052601260045260246000fd5b500490565b601f8211156129d357600081815260208120601f850160051c810160208610156132855750805b601f850160051c820191505b81811015612b0057828155600101613291565b815167ffffffffffffffff8111156132be576132be613109565b6132d2816132cc845461311f565b8461325e565b602080601f83116001811461330757600084156132ef5750858301515b600019600386901b1c1916600185901b178555612b00565b600085815260208120601f198616915b8281101561333657888601518255948401946001909101908401613317565b50858210156133545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008161337357613373613159565b506000190190565b6000825161338d818460208701612da8565b9190910192915050565b6000602082840312156133a957600080fd5b8151612f7081612f77565b634e487b7160e01b600052603160045260246000fdfea264697066735822122093bc778fae5e69cb491bb0bd26470c5dbb848829ebad2ee4cb3243d537de9f4d64736f6c63430008110033