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:43.824563Z
Contract source code
// File: contracts/Ownable.sol
pragma solidity ^0.8.0;
/**
* @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;
}
}
// File: contracts/TransferHelper.sol
pragma solidity ^0.8.0;
// 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');
}
}
// File: contracts/EnumerableSet.sol
pragma solidity ^0.8.0;
/**
* @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];
}
}
// File: contracts/MasterNodes.sol
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);
}
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
uint256 public pendingCallistoReward;
event SetRatios(uint256 _ratioCLO, uint256 _ratioCLOE, uint256 _ratioSOY, uint256 _usersNodesRewardRatio);
event NodeAdded(address indexed authority, Node node);
event TokensAdded(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");
require(_nodes[authority].owner == address(0), "authority already added");
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
}
// add more tokens to active user's master node
function addTokens(uint256 amountCLOE, uint256 amountSOY) external payable {
update();
_payRewards(msg.sender);
address authority = authorityByOwner[msg.sender];
Node storage n = _nodes[authority];
require(authority != address(0) && n.isUser == 1, "Only user's node");
require(n.isActive, "Not active");
_checkAmounts(msg.value + n.balances[0], amountCLOE + n.balances[1], amountSOY + n.balances[2]);
CLOE_TOKEN.safeTransferFrom(msg.sender, address(this), amountCLOE);
SOY_TOKEN.safeTransferFrom(msg.sender, address(this), amountSOY);
// update user's balances
n.balances[0] += msg.value;
n.balances[1] += amountCLOE;
n.balances[2] += amountSOY;
// update total deposits
_details[1].totalDeposits[0] += msg.value;
_details[1].totalDeposits[1] += amountCLOE;
_details[1].totalDeposits[2] += amountSOY;
emit TokensAdded(authority, n);
}
// 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");
uint256 isUser = uint256(n.isUser);
if (isUser == 0) n.owner = owner(); // node owner of CLOE nodes is always current contract owner.
require(n.owner == msg.sender || owner() == msg.sender, "Only node or contract owner");
if (isUser == 1) _payRewards(n.owner);
else _payRewards(owner());
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;
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");
uint256 isUser = uint256(n.isUser);
if (isUser == 0) nodeOwner = owner(); // node owner of CLOE nodes is always current contract owner.
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];
delete authorityByOwner[nodeOwner];
nodeOwner.safeTransferETH(amountCLO);
CLOE_TOKEN.safeTransfer(nodeOwner, amountCLOE);
SOY_TOKEN.safeTransfer(nodeOwner, amountSOY);
emit NodeRemoved(authority);
}
// claim earned reward
function claimReward() external {
update();
_payRewards(msg.sender);
}
function _payRewards(address user) internal {
uint256 reward;
address authority = authorityByOwner[user];
if (authority != address(0)) { // user's node
Node storage n = _nodes[authority];
if (n.isActive) { // reward available only for active nodes
for (uint256 i = 0; i < 3; i++) {
reward = reward + (n.balances[i] * (accumulatedRewardPerShare[i] - n.rewardPerShares[i]) / 1e18);
}
n.rewardPerShares = accumulatedRewardPerShare; // save rewardPerShares only for users node
}
} else if (user == owner() && _details[0].nodes.length() != 0) { // callisto's node
// contract owner receive reward from all nodes belong to Callisto Enterprise
reward = pendingCallistoReward;
pendingCallistoReward = 0;
}
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 = pendingCallistoReward + (_reward * (100 - usersNodesRewardRatio) / 100);
}
}
// increase users rewards pool
function addRewardToUsersPool(uint256 amountSOY) external onlyOwner {
SOY_TOKEN.safeTransferFrom(msg.sender, address(this), amountSOY);
for (uint256 i = 0; i < 3; i++) {
uint256 r = amountSOY * 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);
}
}
// 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 _totalReward = multiplier * getRewardPerSecond() * getAllocationX1000() / 1000;
uint256 _reward = _totalReward * usersNodesRewardRatio / 100; // users' part of rewards
pendingCallistoReward = pendingCallistoReward + (_totalReward - _reward); // callisto's 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":"event","name":"TokensAdded","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":"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":"nonpayable","outputs":[],"name":"addRewardToUsersPool","inputs":[{"type":"uint256","name":"amountSOY","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"addTokens","inputs":[{"type":"uint256","name":"amountCLOE","internalType":"uint256"},{"type":"uint256","name":"amountSOY","internalType":"uint256"}]},{"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":"pendingCallistoReward","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
0x608060405234801561001057600080fd5b50613b23806100206000396000f3fe60806040526004361061022f5760003560e01c8063b199892a1161012e578063da5b4ee7116100ab578063ebd5f9e11161006f578063ebd5f9e11461067a578063f2fde38b14610698578063f8077fae146106b8578063fcceb25a146106ce578063feac1200146106ec57600080fd5b8063da5b4ee7146105ef578063e173bd4514610604578063e22733a214610624578063e80233c614610644578063ea5c285d1461066457600080fd5b8063bbebdcc0116100f2578063bbebdcc014610544578063c00007b014610571578063c23bdaa714610591578063cdfdb7dc146105af578063d096a21b146105cf57600080fd5b8063b199892a146104a3578063b2b99ec9146104b6578063b81c806a146104d6578063b88a802f14610500578063b93a89f71461051557600080fd5b80634f3a1ff8116101bc57806374d43ac41161018057806374d43ac4146104055780638129fc1c146104335780638da5cb5b14610448578063a2e6204514610466578063a9622dc51461047b57600080fd5b80634f3a1ff81461033e5780635b17f5061461037e5780635d799f87146103a657806365814455146103c657806370a1579e146103e657600080fd5b806318a75f521161020357806318a75f52146102b65780631e29653c146102d45780632f4860c9146102e957806336f3d514146102ff5780633c6b16ab1461031e57600080fd5b80628df454146102345780630102609914610267578063135e5d891461027c578063141e93be1461029f575b600080fd5b34801561024057600080fd5b5061025461024f36600461334a565b610722565b6040519081526020015b60405180910390f35b61027a610275366004613363565b610739565b005b34801561028857600080fd5b50610291610979565b60405161025e929190613468565b3480156102ab57600080fd5b506102546212750081565b3480156102c257600080fd5b506102546934f086f3b33b6840000081565b3480156102e057600080fd5b50610254610c2c565b3480156102f557600080fd5b5061025460195481565b34801561030b57600080fd5b506102546a013da329b633647180000081565b34801561032a57600080fd5b5061027a61033936600461334a565b610ca7565b34801561034a57600080fd5b506103667364fa36acd0d13472fd786b03afc9c52ad5fcf02381565b6040516001600160a01b03909116815260200161025e565b34801561038a57600080fd5b50610366739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b3480156103b257600080fd5b5061027a6103c1366004613528565b610d41565b3480156103d257600080fd5b5061027a6103e136600461355b565b610f00565b3480156103f257600080fd5b506102546a0422ca8b0a00a42500000081565b34801561041157600080fd5b5061042561042036600461358b565b611200565b60405161025e9291906135bb565b34801561043f57600080fd5b5061027a611399565b34801561045457600080fd5b506000546001600160a01b0316610366565b34801561047257600080fd5b5061027a611493565b34801561048757600080fd5b50610366731eaa43544daa399b87eecfcc6fa579d5ea4a618781565b61027a6104b13660046135e5565b611658565b3480156104c257600080fd5b5061027a6104d136600461355b565b611aa5565b3480156104e257600080fd5b506104eb611d45565b6040805192835260208301919091520161025e565b34801561050c57600080fd5b5061027a611d67565b34801561052157600080fd5b5061053561053036600461334a565b611d7a565b60405161025e93929190613679565b34801561055057600080fd5b5061056461055f36600461355b565b611e13565b60405161025e91906136ba565b34801561057d57600080fd5b5061025461058c36600461355b565b611f7e565b34801561059d57600080fd5b5061025469054b40b1f852bda0000081565b3480156105bb57600080fd5b5061027a6105ca3660046136cd565b6121a5565b3480156105db57600080fd5b506104256105ea36600461355b565b6122e2565b3480156105fb57600080fd5b5061025461245a565b34801561061057600080fd5b5061025461061f36600461334a565b6124ae565b34801561063057600080fd5b5061027a61063f36600461334a565b6124be565b34801561065057600080fd5b5061027a61065f36600461355b565b6125dc565b34801561067057600080fd5b5061025460015481565b34801561068657600080fd5b506102546969e10de76676d080000081565b3480156106a457600080fd5b5061027a6106b336600461355b565b6128ba565b3480156106c457600080fd5b5061025460085481565b3480156106da57600080fd5b50610254691fc3842bd1f071c0000081565b3480156106f857600080fd5b5061036661070736600461355b565b6018602052600090815260409020546001600160a01b031681565b6002816003811061073257600080fd5b0154905081565b610741611493565b61074a336129b3565b336000908152601860209081526040808320546001600160a01b03168084526017909252909120811580159061078b57508054600160a81b900460ff166001145b6107cf5760405162461bcd60e51b815260206004820152601060248201526f4f6e6c7920757365722773206e6f646560801b60448201526064015b60405180910390fd5b8054600160a01b900460ff166108145760405162461bcd60e51b815260206004820152600a6024820152694e6f742061637469766560b01b60448201526064016107c6565b600181015461084a906108279034613725565b60028301546108369087613725565b60038401546108459087613725565b612b0e565b61086a731eaa43544daa399b87eecfcc6fa579d5ea4a6187333087612cce565b61088a739fae2529863bd691b4a7171bdfcf33c7ebb10a65333086612cce565b346001820160000160008282546108a19190613725565b9091555084905060018083010160008282546108bd9190613725565b909155508390506001820160020160008282546108da9190613725565b90915550349050601460000160008282546108f59190613725565b90915550849050601460010160008282546109109190613725565b909155508390506014600201600082825461092b9190613725565b92505081905550816001600160a01b03167f6f7579464656d5010911f2a5ddf87eaa7149e87a41834055e651366a6e8f3ec08260405161096b9190613812565b60405180910390a250505050565b606080600061098d6009825b600702015490565b90508067ffffffffffffffff8111156109a8576109a861388f565b6040519080825280602002602001820160405280156109d1578160200160208202803683370190505b5091508067ffffffffffffffff8111156109ed576109ed61388f565b604051908082528060200260200182016040528015610a2657816020015b610a13613227565b815260200190600190039081610a0b5790505b50925060005b81811015610c2657610a4781600960005b6007020190612dfe565b838281518110610a5957610a596136f9565b60200260200101906001600160a01b031690816001600160a01b03168152505060176000848381518110610a8f57610a8f6136f9565b6020908102919091018101516001600160a01b039081168352828201939093526040918201600020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b815481526020019060010190808311610b0557505050918352505060408051606081019182905260209092019190600484019060039082845b815481526020019060010190808311610b3e575050505050815260200160078201548152602001600882018054610b749061375b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ba09061375b565b8015610bed5780601f10610bc257610100808354040283529160200191610bed565b820191906000526020600020905b815481529060010190602001808311610bd057829003601f168201915b505050505081525050848281518110610c0857610c086136f9565b60200260200101819052508080610c1e906138a5565b915050610a2c565b50509091565b60405163389bbbfd60e21b81523060048201526000907364fa36acd0d13472fd786b03afc9c52ad5fcf0239063e26eeff490602401602060405180830381865afa158015610c7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca291906138be565b905090565b337364fa36acd0d13472fd786b03afc9c52ad5fcf02314610cfc5760405162461bcd60e51b815260206004820152600f60248201526e4f6e6c7920676c6f62616c4661726d60881b60448201526064016107c6565b600854600003610d0b57426008555b6040518181527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a150565b33610d546000546001600160a01b031690565b6001600160a01b031614610d7a5760405162461bcd60e51b81526004016107c6906138d7565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610dc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de591906138be565b9050731eaa43544daa399b87eecfcc6fa579d5ea4a6186196001600160a01b03841601610e2d57601554600e54610e1c908361390c565b610e26919061390c565b9050610e9b565b739fae2529863bd691b4a7171bdfcf33c7ebb10a64196001600160a01b03841601610e9b57600f54158015610e625750601654155b610e9b5760405162461bcd60e51b815260206004820152600a602482015269534f5920696e2075736560b01b60448201526064016107c6565b610eaf6001600160a01b0384168383612e8f565b604080516001600160a01b038086168252841660208201529081018290527f9b793652de97f04c5168920587bad4b1c6345295a8f5ad31c59ff946a26f91d2906060015b60405180910390a1505050565b610f08611493565b6001600160a01b038082166000908152601760205260409020805490911615801590610f3c57508054600160a01b900460ff165b610f585760405162461bcd60e51b81526004016107c69061391f565b8054600160a81b900460ff166000819003610f8b5760005482546001600160a01b0319166001600160a01b039091161782555b81546001600160a01b0316331480610fbc575033610fb16000546001600160a01b031690565b6001600160a01b0316145b6110085760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206e6f6465206f7220636f6e7472616374206f776e6572000000000060448201526064016107c6565b80600103611029578154611024906001600160a01b03166129b3565b611043565b61104361103e6000546001600160a01b031690565b6129b3565b611064836009836002811061105a5761105a6136f9565b6007020190612faa565b6110a65760405162461bcd60e51b8152602060048201526013602482015272105d5d1a1bdc9a5d1e481b9bdd08195e1a5cdd606a1b60448201526064016107c6565b600981600281106110b9576110b96136f9565b6007020160030160008154809291906110d1906138a5565b90915550506001820154600982600281106110ee576110ee6136f9565b60070201600401600060038110611107576111076136f9565b016000828254611117919061390c565b90915550506001808301015460098260028110611136576111366136f9565b6007020160040160016003811061114f5761114f6136f9565b01600082825461115f919061390c565b909155505060038201546009826002811061117c5761117c6136f9565b60070201600401600260038110611195576111956136f9565b0160008282546111a5919061390c565b9091555050815460ff60a01b191682556111c26212750042613725565b60078301556040516001600160a01b038416907fd9957750e6343405c319eb99a4ec67fa11cfd66969318cbc71aa2d45fa53a34990600090a2505050565b611208613227565b600082156112245761121d8460096001610a3d565b9050611234565b6112318460096000610a3d565b90505b6001600160a01b03818116600090815260176020908152604091829020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b81548152602001906001019080831161129f57505050918352505060408051606081019182905260209092019190600484019060039082845b8154815260200190600101908083116112d857505050505081526020016007820154815260200160088201805461130e9061375b565b80601f016020809104026020016040519081016040528092919081815260200182805461133a9061375b565b80156113875780601f1061135c57610100808354040283529160200191611387565b820191906000526020600020905b81548152906001019060200180831161136a57829003601f168201915b50505050508152505091509250929050565b6000546001600160a01b0316156113e85760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016107c6565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3603e6002819055601b6003819055600b6004819055604160018190556040805194855260208501939093529183015260608201527f9644b6174df1bd5bad31e571d2506445b44f89a0ec9f80f86ad150284c317b5a9060800160405180910390a1600b8055600a601255565b60405163032453f160e51b81523060048201527364fa36acd0d13472fd786b03afc9c52ad5fcf0239063648a7e2090602401600060405180830381600087803b1580156114df57600080fd5b505af11580156114f3573d6000803e3d6000fd5b50505050600854421161150257565b60085460000361150e57565b60006008544261151e919061390c565b905060006103e861152d610c2c565b61153561245a565b61153f9085613948565b6115499190613948565b611553919061395f565b905060006064600154836115679190613948565b611571919061395f565b905061157d818361390c565b60195461158a9190613725565b60195560005b600381101561164e5760006064600283600381106115b0576115b06136f9565b01546115bc9085613948565b6115c6919061395f565b90506000601483600381106115dd576115dd6136f9565b01549050801561163957806115fa83670de0b6b3a7640000613948565b611604919061395f565b60058460038110611617576116176136f9565b01546116239190613725565b60058460038110611636576116366136f9565b01555b50508080611646906138a5565b915050611590565b5050426008555050565b611663348686612b0e565b6000336116786000546001600160a01b031690565b6001600160a01b03161461177857336000908152601860205260409020546001600160a01b0316156116e45760405162461bcd60e51b81526020600482015260156024820152745573657220616c726561647920686173206e6f646560581b60448201526064016107c6565b6001600160a01b03848116600090815260176020526040902054161561174c5760405162461bcd60e51b815260206004820152601760248201527f617574686f7269747920616c726561647920616464656400000000000000000060448201526064016107c6565b5033600090815260186020526040902080546001600160a01b0319166001600160a01b03851617905560015b6009816002811061178b5761178b6136f9565b60070201600201546117a960098360028110610985576109856136f9565b106117e85760405162461bcd60e51b815260206004820152600f60248201526e105b1b081b9bd9195cc81859191959608a1b60448201526064016107c6565b61182584600983600281106117ff576117ff6136f9565b60070201906001600160a01b031660009081526001919091016020526040902054151590565b1561186c5760405162461bcd60e51b8152602060048201526017602482015276105d5d1a1bdc9a5d1e48185b1c9958591e481859191959604a1b60448201526064016107c6565b6009816002811061187f5761187f6136f9565b600702016003016000815480929190611897906138a5565b909155506118bd9050731eaa43544daa399b87eecfcc6fa579d5ea4a6187333089612cce565b6118dd739fae2529863bd691b4a7171bdfcf33c7ebb10a65333088612cce565b60006040518060e00160405280336001600160a01b031681526020016000151581526020018360ff16815260200160405180606001604052803481526020018a81526020018981525081526020016040518060600160405280600081526020016000815260200160008152508152602001621275004261195d9190613725565b815260200185858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250506001600160a01b0380891682526017602090815260409283902085518154928701519487015160ff16600160a81b0260ff60a81b19951515600160a01b026001600160a81b03199094169190941617919091179290921617815560608301519293508392909150611a119060018301906003613271565b506080820151611a279060048301906003613271565b5060a0820151600782015560c08201516008820190611a4690826139c7565b50905050846001600160a01b03167fb6b552e59896e4d58bd65ecce8af2a09e960820e2a6876d694f15471430d5ca582604051611a8391906136ba565b60405180910390a281600003611a9c57611a9c856125dc565b50505050505050565b611aad611493565b6001600160a01b03808216600090815260176020526040902080549091168015801590611ae357508154600160a01b900460ff16155b611aff5760405162461bcd60e51b81526004016107c69061391f565b8154600160a81b900460ff166000819003611b23576000546001600160a01b031691505b6001600160a01b038216331480611b53575033611b486000546001600160a01b031690565b6001600160a01b0316145b611b9f5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206e6f6465206f7220636f6e7472616374206f776e6572000000000060448201526064016107c6565b4283600701541115611be45760405162461bcd60e51b815260206004820152600e60248201526d139bd919481a5cc81b1bd8dad95960921b60448201526064016107c6565b8254600990600160a81b900460ff1660028110611c0357611c036136f9565b600702016003016000815480929190611c1b90613a87565b90915550506001838101546002808601546003808801546001600160a01b038a16600090815260176020526040812080546001600160b01b0319168155968701819055938601849055908501839055600485018390556005850183905560068501839055600785018390559293909291611c9860088301826132af565b50506001600160a01b038516600081815260186020526040902080546001600160a01b0319169055611cca90846130ec565b611ce9731eaa43544daa399b87eecfcc6fa579d5ea4a61878684612e8f565b611d08739fae2529863bd691b4a7171bdfcf33c7ebb10a658683612e8f565b6040516001600160a01b038816907fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b90600090a250505050505050565b600080611d53600982610985565b9150611d6160096001610985565b90509091565b611d6f611493565b611d78336129b3565b565b600080611d856132ec565b60098460028110611d9857611d986136f9565b6007020160020154925060098460028110611db557611db56136f9565b6007020160030154915060098460028110611dd257611dd26136f9565b604080516060810191829052926007929092029091016004019060039082845b815481526020019060010190808311611df257505050505090509193909250565b611e1b613227565b6001600160a01b03828116600090815260176020908152604091829020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b815481526020019060010190808311611e8657505050918352505060408051606081019182905260209092019190600484019060039082845b815481526020019060010190808311611ebf575050505050815260200160078201548152602001600882018054611ef59061375b565b80601f0160208091040260200160405190810160405280929190818152602001828054611f219061375b565b8015611f6e5780601f10611f4357610100808354040283529160200191611f6e565b820191906000526020600020905b815481529060010190602001808311611f5157829003601f168201915b5050505050815250509050919050565b6001600160a01b03808216600090815260186020526040812054909116816103e8611fa7610c2c565b611faf61245a565b600854611fbc904261390c565b611fc69190613948565b611fd09190613948565b611fda919061395f565b90506001600160a01b0382161561213d576001600160a01b03821660009081526017602052604090208054600160a01b900460ff1615612137576064600154836120249190613948565b61202e919061395f565b915060005b6003811015612135576000606460028360038110612053576120536136f9565b015461205f9086613948565b612069919061395f565b9050600060148360038110612080576120806136f9565b015461209483670de0b6b3a7640000613948565b61209e919061395f565b600584600381106120b1576120b16136f9565b01546120bd9190613725565b9050670de0b6b3a76400008460040184600381106120dd576120dd6136f9565b01546120e9908361390c565b8560010185600381106120fe576120fe6136f9565b015461210a9190613948565b612114919061395f565b61211e9088613725565b96505050808061212d906138a5565b915050612033565b505b5061219e565b6000546001600160a01b038581169116148015612164575061216160096000610985565b15155b1561219e576064600154606461217a919061390c565b6121849083613948565b61218e919061395f565b60195461219b9190613725565b92505b5050919050565b336121b86000546001600160a01b031690565b6001600160a01b0316146121de5760405162461bcd60e51b81526004016107c6906138d7565b60646121ea8385613725565b111561222d5760405162461bcd60e51b8152602060048201526012602482015271546f74616c20726174696f203e203130302560701b60448201526064016107c6565b8161223984606461390c565b612243919061390c565b6002556003839055600482905560648111156122965760405162461bcd60e51b8152602060048201526012602482015271557365727320726174696f203e203130302560701b60448201526064016107c6565b600181905560025460408051918252602082018590528101839052606081018290527f9644b6174df1bd5bad31e571d2506445b44f89a0ec9f80f86ad150284c317b5a90608001610ef3565b6122ea613227565b6001600160a01b0382811660009081526018602090815260408083205484168084526017835292819020815160e0810183528154958616815260ff600160a01b87048116151594820194909452600160a81b909504909216848201528051606080820192839052939493840191600184019060039082845b81548152602001906001019080831161236257505050918352505060408051606081019182905260209092019190600484019060039082845b81548152602001906001019080831161239b5750505050508152602001600782015481526020016008820180546123d19061375b565b80601f01602080910402602001604051908101604052809291908181526020018280546123fd9061375b565b801561244a5780601f1061241f5761010080835404028352916020019161244a565b820191906000526020600020905b81548152906001019060200180831161242d57829003601f168201915b5050505050815250509150915091565b60007364fa36acd0d13472fd786b03afc9c52ad5fcf0236001600160a01b031663da5b4ee76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c7e573d6000803e3d6000fd5b6005816003811061073257600080fd5b336124d16000546001600160a01b031690565b6001600160a01b0316146124f75760405162461bcd60e51b81526004016107c6906138d7565b612517739fae2529863bd691b4a7171bdfcf33c7ebb10a65333084612cce565b60005b60038110156125d857600060646002836003811061253a5761253a6136f9565b01546125469085613948565b612550919061395f565b9050600060148360038110612567576125676136f9565b0154905080156125c3578061258483670de0b6b3a7640000613948565b61258e919061395f565b600584600381106125a1576125a16136f9565b01546125ad9190613725565b600584600381106125c0576125c06136f9565b01555b505080806125d0906138a5565b91505061251a565b5050565b336125ef6000546001600160a01b031690565b6001600160a01b0316146126155760405162461bcd60e51b81526004016107c6906138d7565b61261d611493565b6001600160a01b03808216600090815260176020526040902080549091161580159061265257508054600160a01b900460ff16155b61266e5760405162461bcd60e51b81526004016107c69061391f565b8054600160a81b900460ff166009816002811061268d5761268d6136f9565b60070201600201546126ab60098360028110610985576109856136f9565b106126ea5760405162461bcd60e51b815260206004820152600f60248201526e105b1b081b9bd9195cc81859191959608a1b60448201526064016107c6565b61270b8360098360028110612701576127016136f9565b60070201906131b5565b6127515760405162461bcd60e51b8152602060048201526017602482015276105d5d1a1bdc9a5d1e48185b1c9958591e481859191959604a1b60448201526064016107c6565b60098160028110612764576127646136f9565b60070201600301600081548092919061277c90613a87565b9091555050600182015460098260028110612799576127996136f9565b600702016004016000600381106127b2576127b26136f9565b0160008282546127c29190613725565b909155505060018083010154600982600281106127e1576127e16136f9565b600702016004016001600381106127fa576127fa6136f9565b01600082825461280a9190613725565b9091555050600382015460098260028110612827576128276136f9565b60070201600401600260038110612840576128406136f9565b0160008282546128509190613725565b909155505060018190036128705761286e600483016005600361330a565b505b815460ff60a01b1916600160a01b1782556040516001600160a01b038416907f7dc8b937d2916b130743c447af3d771fa55e66b7393105150e2e635ac3e8726090600090a2505050565b336128cd6000546001600160a01b031690565b6001600160a01b0316146128f35760405162461bcd60e51b81526004016107c6906138d7565b6001600160a01b0381166129585760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107c6565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038082166000908152601860205260408120549091168015612aac576001600160a01b03811660009081526017602052604090208054600160a01b900460ff1615612aa65760005b6003811015612a9357670de0b6b3a7640000826004018260038110612a2957612a296136f9565b015460058360038110612a3e57612a3e6136f9565b0154612a4a919061390c565b836001018360038110612a5f57612a5f6136f9565b0154612a6b9190613948565b612a75919061395f565b612a7f9085613725565b935080612a8b816138a5565b915050612a02565b50612aa4600482016005600361330a565b505b50612ae4565b6000546001600160a01b038481169116148015612ad35750612ad060096000610985565b15155b15612ae45760198054600090915591505b8115612b0957612b09739fae2529863bd691b4a7171bdfcf33c7ebb10a658484612e8f565b505050565b6969e10de76676d0800000831015612b595760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f75676820434c4f60901b60448201526064016107c6565b691fc3842bd1f071c00000821015612ba55760405162461bcd60e51b815260206004820152600f60248201526e4e6f7420656e6f75676820434c4f4560881b60448201526064016107c6565b69054b40b1f852bda00000811015612bf05760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f75676820534f5960901b60448201526064016107c6565b6a0422ca8b0a00a425000000831115612c3a5760405162461bcd60e51b815260206004820152600c60248201526b546f6f206d616e7920434c4f60a01b60448201526064016107c6565b6a013da329b6336471800000821115612c855760405162461bcd60e51b815260206004820152600d60248201526c546f6f206d616e7920434c4f4560981b60448201526064016107c6565b6934f086f3b33b68400000811115612b095760405162461bcd60e51b815260206004820152600c60248201526b546f6f206d616e7920534f5960a01b60448201526064016107c6565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612d329190613a9e565b6000604051808303816000865af19150503d8060008114612d6f576040519150601f19603f3d011682016040523d82523d6000602084013e612d74565b606091505b5091509150818015612d9e575080511580612d9e575080806020019051810190612d9e9190613aba565b612df65760405162461bcd60e51b8152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416044820152631253115160e21b60648201526084016107c6565b505050505050565b81546000908210612e5c5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b60648201526084016107c6565b826000018281548110612e7157612e716136f9565b6000918252602090912001546001600160a01b031690505b92915050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691612eeb9190613a9e565b6000604051808303816000865af19150503d8060008114612f28576040519150601f19603f3d011682016040523d82523d6000602084013e612f2d565b606091505b5091509150818015612f57575080511580612f57575080806020019051810190612f579190613aba565b612fa35760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016107c6565b5050505050565b6001600160a01b038116600090815260018301602052604081205480156130e2576000612fd860018361390c565b8554909150600090612fec9060019061390c565b90506000866000018281548110613005576130056136f9565b60009182526020909120015487546001600160a01b0390911691508190889085908110613034576130346136f9565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055613068836001613725565b6001600160a01b0382166000908152600189016020526040902055865487908061309457613094613ad7565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220919091559450612e899350505050565b6000915050612e89565b604080516000808252602082019092526001600160a01b0384169083906040516131169190613a9e565b60006040518083038185875af1925050503d8060008114613153576040519150601f19603f3d011682016040523d82523d6000602084013e613158565b606091505b5050905080612b095760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b60648201526084016107c6565b6001600160a01b038116600090815260018301602052604081205461321f57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b03861690811790915585549082528286019093526040902091909155612e89565b506000612e89565b6040805160e08101825260008082526020820181905291810191909152606081016132506132ec565b815260200161325d6132ec565b815260200160008152602001606081525090565b826003810192821561329f579160200282015b8281111561329f578251825591602001919060010190613284565b506132ab929150613335565b5090565b5080546132bb9061375b565b6000825580601f106132cb575050565b601f0160209004906000526020600020908101906132e99190613335565b50565b60405180606001604052806003906020820280368337509192915050565b826003810192821561329f579182015b8281111561329f57825482559160010191906001019061331a565b5b808211156132ab5760008155600101613336565b60006020828403121561335c57600080fd5b5035919050565b6000806040838503121561337657600080fd5b50508035926020909101359150565b8060005b60038110156133a8578151845260209384019390910190600101613389565b50505050565b60005b838110156133c95781810151838201526020016133b1565b50506000910152565b600061016060018060a01b03835116845260208301511515602085015260ff6040840151166040850152606083015161340e6060860182613385565b50608083015161342160c0860182613385565b5060a083015161012085015260c08301518161014086015280518083870152610180925061345581848801602085016133ae565b601f01601f191694909401019392505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b838110156134bf57605f198887030185526134ad8683516133d2565b95509382019390820190600101613491565b50508584038187015286518085528782019482019350915060005b828110156134ff5784516001600160a01b0316845293810193928101926001016134da565b5091979650505050505050565b80356001600160a01b038116811461352357600080fd5b919050565b6000806040838503121561353b57600080fd5b6135448361350c565b91506135526020840161350c565b90509250929050565b60006020828403121561356d57600080fd5b6135768261350c565b9392505050565b80151581146132e957600080fd5b6000806040838503121561359e57600080fd5b8235915060208301356135b08161357d565b809150509250929050565b6040815260006135ce60408301856133d2565b905060018060a01b03831660208301529392505050565b6000806000806000608086880312156135fd57600080fd5b85359450602086013593506136146040870161350c565b9250606086013567ffffffffffffffff8082111561363157600080fd5b818801915088601f83011261364557600080fd5b81358181111561365457600080fd5b89602082850101111561366657600080fd5b9699959850939650602001949392505050565b838152602080820184905260a0820190604083018460005b60038110156136ae57815183529183019190830190600101613691565b50505050949350505050565b60208152600061357660208301846133d2565b6000806000606084860312156136e257600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115612e8957612e8961370f565b8060005b60038110156133a857815484526020909301926001918201910161373c565b600181811c9082168061376f57607f821691505b60208210810361378f57634e487b7160e01b600052602260045260246000fd5b50919050565b600081546137a28161375b565b8085526020600183811680156137bf57600181146137d957613807565b60ff1985168884015283151560051b880183019550613807565b866000528260002060005b858110156137ff5781548a82018601529083019084016137e4565b890184019650505b505050505092915050565b602081526000825460018060a01b038116602084015260ff8160a01c161515604084015261384b6060840160ff8360a81c1660ff169052565b5061385c6080830160018501613738565b61386c60e0830160048501613738565b600783015461014083015261016080830152613576610180830160088501613795565b634e487b7160e01b600052604160045260246000fd5b6000600182016138b7576138b761370f565b5060010190565b6000602082840312156138d057600080fd5b5051919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b81810381811115612e8957612e8961370f565b6020808252600f908201526e77726f6e6720617574686f7269747960881b604082015260600190565b8082028115828204841417612e8957612e8961370f565b60008261397c57634e487b7160e01b600052601260045260246000fd5b500490565b601f821115612b0957600081815260208120601f850160051c810160208610156139a85750805b601f850160051c820191505b81811015612df6578281556001016139b4565b815167ffffffffffffffff8111156139e1576139e161388f565b6139f5816139ef845461375b565b84613981565b602080601f831160018114613a2a5760008415613a125750858301515b600019600386901b1c1916600185901b178555612df6565b600085815260208120601f198616915b82811015613a5957888601518255948401946001909101908401613a3a565b5085821015613a775787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600081613a9657613a9661370f565b506000190190565b60008251613ab08184602087016133ae565b9190910192915050565b600060208284031215613acc57600080fd5b81516135768161357d565b634e487b7160e01b600052603160045260246000fdfea264697066735822122077301dcae5bd1561f06f6f40c5a502225beb65a920db5b23a18b8d1e96a73a9f64736f6c63430008110033
Deployed ByteCode
0x60806040526004361061022f5760003560e01c8063b199892a1161012e578063da5b4ee7116100ab578063ebd5f9e11161006f578063ebd5f9e11461067a578063f2fde38b14610698578063f8077fae146106b8578063fcceb25a146106ce578063feac1200146106ec57600080fd5b8063da5b4ee7146105ef578063e173bd4514610604578063e22733a214610624578063e80233c614610644578063ea5c285d1461066457600080fd5b8063bbebdcc0116100f2578063bbebdcc014610544578063c00007b014610571578063c23bdaa714610591578063cdfdb7dc146105af578063d096a21b146105cf57600080fd5b8063b199892a146104a3578063b2b99ec9146104b6578063b81c806a146104d6578063b88a802f14610500578063b93a89f71461051557600080fd5b80634f3a1ff8116101bc57806374d43ac41161018057806374d43ac4146104055780638129fc1c146104335780638da5cb5b14610448578063a2e6204514610466578063a9622dc51461047b57600080fd5b80634f3a1ff81461033e5780635b17f5061461037e5780635d799f87146103a657806365814455146103c657806370a1579e146103e657600080fd5b806318a75f521161020357806318a75f52146102b65780631e29653c146102d45780632f4860c9146102e957806336f3d514146102ff5780633c6b16ab1461031e57600080fd5b80628df454146102345780630102609914610267578063135e5d891461027c578063141e93be1461029f575b600080fd5b34801561024057600080fd5b5061025461024f36600461334a565b610722565b6040519081526020015b60405180910390f35b61027a610275366004613363565b610739565b005b34801561028857600080fd5b50610291610979565b60405161025e929190613468565b3480156102ab57600080fd5b506102546212750081565b3480156102c257600080fd5b506102546934f086f3b33b6840000081565b3480156102e057600080fd5b50610254610c2c565b3480156102f557600080fd5b5061025460195481565b34801561030b57600080fd5b506102546a013da329b633647180000081565b34801561032a57600080fd5b5061027a61033936600461334a565b610ca7565b34801561034a57600080fd5b506103667364fa36acd0d13472fd786b03afc9c52ad5fcf02381565b6040516001600160a01b03909116815260200161025e565b34801561038a57600080fd5b50610366739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b3480156103b257600080fd5b5061027a6103c1366004613528565b610d41565b3480156103d257600080fd5b5061027a6103e136600461355b565b610f00565b3480156103f257600080fd5b506102546a0422ca8b0a00a42500000081565b34801561041157600080fd5b5061042561042036600461358b565b611200565b60405161025e9291906135bb565b34801561043f57600080fd5b5061027a611399565b34801561045457600080fd5b506000546001600160a01b0316610366565b34801561047257600080fd5b5061027a611493565b34801561048757600080fd5b50610366731eaa43544daa399b87eecfcc6fa579d5ea4a618781565b61027a6104b13660046135e5565b611658565b3480156104c257600080fd5b5061027a6104d136600461355b565b611aa5565b3480156104e257600080fd5b506104eb611d45565b6040805192835260208301919091520161025e565b34801561050c57600080fd5b5061027a611d67565b34801561052157600080fd5b5061053561053036600461334a565b611d7a565b60405161025e93929190613679565b34801561055057600080fd5b5061056461055f36600461355b565b611e13565b60405161025e91906136ba565b34801561057d57600080fd5b5061025461058c36600461355b565b611f7e565b34801561059d57600080fd5b5061025469054b40b1f852bda0000081565b3480156105bb57600080fd5b5061027a6105ca3660046136cd565b6121a5565b3480156105db57600080fd5b506104256105ea36600461355b565b6122e2565b3480156105fb57600080fd5b5061025461245a565b34801561061057600080fd5b5061025461061f36600461334a565b6124ae565b34801561063057600080fd5b5061027a61063f36600461334a565b6124be565b34801561065057600080fd5b5061027a61065f36600461355b565b6125dc565b34801561067057600080fd5b5061025460015481565b34801561068657600080fd5b506102546969e10de76676d080000081565b3480156106a457600080fd5b5061027a6106b336600461355b565b6128ba565b3480156106c457600080fd5b5061025460085481565b3480156106da57600080fd5b50610254691fc3842bd1f071c0000081565b3480156106f857600080fd5b5061036661070736600461355b565b6018602052600090815260409020546001600160a01b031681565b6002816003811061073257600080fd5b0154905081565b610741611493565b61074a336129b3565b336000908152601860209081526040808320546001600160a01b03168084526017909252909120811580159061078b57508054600160a81b900460ff166001145b6107cf5760405162461bcd60e51b815260206004820152601060248201526f4f6e6c7920757365722773206e6f646560801b60448201526064015b60405180910390fd5b8054600160a01b900460ff166108145760405162461bcd60e51b815260206004820152600a6024820152694e6f742061637469766560b01b60448201526064016107c6565b600181015461084a906108279034613725565b60028301546108369087613725565b60038401546108459087613725565b612b0e565b61086a731eaa43544daa399b87eecfcc6fa579d5ea4a6187333087612cce565b61088a739fae2529863bd691b4a7171bdfcf33c7ebb10a65333086612cce565b346001820160000160008282546108a19190613725565b9091555084905060018083010160008282546108bd9190613725565b909155508390506001820160020160008282546108da9190613725565b90915550349050601460000160008282546108f59190613725565b90915550849050601460010160008282546109109190613725565b909155508390506014600201600082825461092b9190613725565b92505081905550816001600160a01b03167f6f7579464656d5010911f2a5ddf87eaa7149e87a41834055e651366a6e8f3ec08260405161096b9190613812565b60405180910390a250505050565b606080600061098d6009825b600702015490565b90508067ffffffffffffffff8111156109a8576109a861388f565b6040519080825280602002602001820160405280156109d1578160200160208202803683370190505b5091508067ffffffffffffffff8111156109ed576109ed61388f565b604051908082528060200260200182016040528015610a2657816020015b610a13613227565b815260200190600190039081610a0b5790505b50925060005b81811015610c2657610a4781600960005b6007020190612dfe565b838281518110610a5957610a596136f9565b60200260200101906001600160a01b031690816001600160a01b03168152505060176000848381518110610a8f57610a8f6136f9565b6020908102919091018101516001600160a01b039081168352828201939093526040918201600020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b815481526020019060010190808311610b0557505050918352505060408051606081019182905260209092019190600484019060039082845b815481526020019060010190808311610b3e575050505050815260200160078201548152602001600882018054610b749061375b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ba09061375b565b8015610bed5780601f10610bc257610100808354040283529160200191610bed565b820191906000526020600020905b815481529060010190602001808311610bd057829003601f168201915b505050505081525050848281518110610c0857610c086136f9565b60200260200101819052508080610c1e906138a5565b915050610a2c565b50509091565b60405163389bbbfd60e21b81523060048201526000907364fa36acd0d13472fd786b03afc9c52ad5fcf0239063e26eeff490602401602060405180830381865afa158015610c7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca291906138be565b905090565b337364fa36acd0d13472fd786b03afc9c52ad5fcf02314610cfc5760405162461bcd60e51b815260206004820152600f60248201526e4f6e6c7920676c6f62616c4661726d60881b60448201526064016107c6565b600854600003610d0b57426008555b6040518181527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a150565b33610d546000546001600160a01b031690565b6001600160a01b031614610d7a5760405162461bcd60e51b81526004016107c6906138d7565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610dc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de591906138be565b9050731eaa43544daa399b87eecfcc6fa579d5ea4a6186196001600160a01b03841601610e2d57601554600e54610e1c908361390c565b610e26919061390c565b9050610e9b565b739fae2529863bd691b4a7171bdfcf33c7ebb10a64196001600160a01b03841601610e9b57600f54158015610e625750601654155b610e9b5760405162461bcd60e51b815260206004820152600a602482015269534f5920696e2075736560b01b60448201526064016107c6565b610eaf6001600160a01b0384168383612e8f565b604080516001600160a01b038086168252841660208201529081018290527f9b793652de97f04c5168920587bad4b1c6345295a8f5ad31c59ff946a26f91d2906060015b60405180910390a1505050565b610f08611493565b6001600160a01b038082166000908152601760205260409020805490911615801590610f3c57508054600160a01b900460ff165b610f585760405162461bcd60e51b81526004016107c69061391f565b8054600160a81b900460ff166000819003610f8b5760005482546001600160a01b0319166001600160a01b039091161782555b81546001600160a01b0316331480610fbc575033610fb16000546001600160a01b031690565b6001600160a01b0316145b6110085760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206e6f6465206f7220636f6e7472616374206f776e6572000000000060448201526064016107c6565b80600103611029578154611024906001600160a01b03166129b3565b611043565b61104361103e6000546001600160a01b031690565b6129b3565b611064836009836002811061105a5761105a6136f9565b6007020190612faa565b6110a65760405162461bcd60e51b8152602060048201526013602482015272105d5d1a1bdc9a5d1e481b9bdd08195e1a5cdd606a1b60448201526064016107c6565b600981600281106110b9576110b96136f9565b6007020160030160008154809291906110d1906138a5565b90915550506001820154600982600281106110ee576110ee6136f9565b60070201600401600060038110611107576111076136f9565b016000828254611117919061390c565b90915550506001808301015460098260028110611136576111366136f9565b6007020160040160016003811061114f5761114f6136f9565b01600082825461115f919061390c565b909155505060038201546009826002811061117c5761117c6136f9565b60070201600401600260038110611195576111956136f9565b0160008282546111a5919061390c565b9091555050815460ff60a01b191682556111c26212750042613725565b60078301556040516001600160a01b038416907fd9957750e6343405c319eb99a4ec67fa11cfd66969318cbc71aa2d45fa53a34990600090a2505050565b611208613227565b600082156112245761121d8460096001610a3d565b9050611234565b6112318460096000610a3d565b90505b6001600160a01b03818116600090815260176020908152604091829020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b81548152602001906001019080831161129f57505050918352505060408051606081019182905260209092019190600484019060039082845b8154815260200190600101908083116112d857505050505081526020016007820154815260200160088201805461130e9061375b565b80601f016020809104026020016040519081016040528092919081815260200182805461133a9061375b565b80156113875780601f1061135c57610100808354040283529160200191611387565b820191906000526020600020905b81548152906001019060200180831161136a57829003601f168201915b50505050508152505091509250929050565b6000546001600160a01b0316156113e85760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016107c6565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3603e6002819055601b6003819055600b6004819055604160018190556040805194855260208501939093529183015260608201527f9644b6174df1bd5bad31e571d2506445b44f89a0ec9f80f86ad150284c317b5a9060800160405180910390a1600b8055600a601255565b60405163032453f160e51b81523060048201527364fa36acd0d13472fd786b03afc9c52ad5fcf0239063648a7e2090602401600060405180830381600087803b1580156114df57600080fd5b505af11580156114f3573d6000803e3d6000fd5b50505050600854421161150257565b60085460000361150e57565b60006008544261151e919061390c565b905060006103e861152d610c2c565b61153561245a565b61153f9085613948565b6115499190613948565b611553919061395f565b905060006064600154836115679190613948565b611571919061395f565b905061157d818361390c565b60195461158a9190613725565b60195560005b600381101561164e5760006064600283600381106115b0576115b06136f9565b01546115bc9085613948565b6115c6919061395f565b90506000601483600381106115dd576115dd6136f9565b01549050801561163957806115fa83670de0b6b3a7640000613948565b611604919061395f565b60058460038110611617576116176136f9565b01546116239190613725565b60058460038110611636576116366136f9565b01555b50508080611646906138a5565b915050611590565b5050426008555050565b611663348686612b0e565b6000336116786000546001600160a01b031690565b6001600160a01b03161461177857336000908152601860205260409020546001600160a01b0316156116e45760405162461bcd60e51b81526020600482015260156024820152745573657220616c726561647920686173206e6f646560581b60448201526064016107c6565b6001600160a01b03848116600090815260176020526040902054161561174c5760405162461bcd60e51b815260206004820152601760248201527f617574686f7269747920616c726561647920616464656400000000000000000060448201526064016107c6565b5033600090815260186020526040902080546001600160a01b0319166001600160a01b03851617905560015b6009816002811061178b5761178b6136f9565b60070201600201546117a960098360028110610985576109856136f9565b106117e85760405162461bcd60e51b815260206004820152600f60248201526e105b1b081b9bd9195cc81859191959608a1b60448201526064016107c6565b61182584600983600281106117ff576117ff6136f9565b60070201906001600160a01b031660009081526001919091016020526040902054151590565b1561186c5760405162461bcd60e51b8152602060048201526017602482015276105d5d1a1bdc9a5d1e48185b1c9958591e481859191959604a1b60448201526064016107c6565b6009816002811061187f5761187f6136f9565b600702016003016000815480929190611897906138a5565b909155506118bd9050731eaa43544daa399b87eecfcc6fa579d5ea4a6187333089612cce565b6118dd739fae2529863bd691b4a7171bdfcf33c7ebb10a65333088612cce565b60006040518060e00160405280336001600160a01b031681526020016000151581526020018360ff16815260200160405180606001604052803481526020018a81526020018981525081526020016040518060600160405280600081526020016000815260200160008152508152602001621275004261195d9190613725565b815260200185858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250506001600160a01b0380891682526017602090815260409283902085518154928701519487015160ff16600160a81b0260ff60a81b19951515600160a01b026001600160a81b03199094169190941617919091179290921617815560608301519293508392909150611a119060018301906003613271565b506080820151611a279060048301906003613271565b5060a0820151600782015560c08201516008820190611a4690826139c7565b50905050846001600160a01b03167fb6b552e59896e4d58bd65ecce8af2a09e960820e2a6876d694f15471430d5ca582604051611a8391906136ba565b60405180910390a281600003611a9c57611a9c856125dc565b50505050505050565b611aad611493565b6001600160a01b03808216600090815260176020526040902080549091168015801590611ae357508154600160a01b900460ff16155b611aff5760405162461bcd60e51b81526004016107c69061391f565b8154600160a81b900460ff166000819003611b23576000546001600160a01b031691505b6001600160a01b038216331480611b53575033611b486000546001600160a01b031690565b6001600160a01b0316145b611b9f5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206e6f6465206f7220636f6e7472616374206f776e6572000000000060448201526064016107c6565b4283600701541115611be45760405162461bcd60e51b815260206004820152600e60248201526d139bd919481a5cc81b1bd8dad95960921b60448201526064016107c6565b8254600990600160a81b900460ff1660028110611c0357611c036136f9565b600702016003016000815480929190611c1b90613a87565b90915550506001838101546002808601546003808801546001600160a01b038a16600090815260176020526040812080546001600160b01b0319168155968701819055938601849055908501839055600485018390556005850183905560068501839055600785018390559293909291611c9860088301826132af565b50506001600160a01b038516600081815260186020526040902080546001600160a01b0319169055611cca90846130ec565b611ce9731eaa43544daa399b87eecfcc6fa579d5ea4a61878684612e8f565b611d08739fae2529863bd691b4a7171bdfcf33c7ebb10a658683612e8f565b6040516001600160a01b038816907fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b90600090a250505050505050565b600080611d53600982610985565b9150611d6160096001610985565b90509091565b611d6f611493565b611d78336129b3565b565b600080611d856132ec565b60098460028110611d9857611d986136f9565b6007020160020154925060098460028110611db557611db56136f9565b6007020160030154915060098460028110611dd257611dd26136f9565b604080516060810191829052926007929092029091016004019060039082845b815481526020019060010190808311611df257505050505090509193909250565b611e1b613227565b6001600160a01b03828116600090815260176020908152604091829020825160e0810184528154948516815260ff600160a01b86048116151593820193909352600160a81b909404909116838301528151606080820193849052919291840191600184019060039082845b815481526020019060010190808311611e8657505050918352505060408051606081019182905260209092019190600484019060039082845b815481526020019060010190808311611ebf575050505050815260200160078201548152602001600882018054611ef59061375b565b80601f0160208091040260200160405190810160405280929190818152602001828054611f219061375b565b8015611f6e5780601f10611f4357610100808354040283529160200191611f6e565b820191906000526020600020905b815481529060010190602001808311611f5157829003601f168201915b5050505050815250509050919050565b6001600160a01b03808216600090815260186020526040812054909116816103e8611fa7610c2c565b611faf61245a565b600854611fbc904261390c565b611fc69190613948565b611fd09190613948565b611fda919061395f565b90506001600160a01b0382161561213d576001600160a01b03821660009081526017602052604090208054600160a01b900460ff1615612137576064600154836120249190613948565b61202e919061395f565b915060005b6003811015612135576000606460028360038110612053576120536136f9565b015461205f9086613948565b612069919061395f565b9050600060148360038110612080576120806136f9565b015461209483670de0b6b3a7640000613948565b61209e919061395f565b600584600381106120b1576120b16136f9565b01546120bd9190613725565b9050670de0b6b3a76400008460040184600381106120dd576120dd6136f9565b01546120e9908361390c565b8560010185600381106120fe576120fe6136f9565b015461210a9190613948565b612114919061395f565b61211e9088613725565b96505050808061212d906138a5565b915050612033565b505b5061219e565b6000546001600160a01b038581169116148015612164575061216160096000610985565b15155b1561219e576064600154606461217a919061390c565b6121849083613948565b61218e919061395f565b60195461219b9190613725565b92505b5050919050565b336121b86000546001600160a01b031690565b6001600160a01b0316146121de5760405162461bcd60e51b81526004016107c6906138d7565b60646121ea8385613725565b111561222d5760405162461bcd60e51b8152602060048201526012602482015271546f74616c20726174696f203e203130302560701b60448201526064016107c6565b8161223984606461390c565b612243919061390c565b6002556003839055600482905560648111156122965760405162461bcd60e51b8152602060048201526012602482015271557365727320726174696f203e203130302560701b60448201526064016107c6565b600181905560025460408051918252602082018590528101839052606081018290527f9644b6174df1bd5bad31e571d2506445b44f89a0ec9f80f86ad150284c317b5a90608001610ef3565b6122ea613227565b6001600160a01b0382811660009081526018602090815260408083205484168084526017835292819020815160e0810183528154958616815260ff600160a01b87048116151594820194909452600160a81b909504909216848201528051606080820192839052939493840191600184019060039082845b81548152602001906001019080831161236257505050918352505060408051606081019182905260209092019190600484019060039082845b81548152602001906001019080831161239b5750505050508152602001600782015481526020016008820180546123d19061375b565b80601f01602080910402602001604051908101604052809291908181526020018280546123fd9061375b565b801561244a5780601f1061241f5761010080835404028352916020019161244a565b820191906000526020600020905b81548152906001019060200180831161242d57829003601f168201915b5050505050815250509150915091565b60007364fa36acd0d13472fd786b03afc9c52ad5fcf0236001600160a01b031663da5b4ee76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c7e573d6000803e3d6000fd5b6005816003811061073257600080fd5b336124d16000546001600160a01b031690565b6001600160a01b0316146124f75760405162461bcd60e51b81526004016107c6906138d7565b612517739fae2529863bd691b4a7171bdfcf33c7ebb10a65333084612cce565b60005b60038110156125d857600060646002836003811061253a5761253a6136f9565b01546125469085613948565b612550919061395f565b9050600060148360038110612567576125676136f9565b0154905080156125c3578061258483670de0b6b3a7640000613948565b61258e919061395f565b600584600381106125a1576125a16136f9565b01546125ad9190613725565b600584600381106125c0576125c06136f9565b01555b505080806125d0906138a5565b91505061251a565b5050565b336125ef6000546001600160a01b031690565b6001600160a01b0316146126155760405162461bcd60e51b81526004016107c6906138d7565b61261d611493565b6001600160a01b03808216600090815260176020526040902080549091161580159061265257508054600160a01b900460ff16155b61266e5760405162461bcd60e51b81526004016107c69061391f565b8054600160a81b900460ff166009816002811061268d5761268d6136f9565b60070201600201546126ab60098360028110610985576109856136f9565b106126ea5760405162461bcd60e51b815260206004820152600f60248201526e105b1b081b9bd9195cc81859191959608a1b60448201526064016107c6565b61270b8360098360028110612701576127016136f9565b60070201906131b5565b6127515760405162461bcd60e51b8152602060048201526017602482015276105d5d1a1bdc9a5d1e48185b1c9958591e481859191959604a1b60448201526064016107c6565b60098160028110612764576127646136f9565b60070201600301600081548092919061277c90613a87565b9091555050600182015460098260028110612799576127996136f9565b600702016004016000600381106127b2576127b26136f9565b0160008282546127c29190613725565b909155505060018083010154600982600281106127e1576127e16136f9565b600702016004016001600381106127fa576127fa6136f9565b01600082825461280a9190613725565b9091555050600382015460098260028110612827576128276136f9565b60070201600401600260038110612840576128406136f9565b0160008282546128509190613725565b909155505060018190036128705761286e600483016005600361330a565b505b815460ff60a01b1916600160a01b1782556040516001600160a01b038416907f7dc8b937d2916b130743c447af3d771fa55e66b7393105150e2e635ac3e8726090600090a2505050565b336128cd6000546001600160a01b031690565b6001600160a01b0316146128f35760405162461bcd60e51b81526004016107c6906138d7565b6001600160a01b0381166129585760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107c6565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038082166000908152601860205260408120549091168015612aac576001600160a01b03811660009081526017602052604090208054600160a01b900460ff1615612aa65760005b6003811015612a9357670de0b6b3a7640000826004018260038110612a2957612a296136f9565b015460058360038110612a3e57612a3e6136f9565b0154612a4a919061390c565b836001018360038110612a5f57612a5f6136f9565b0154612a6b9190613948565b612a75919061395f565b612a7f9085613725565b935080612a8b816138a5565b915050612a02565b50612aa4600482016005600361330a565b505b50612ae4565b6000546001600160a01b038481169116148015612ad35750612ad060096000610985565b15155b15612ae45760198054600090915591505b8115612b0957612b09739fae2529863bd691b4a7171bdfcf33c7ebb10a658484612e8f565b505050565b6969e10de76676d0800000831015612b595760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f75676820434c4f60901b60448201526064016107c6565b691fc3842bd1f071c00000821015612ba55760405162461bcd60e51b815260206004820152600f60248201526e4e6f7420656e6f75676820434c4f4560881b60448201526064016107c6565b69054b40b1f852bda00000811015612bf05760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f75676820534f5960901b60448201526064016107c6565b6a0422ca8b0a00a425000000831115612c3a5760405162461bcd60e51b815260206004820152600c60248201526b546f6f206d616e7920434c4f60a01b60448201526064016107c6565b6a013da329b6336471800000821115612c855760405162461bcd60e51b815260206004820152600d60248201526c546f6f206d616e7920434c4f4560981b60448201526064016107c6565b6934f086f3b33b68400000811115612b095760405162461bcd60e51b815260206004820152600c60248201526b546f6f206d616e7920534f5960a01b60448201526064016107c6565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612d329190613a9e565b6000604051808303816000865af19150503d8060008114612d6f576040519150601f19603f3d011682016040523d82523d6000602084013e612d74565b606091505b5091509150818015612d9e575080511580612d9e575080806020019051810190612d9e9190613aba565b612df65760405162461bcd60e51b8152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416044820152631253115160e21b60648201526084016107c6565b505050505050565b81546000908210612e5c5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b60648201526084016107c6565b826000018281548110612e7157612e716136f9565b6000918252602090912001546001600160a01b031690505b92915050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691612eeb9190613a9e565b6000604051808303816000865af19150503d8060008114612f28576040519150601f19603f3d011682016040523d82523d6000602084013e612f2d565b606091505b5091509150818015612f57575080511580612f57575080806020019051810190612f579190613aba565b612fa35760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016107c6565b5050505050565b6001600160a01b038116600090815260018301602052604081205480156130e2576000612fd860018361390c565b8554909150600090612fec9060019061390c565b90506000866000018281548110613005576130056136f9565b60009182526020909120015487546001600160a01b0390911691508190889085908110613034576130346136f9565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055613068836001613725565b6001600160a01b0382166000908152600189016020526040902055865487908061309457613094613ad7565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220919091559450612e899350505050565b6000915050612e89565b604080516000808252602082019092526001600160a01b0384169083906040516131169190613a9e565b60006040518083038185875af1925050503d8060008114613153576040519150601f19603f3d011682016040523d82523d6000602084013e613158565b606091505b5050905080612b095760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b60648201526084016107c6565b6001600160a01b038116600090815260018301602052604081205461321f57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b03861690811790915585549082528286019093526040902091909155612e89565b506000612e89565b6040805160e08101825260008082526020820181905291810191909152606081016132506132ec565b815260200161325d6132ec565b815260200160008152602001606081525090565b826003810192821561329f579160200282015b8281111561329f578251825591602001919060010190613284565b506132ab929150613335565b5090565b5080546132bb9061375b565b6000825580601f106132cb575050565b601f0160209004906000526020600020908101906132e99190613335565b50565b60405180606001604052806003906020820280368337509192915050565b826003810192821561329f579182015b8281111561329f57825482559160010191906001019061331a565b5b808211156132ab5760008155600101613336565b60006020828403121561335c57600080fd5b5035919050565b6000806040838503121561337657600080fd5b50508035926020909101359150565b8060005b60038110156133a8578151845260209384019390910190600101613389565b50505050565b60005b838110156133c95781810151838201526020016133b1565b50506000910152565b600061016060018060a01b03835116845260208301511515602085015260ff6040840151166040850152606083015161340e6060860182613385565b50608083015161342160c0860182613385565b5060a083015161012085015260c08301518161014086015280518083870152610180925061345581848801602085016133ae565b601f01601f191694909401019392505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b838110156134bf57605f198887030185526134ad8683516133d2565b95509382019390820190600101613491565b50508584038187015286518085528782019482019350915060005b828110156134ff5784516001600160a01b0316845293810193928101926001016134da565b5091979650505050505050565b80356001600160a01b038116811461352357600080fd5b919050565b6000806040838503121561353b57600080fd5b6135448361350c565b91506135526020840161350c565b90509250929050565b60006020828403121561356d57600080fd5b6135768261350c565b9392505050565b80151581146132e957600080fd5b6000806040838503121561359e57600080fd5b8235915060208301356135b08161357d565b809150509250929050565b6040815260006135ce60408301856133d2565b905060018060a01b03831660208301529392505050565b6000806000806000608086880312156135fd57600080fd5b85359450602086013593506136146040870161350c565b9250606086013567ffffffffffffffff8082111561363157600080fd5b818801915088601f83011261364557600080fd5b81358181111561365457600080fd5b89602082850101111561366657600080fd5b9699959850939650602001949392505050565b838152602080820184905260a0820190604083018460005b60038110156136ae57815183529183019190830190600101613691565b50505050949350505050565b60208152600061357660208301846133d2565b6000806000606084860312156136e257600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115612e8957612e8961370f565b8060005b60038110156133a857815484526020909301926001918201910161373c565b600181811c9082168061376f57607f821691505b60208210810361378f57634e487b7160e01b600052602260045260246000fd5b50919050565b600081546137a28161375b565b8085526020600183811680156137bf57600181146137d957613807565b60ff1985168884015283151560051b880183019550613807565b866000528260002060005b858110156137ff5781548a82018601529083019084016137e4565b890184019650505b505050505092915050565b602081526000825460018060a01b038116602084015260ff8160a01c161515604084015261384b6060840160ff8360a81c1660ff169052565b5061385c6080830160018501613738565b61386c60e0830160048501613738565b600783015461014083015261016080830152613576610180830160088501613795565b634e487b7160e01b600052604160045260246000fd5b6000600182016138b7576138b761370f565b5060010190565b6000602082840312156138d057600080fd5b5051919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b81810381811115612e8957612e8961370f565b6020808252600f908201526e77726f6e6720617574686f7269747960881b604082015260600190565b8082028115828204841417612e8957612e8961370f565b60008261397c57634e487b7160e01b600052601260045260246000fd5b500490565b601f821115612b0957600081815260208120601f850160051c810160208610156139a85750805b601f850160051c820191505b81811015612df6578281556001016139b4565b815167ffffffffffffffff8111156139e1576139e161388f565b6139f5816139ef845461375b565b84613981565b602080601f831160018114613a2a5760008415613a125750858301515b600019600386901b1c1916600185901b178555612df6565b600085815260208120601f198616915b82811015613a5957888601518255948401946001909101908401613a3a565b5085821015613a775787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600081613a9657613a9661370f565b506000190190565b60008251613ab08184602087016133ae565b9190910192915050565b600060208284031215613acc57600080fd5b81516135768161357d565b634e487b7160e01b600052603160045260246000fdfea264697066735822122077301dcae5bd1561f06f6f40c5a502225beb65a920db5b23a18b8d1e96a73a9f64736f6c63430008110033