Address Details
contract

0x90b55E39810109A6DB63FC5ae55eFAF8D3B40Df7

Contract Name
StakingV2
Creator
0x562e01–dba6b6 at 0xa4dc7c–fbe6bc
Balance
1.000010020201010111 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
12 Transactions
Transfers
13 Transfers
Gas Used
1,216,656
Last Balance Update
14724402
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
StakingV2




Optimization enabled
false
Compiler version
v0.8.0+commit.c7dfd78e




EVM Version
istanbul




Verified at
2022-08-22T18:39:17.759364Z

contracts/StakingV2.sol

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

/// @title A contract to allow users to stake tokens and other assets to earn rewards
/// @author Gilberts Ahumada Cabrera - CHILE
/// @notice Use this contract to manage staking and vesting protocol

contract StakingV2 is ReentrancyGuard {
    /* State variables */
    // @dev Mapping to maintain onwers of this protocol
    /*
    mapping(address => bool) private tokensToStake;

    struct StakingPool{
        IERC20 stakingToken;
        bool state;
        mapping (address => uint256) s_balances;
        mapping(address => bool) hasStaked;
    }
    */
    
    IERC20 public rewardToken;
    IERC20 public stakingToken;

    mapping(address => uint256) public s_balances;
    mapping(address => uint256) public s_rewards;
    mapping(address => uint256) public s_userRewardPerTokenPaid;
    mapping(address => uint256) public s_totalPaidByUser;    
    
    uint256 public constant REWARD_RATE = 10000000000000000000; // 10 x sec
    uint8 public constant RELEASE_LIMIT = 2; // divided by this value - means half
    uint8 public constant RELEASE_TIME = 3 minutes;

    uint256 public s_lastUpdateTime;
    uint256 public s_rewardPerTokenStored;
    uint256 public s_totalStaked;   
    uint256 public s_tokensToGive;    

    address private owner;   
    mapping(address => uint256) private s_lastRedeem;
    mapping(address => uint256) public s_lastRelease;
    mapping(address => uint256) public s_rewardUnlocked;


    constructor(address _stakeToken, address _rewardToken){        
        stakingToken = IERC20(_stakeToken);       
        rewardToken = IERC20(_rewardToken); 
        owner = msg.sender;        
    }


    function stake(uint256 _amount) public nonReentrant updateReward(msg.sender) moreThanZero(_amount){        
        require(stakingToken.balanceOf(msg.sender) >= _amount, "Not Enough Funds to Stake");  
        s_totalStaked += _amount;
        s_balances[msg.sender] += _amount;

        if(s_lastRelease[msg.sender] == 0){
            s_lastRelease[msg.sender] = block.timestamp;
        } 

        bool success = stakingToken.transferFrom(msg.sender, address(this), _amount);                
        require(success, "stake: Error tx");    
    }

    function unStake(uint256 _amount) public nonReentrant updateReward(msg.sender) moreThanZero(_amount){
        require(s_balances[msg.sender] >= _amount, "Amount sent higher than balance staked");                            
        s_totalStaked -= _amount;
        s_balances[msg.sender] -= _amount;
        bool success = rewardToken.transfer(msg.sender, _amount);
        require(success, "unStake: Error tx");               
    }

    function rewardPerToken() public view returns (uint256) {
        if (s_totalStaked == 0) {
            return s_rewardPerTokenStored;
        }
        return
            s_rewardPerTokenStored +
            (((block.timestamp - s_lastUpdateTime) * REWARD_RATE * 1e18) / s_totalStaked);
    }

    // Libera el reward generado hasta ahora
    function releaseReward() external updateReward(msg.sender) nonReentrant {
        require(canRelease(msg.sender),"Can't release");
        uint256 currentTime = block.timestamp;   
        require((currentTime - s_lastRelease[msg.sender]) >= RELEASE_TIME, "Cannot Release Tokens Before 3 days");                
        uint256 unlockedAmount = s_rewards[msg.sender] / RELEASE_LIMIT; 
        s_lastRelease[msg.sender] = currentTime;
        s_rewards[msg.sender] -= unlockedAmount;
        s_rewardUnlocked[msg.sender] += unlockedAmount;
        s_totalPaidByUser[msg.sender] += unlockedAmount;
    }

    // Se transfiere los tokens ganados almacenados en el mapping s_rewardUnlocked
    function claimReward() external nonReentrant{
        require(s_rewardUnlocked[msg.sender] > 0, "Insufficient Unlocked Balance");
        uint256 reward = s_rewardUnlocked[msg.sender];  
        s_rewardUnlocked[msg.sender] = 0;        
        bool success = rewardToken.transfer(msg.sender, reward);
        require(success, "ClaimReward: Error tx");         
    }

    function earnedWithLimit(address _staker) public view returns(uint256){        
        return ( earned(_staker) / RELEASE_LIMIT);         
    }

    function earned(address account) public view returns (uint256) {
        return
            ((s_balances[account] * (rewardPerToken() - s_userRewardPerTokenPaid[account])) /
                1e18) + s_rewards[account];
    }

    function unlockedBalance(address account) public view returns(uint256){
        return s_rewardUnlocked[account];
    }

    function whenNextRelease(address _staker) public view returns(int256){
        require(s_lastRelease[_staker] != 0, "User has not staked");
        uint256 diffTodayLastRelease = block.timestamp - s_lastRelease[_staker];
        int256 result = int256(diffTodayLastRelease) - RELEASE_TIME;
        return result;
        //
    }

    function canRelease(address _staker) public view returns(bool){
        require(s_lastRelease[_staker] != 0, "User has not staked");
        if((block.timestamp - s_lastRelease[_staker]) > RELEASE_TIME)
            return true;
        else
            return false;
    }
    
    modifier updateReward(address _account){
        s_rewardPerTokenStored = rewardPerToken();
        s_lastUpdateTime = block.timestamp;
        s_rewards[_account] = earned(_account);
        s_userRewardPerTokenPaid[_account] = s_rewardPerTokenStored;        
        _;
    }    

    function totalTokensToBeRewarded() public view returns(uint256){
        return rewardToken.balanceOf(address(this));
    }

    function withDrawEmergency() external onlyOwner returns(bool success){
        success = rewardToken.transfer(msg.sender, rewardToken.balanceOf(address(this)));
        return success;
    }

    /* Owner Seciton */
    function changeOwner(address _newOwner) public onlyOwner {
        owner = _newOwner;
    }

    function totalStaked() public view returns (uint256){
        return s_totalStaked;
    }

    /* Modifiers Seciton */

    modifier onlyOwner() {
        require(owner == msg.sender, "Only owner can call this function");
        _;
    }

    modifier moreThanZero(uint256 amount){        
        require(amount > 0, "Amount must be > 0");
        _;
    }
}
        

/_openzeppelin/contracts/interfaces/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.0;

import "../token/ERC20/IERC20.sol";
          

/_openzeppelin/contracts/security/ReentrancyGuard.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}
          

/_openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}
          

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_stakeToken","internalType":"address"},{"type":"address","name":"_rewardToken","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"RELEASE_LIMIT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"RELEASE_TIME","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"REWARD_RATE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"canRelease","inputs":[{"type":"address","name":"_staker","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeOwner","inputs":[{"type":"address","name":"_newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"earned","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"earnedWithLimit","inputs":[{"type":"address","name":"_staker","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"releaseReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardPerToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"rewardToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_balances","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_lastRelease","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_lastUpdateTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_rewardPerTokenStored","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_rewardUnlocked","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_rewards","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_tokensToGive","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_totalPaidByUser","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_totalStaked","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"s_userRewardPerTokenPaid","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stake","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"stakingToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalStaked","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalTokensToBeRewarded","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unStake","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"unlockedBalance","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"whenNextRelease","inputs":[{"type":"address","name":"_staker","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"withDrawEmergency","inputs":[]}]
              

Contract Creation Code

0x60806040523480156200001157600080fd5b506040516200274f3803806200274f833981810160405281019062000037919062000121565b600160008190555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050620001b0565b6000815190506200011b8162000196565b92915050565b600080604083850312156200013557600080fd5b600062000145858286016200010a565b925050602062000158858286016200010a565b9150509250929050565b60006200016f8262000176565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620001a18162000162565b8114620001ad57600080fd5b50565b61258f80620001c06000396000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c8063a694fc3a11610104578063cd3daf9d116100a2578063e4086c5111610071578063e4086c5114610535578063ef772a6014610565578063f245ace414610583578063f7c618c1146105b3576101ce565b8063cd3daf9d146104bf578063d3ccd1df146104dd578063d58f91131461050d578063e3bce10e1461052b576101ce565b8063ad84746e116100de578063ad84746e14610425578063b88a802f14610455578063bea081511461045f578063c281a4171461048f576101ce565b8063a694fc3a146103bd578063a6f9dae1146103d9578063ab32eb69146103f5576101ce565b80635e0fac2e1161017157806372f702f31161014b57806372f702f314610333578063761634bd14610351578063817b1cd21461036f578063a17bb1531461038d576101ce565b80635e0fac2e146102b55780636aa0838f146102e55780636dfe789a14610303576101ce565b80633dc1579a116101ad5780633dc1579a1461023f5780634959565b1461025d5780635997bb371461027b5780635d3eea9114610299576101ce565b80628cc262146101d3578063304ac91b146102035780633504ffb214610221575b600080fd5b6101ed60048036038101906101e89190611b87565b6105d1565b6040516101fa9190612243565b60405180910390f35b61020b6106d3565b6040516102189190612243565b60405180910390f35b6102296106d9565b6040516102369190612243565b60405180910390f35b6102476106df565b604051610254919061225e565b60405180910390f35b6102656106e4565b604051610272919061225e565b60405180910390f35b6102836106e9565b6040516102909190612243565b60405180910390f35b6102b360048036038101906102ae9190611bd9565b6106f5565b005b6102cf60048036038101906102ca9190611b87565b610a21565b6040516102dc9190612243565b60405180910390f35b6102ed610a6a565b6040516102fa9190612243565b60405180910390f35b61031d60048036038101906103189190611b87565b610a70565b60405161032a9190612072565b60405180910390f35b61033b610b5d565b604051610348919061208d565b60405180910390f35b610359610b83565b6040516103669190612072565b60405180910390f35b610377610d73565b6040516103849190612243565b60405180910390f35b6103a760048036038101906103a29190611b87565b610d7d565b6040516103b49190612243565b60405180910390f35b6103d760048036038101906103d29190611bd9565b610d95565b005b6103f360048036038101906103ee9190611b87565b6111bb565b005b61040f600480360381019061040a9190611b87565b61128f565b60405161041c9190612243565b60405180910390f35b61043f600480360381019061043a9190611b87565b6112a7565b60405161044c91906120a8565b60405180910390f35b61045d611398565b005b61047960048036038101906104749190611b87565b6115f0565b6040516104869190612243565b60405180910390f35b6104a960048036038101906104a49190611b87565b611608565b6040516104b69190612243565b60405180910390f35b6104c7611629565b6040516104d49190612243565b60405180910390f35b6104f760048036038101906104f29190611b87565b611693565b6040516105049190612243565b60405180910390f35b6105156116ab565b6040516105229190612243565b60405180910390f35b61053361175d565b005b61054f600480360381019061054a9190611b87565b611ad7565b60405161055c9190612243565b60405180910390f35b61056d611aef565b60405161057a9190612243565b60405180910390f35b61059d60048036038101906105989190611b87565b611af5565b6040516105aa9190612243565b60405180910390f35b6105bb611b0d565b6040516105c8919061208d565b60405180910390f35b6000600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054670de0b6b3a7640000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610664611629565b61066e91906123ff565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546106b89190612311565b6106c291906122e0565b6106cc919061228a565b9050919050565b60085481565b600a5481565b60b481565b600281565b678ac7230489e8000081565b6002600054141561073b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073290612203565b60405180910390fd5b60026000819055503361074c611629565b60088190555042600781905550610762816105d1565b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600854600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000811161082f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610826906120c3565b60405180910390fd5b82600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156108b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a890612183565b60405180910390fd5b82600960008282546108c391906123ff565b9250508190555082600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461091991906123ff565b925050819055506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33866040518363ffffffff1660e01b815260040161097f929190612049565b602060405180830381600087803b15801561099957600080fd5b505af11580156109ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d19190611bb0565b905080610a13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0a90612123565b60405180910390fd5b505050600160008190555050565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60075481565b600080600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610af4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aeb906121c3565b60405180910390fd5b60b460ff16600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205442610b4491906123ff565b1115610b535760019050610b58565b600090505b919050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003373ffffffffffffffffffffffffffffffffffffffff16600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0c90612103565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610caf9190611ff7565b60206040518083038186803b158015610cc757600080fd5b505afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190611c02565b6040518363ffffffff1660e01b8152600401610d1c929190612049565b602060405180830381600087803b158015610d3657600080fd5b505af1158015610d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6e9190611bb0565b905090565b6000600954905090565b600e6020528060005260406000206000915090505481565b60026000541415610ddb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd290612203565b60405180910390fd5b600260008190555033610dec611629565b60088190555042600781905550610e02816105d1565b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600854600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008111610ecf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ec6906120c3565b60405180910390fd5b82600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610f2b9190611ff7565b60206040518083038186803b158015610f4357600080fd5b505afa158015610f57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7b9190611c02565b1015610fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb3906120e3565b60405180910390fd5b8260096000828254610fce919061228a565b9250508190555082600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611024919061228a565b925050819055506000600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156110b85742600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330876040518463ffffffff1660e01b815260040161111993929190612012565b602060405180830381600087803b15801561113357600080fd5b505af1158015611147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116b9190611bb0565b9050806111ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a490612163565b60405180910390fd5b505050600160008190555050565b3373ffffffffffffffffffffffffffffffffffffffff16600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461124b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124290612103565b60405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60036020528060005260406000206000915090505481565b600080600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561132b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611322906121c3565b60405180910390fd5b6000600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020544261137891906123ff565b9050600060b460ff168261138c919061236b565b90508092505050919050565b600260005414156113de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d590612203565b60405180910390fd5b60026000819055506000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411611468576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145f906121e3565b60405180910390fd5b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401611550929190612049565b602060405180830381600087803b15801561156a57600080fd5b505af115801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190611bb0565b9050806115e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115db90612143565b60405180910390fd5b50506001600081905550565b60046020528060005260406000206000915090505481565b6000600260ff16611618836105d1565b61162291906122e0565b9050919050565b600080600954141561163f576008549050611690565b600954670de0b6b3a7640000678ac7230489e800006007544261166291906123ff565b61166c9190612311565b6116769190612311565b61168091906122e0565b60085461168d919061228a565b90505b90565b600d6020528060005260406000206000915090505481565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016117089190611ff7565b60206040518083038186803b15801561172057600080fd5b505afa158015611734573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117589190611c02565b905090565b33611766611629565b6008819055504260078190555061177c816105d1565b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600854600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506002600054141561184b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184290612203565b60405180910390fd5b600260008190555061185c33610a70565b61189b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611892906121a3565b60405180910390fd5b600042905060b460ff16600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826118f091906123ff565b1015611931576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192890612223565b60405180910390fd5b6000600260ff16600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461198291906122e0565b905081600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a1791906123ff565b9250508190555080600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a6d919061228a565b9250508190555080600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ac3919061228a565b925050819055505050600160008190555050565b60066020528060005260406000206000915090505481565b60095481565b60056020528060005260406000206000915090505481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600081359050611b4281612514565b92915050565b600081519050611b578161252b565b92915050565b600081359050611b6c81612542565b92915050565b600081519050611b8181612542565b92915050565b600060208284031215611b9957600080fd5b6000611ba784828501611b33565b91505092915050565b600060208284031215611bc257600080fd5b6000611bd084828501611b48565b91505092915050565b600060208284031215611beb57600080fd5b6000611bf984828501611b5d565b91505092915050565b600060208284031215611c1457600080fd5b6000611c2284828501611b72565b91505092915050565b611c3481612433565b82525050565b611c4381612445565b82525050565b611c5281612492565b82525050565b611c6181612451565b82525050565b6000611c74601283612279565b91507f416d6f756e74206d757374206265203e203000000000000000000000000000006000830152602082019050919050565b6000611cb4601983612279565b91507f4e6f7420456e6f7567682046756e647320746f205374616b65000000000000006000830152602082019050919050565b6000611cf4602183612279565b91507f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f60008301527f6e000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611d5a601183612279565b91507f756e5374616b653a204572726f722074780000000000000000000000000000006000830152602082019050919050565b6000611d9a601583612279565b91507f436c61696d5265776172643a204572726f7220747800000000000000000000006000830152602082019050919050565b6000611dda600f83612279565b91507f7374616b653a204572726f7220747800000000000000000000000000000000006000830152602082019050919050565b6000611e1a602683612279565b91507f416d6f756e742073656e7420686967686572207468616e2062616c616e63652060008301527f7374616b656400000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611e80600d83612279565b91507f43616e27742072656c65617365000000000000000000000000000000000000006000830152602082019050919050565b6000611ec0601383612279565b91507f5573657220686173206e6f74207374616b6564000000000000000000000000006000830152602082019050919050565b6000611f00601d83612279565b91507f496e73756666696369656e7420556e6c6f636b65642042616c616e63650000006000830152602082019050919050565b6000611f40601f83612279565b91507f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006000830152602082019050919050565b6000611f80602383612279565b91507f43616e6e6f742052656c6561736520546f6b656e73204265666f72652033206460008301527f61797300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b611fe28161247b565b82525050565b611ff181612485565b82525050565b600060208201905061200c6000830184611c2b565b92915050565b60006060820190506120276000830186611c2b565b6120346020830185611c2b565b6120416040830184611fd9565b949350505050565b600060408201905061205e6000830185611c2b565b61206b6020830184611fd9565b9392505050565b60006020820190506120876000830184611c3a565b92915050565b60006020820190506120a26000830184611c49565b92915050565b60006020820190506120bd6000830184611c58565b92915050565b600060208201905081810360008301526120dc81611c67565b9050919050565b600060208201905081810360008301526120fc81611ca7565b9050919050565b6000602082019050818103600083015261211c81611ce7565b9050919050565b6000602082019050818103600083015261213c81611d4d565b9050919050565b6000602082019050818103600083015261215c81611d8d565b9050919050565b6000602082019050818103600083015261217c81611dcd565b9050919050565b6000602082019050818103600083015261219c81611e0d565b9050919050565b600060208201905081810360008301526121bc81611e73565b9050919050565b600060208201905081810360008301526121dc81611eb3565b9050919050565b600060208201905081810360008301526121fc81611ef3565b9050919050565b6000602082019050818103600083015261221c81611f33565b9050919050565b6000602082019050818103600083015261223c81611f73565b9050919050565b60006020820190506122586000830184611fd9565b92915050565b60006020820190506122736000830184611fe8565b92915050565b600082825260208201905092915050565b60006122958261247b565b91506122a08361247b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156122d5576122d46124b6565b5b828201905092915050565b60006122eb8261247b565b91506122f68361247b565b925082612306576123056124e5565b5b828204905092915050565b600061231c8261247b565b91506123278361247b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123605761235f6124b6565b5b828202905092915050565b600061237682612451565b915061238183612451565b9250827f8000000000000000000000000000000000000000000000000000000000000000018212600084121516156123bc576123bb6124b6565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0182136000841216156123f4576123f36124b6565b5b828203905092915050565b600061240a8261247b565b91506124158361247b565b925082821015612428576124276124b6565b5b828203905092915050565b600061243e8261245b565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061249d826124a4565b9050919050565b60006124af8261245b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b61251d81612433565b811461252857600080fd5b50565b61253481612445565b811461253f57600080fd5b50565b61254b8161247b565b811461255657600080fd5b5056fea26469706673582212209846dd905cb2d4571804946171887f8b856897479257a156db4e28743739c01264736f6c63430008000033000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c90000000000000000000000008271904b9f81976ea2b3758c8a69859e2f9ab215

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101ce5760003560e01c8063a694fc3a11610104578063cd3daf9d116100a2578063e4086c5111610071578063e4086c5114610535578063ef772a6014610565578063f245ace414610583578063f7c618c1146105b3576101ce565b8063cd3daf9d146104bf578063d3ccd1df146104dd578063d58f91131461050d578063e3bce10e1461052b576101ce565b8063ad84746e116100de578063ad84746e14610425578063b88a802f14610455578063bea081511461045f578063c281a4171461048f576101ce565b8063a694fc3a146103bd578063a6f9dae1146103d9578063ab32eb69146103f5576101ce565b80635e0fac2e1161017157806372f702f31161014b57806372f702f314610333578063761634bd14610351578063817b1cd21461036f578063a17bb1531461038d576101ce565b80635e0fac2e146102b55780636aa0838f146102e55780636dfe789a14610303576101ce565b80633dc1579a116101ad5780633dc1579a1461023f5780634959565b1461025d5780635997bb371461027b5780635d3eea9114610299576101ce565b80628cc262146101d3578063304ac91b146102035780633504ffb214610221575b600080fd5b6101ed60048036038101906101e89190611b87565b6105d1565b6040516101fa9190612243565b60405180910390f35b61020b6106d3565b6040516102189190612243565b60405180910390f35b6102296106d9565b6040516102369190612243565b60405180910390f35b6102476106df565b604051610254919061225e565b60405180910390f35b6102656106e4565b604051610272919061225e565b60405180910390f35b6102836106e9565b6040516102909190612243565b60405180910390f35b6102b360048036038101906102ae9190611bd9565b6106f5565b005b6102cf60048036038101906102ca9190611b87565b610a21565b6040516102dc9190612243565b60405180910390f35b6102ed610a6a565b6040516102fa9190612243565b60405180910390f35b61031d60048036038101906103189190611b87565b610a70565b60405161032a9190612072565b60405180910390f35b61033b610b5d565b604051610348919061208d565b60405180910390f35b610359610b83565b6040516103669190612072565b60405180910390f35b610377610d73565b6040516103849190612243565b60405180910390f35b6103a760048036038101906103a29190611b87565b610d7d565b6040516103b49190612243565b60405180910390f35b6103d760048036038101906103d29190611bd9565b610d95565b005b6103f360048036038101906103ee9190611b87565b6111bb565b005b61040f600480360381019061040a9190611b87565b61128f565b60405161041c9190612243565b60405180910390f35b61043f600480360381019061043a9190611b87565b6112a7565b60405161044c91906120a8565b60405180910390f35b61045d611398565b005b61047960048036038101906104749190611b87565b6115f0565b6040516104869190612243565b60405180910390f35b6104a960048036038101906104a49190611b87565b611608565b6040516104b69190612243565b60405180910390f35b6104c7611629565b6040516104d49190612243565b60405180910390f35b6104f760048036038101906104f29190611b87565b611693565b6040516105049190612243565b60405180910390f35b6105156116ab565b6040516105229190612243565b60405180910390f35b61053361175d565b005b61054f600480360381019061054a9190611b87565b611ad7565b60405161055c9190612243565b60405180910390f35b61056d611aef565b60405161057a9190612243565b60405180910390f35b61059d60048036038101906105989190611b87565b611af5565b6040516105aa9190612243565b60405180910390f35b6105bb611b0d565b6040516105c8919061208d565b60405180910390f35b6000600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054670de0b6b3a7640000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610664611629565b61066e91906123ff565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546106b89190612311565b6106c291906122e0565b6106cc919061228a565b9050919050565b60085481565b600a5481565b60b481565b600281565b678ac7230489e8000081565b6002600054141561073b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073290612203565b60405180910390fd5b60026000819055503361074c611629565b60088190555042600781905550610762816105d1565b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600854600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000811161082f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610826906120c3565b60405180910390fd5b82600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156108b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a890612183565b60405180910390fd5b82600960008282546108c391906123ff565b9250508190555082600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461091991906123ff565b925050819055506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33866040518363ffffffff1660e01b815260040161097f929190612049565b602060405180830381600087803b15801561099957600080fd5b505af11580156109ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d19190611bb0565b905080610a13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0a90612123565b60405180910390fd5b505050600160008190555050565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60075481565b600080600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610af4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aeb906121c3565b60405180910390fd5b60b460ff16600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205442610b4491906123ff565b1115610b535760019050610b58565b600090505b919050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003373ffffffffffffffffffffffffffffffffffffffff16600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0c90612103565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610caf9190611ff7565b60206040518083038186803b158015610cc757600080fd5b505afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190611c02565b6040518363ffffffff1660e01b8152600401610d1c929190612049565b602060405180830381600087803b158015610d3657600080fd5b505af1158015610d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6e9190611bb0565b905090565b6000600954905090565b600e6020528060005260406000206000915090505481565b60026000541415610ddb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd290612203565b60405180910390fd5b600260008190555033610dec611629565b60088190555042600781905550610e02816105d1565b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600854600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008111610ecf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ec6906120c3565b60405180910390fd5b82600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610f2b9190611ff7565b60206040518083038186803b158015610f4357600080fd5b505afa158015610f57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7b9190611c02565b1015610fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb3906120e3565b60405180910390fd5b8260096000828254610fce919061228a565b9250508190555082600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611024919061228a565b925050819055506000600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156110b85742600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330876040518463ffffffff1660e01b815260040161111993929190612012565b602060405180830381600087803b15801561113357600080fd5b505af1158015611147573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116b9190611bb0565b9050806111ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a490612163565b60405180910390fd5b505050600160008190555050565b3373ffffffffffffffffffffffffffffffffffffffff16600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461124b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124290612103565b60405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60036020528060005260406000206000915090505481565b600080600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561132b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611322906121c3565b60405180910390fd5b6000600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020544261137891906123ff565b9050600060b460ff168261138c919061236b565b90508092505050919050565b600260005414156113de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d590612203565b60405180910390fd5b60026000819055506000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411611468576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145f906121e3565b60405180910390fd5b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401611550929190612049565b602060405180830381600087803b15801561156a57600080fd5b505af115801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190611bb0565b9050806115e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115db90612143565b60405180910390fd5b50506001600081905550565b60046020528060005260406000206000915090505481565b6000600260ff16611618836105d1565b61162291906122e0565b9050919050565b600080600954141561163f576008549050611690565b600954670de0b6b3a7640000678ac7230489e800006007544261166291906123ff565b61166c9190612311565b6116769190612311565b61168091906122e0565b60085461168d919061228a565b90505b90565b600d6020528060005260406000206000915090505481565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016117089190611ff7565b60206040518083038186803b15801561172057600080fd5b505afa158015611734573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117589190611c02565b905090565b33611766611629565b6008819055504260078190555061177c816105d1565b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600854600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506002600054141561184b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184290612203565b60405180910390fd5b600260008190555061185c33610a70565b61189b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611892906121a3565b60405180910390fd5b600042905060b460ff16600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826118f091906123ff565b1015611931576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192890612223565b60405180910390fd5b6000600260ff16600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461198291906122e0565b905081600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a1791906123ff565b9250508190555080600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a6d919061228a565b9250508190555080600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ac3919061228a565b925050819055505050600160008190555050565b60066020528060005260406000206000915090505481565b60095481565b60056020528060005260406000206000915090505481565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600081359050611b4281612514565b92915050565b600081519050611b578161252b565b92915050565b600081359050611b6c81612542565b92915050565b600081519050611b8181612542565b92915050565b600060208284031215611b9957600080fd5b6000611ba784828501611b33565b91505092915050565b600060208284031215611bc257600080fd5b6000611bd084828501611b48565b91505092915050565b600060208284031215611beb57600080fd5b6000611bf984828501611b5d565b91505092915050565b600060208284031215611c1457600080fd5b6000611c2284828501611b72565b91505092915050565b611c3481612433565b82525050565b611c4381612445565b82525050565b611c5281612492565b82525050565b611c6181612451565b82525050565b6000611c74601283612279565b91507f416d6f756e74206d757374206265203e203000000000000000000000000000006000830152602082019050919050565b6000611cb4601983612279565b91507f4e6f7420456e6f7567682046756e647320746f205374616b65000000000000006000830152602082019050919050565b6000611cf4602183612279565b91507f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f60008301527f6e000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611d5a601183612279565b91507f756e5374616b653a204572726f722074780000000000000000000000000000006000830152602082019050919050565b6000611d9a601583612279565b91507f436c61696d5265776172643a204572726f7220747800000000000000000000006000830152602082019050919050565b6000611dda600f83612279565b91507f7374616b653a204572726f7220747800000000000000000000000000000000006000830152602082019050919050565b6000611e1a602683612279565b91507f416d6f756e742073656e7420686967686572207468616e2062616c616e63652060008301527f7374616b656400000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000611e80600d83612279565b91507f43616e27742072656c65617365000000000000000000000000000000000000006000830152602082019050919050565b6000611ec0601383612279565b91507f5573657220686173206e6f74207374616b6564000000000000000000000000006000830152602082019050919050565b6000611f00601d83612279565b91507f496e73756666696369656e7420556e6c6f636b65642042616c616e63650000006000830152602082019050919050565b6000611f40601f83612279565b91507f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006000830152602082019050919050565b6000611f80602383612279565b91507f43616e6e6f742052656c6561736520546f6b656e73204265666f72652033206460008301527f61797300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b611fe28161247b565b82525050565b611ff181612485565b82525050565b600060208201905061200c6000830184611c2b565b92915050565b60006060820190506120276000830186611c2b565b6120346020830185611c2b565b6120416040830184611fd9565b949350505050565b600060408201905061205e6000830185611c2b565b61206b6020830184611fd9565b9392505050565b60006020820190506120876000830184611c3a565b92915050565b60006020820190506120a26000830184611c49565b92915050565b60006020820190506120bd6000830184611c58565b92915050565b600060208201905081810360008301526120dc81611c67565b9050919050565b600060208201905081810360008301526120fc81611ca7565b9050919050565b6000602082019050818103600083015261211c81611ce7565b9050919050565b6000602082019050818103600083015261213c81611d4d565b9050919050565b6000602082019050818103600083015261215c81611d8d565b9050919050565b6000602082019050818103600083015261217c81611dcd565b9050919050565b6000602082019050818103600083015261219c81611e0d565b9050919050565b600060208201905081810360008301526121bc81611e73565b9050919050565b600060208201905081810360008301526121dc81611eb3565b9050919050565b600060208201905081810360008301526121fc81611ef3565b9050919050565b6000602082019050818103600083015261221c81611f33565b9050919050565b6000602082019050818103600083015261223c81611f73565b9050919050565b60006020820190506122586000830184611fd9565b92915050565b60006020820190506122736000830184611fe8565b92915050565b600082825260208201905092915050565b60006122958261247b565b91506122a08361247b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156122d5576122d46124b6565b5b828201905092915050565b60006122eb8261247b565b91506122f68361247b565b925082612306576123056124e5565b5b828204905092915050565b600061231c8261247b565b91506123278361247b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123605761235f6124b6565b5b828202905092915050565b600061237682612451565b915061238183612451565b9250827f8000000000000000000000000000000000000000000000000000000000000000018212600084121516156123bc576123bb6124b6565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0182136000841216156123f4576123f36124b6565b5b828203905092915050565b600061240a8261247b565b91506124158361247b565b925082821015612428576124276124b6565b5b828203905092915050565b600061243e8261245b565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061249d826124a4565b9050919050565b60006124af8261245b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b61251d81612433565b811461252857600080fd5b50565b61253481612445565b811461253f57600080fd5b50565b61254b8161247b565b811461255657600080fd5b5056fea26469706673582212209846dd905cb2d4571804946171887f8b856897479257a156db4e28743739c01264736f6c63430008000033