ETH Price: $2,670.81 (-4.22%)

Contract

0xCF532428021BEd194F3AB8D4C003cC2e2cD8628a
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw151959832022-07-23 1:31:04929 days ago1658539864IN
0xCF532428...e2cD8628a
0 ETH0.00033597.35867798
Withdraw151959452022-07-23 1:23:00929 days ago1658539380IN
0xCF532428...e2cD8628a
0 ETH0.000427216.80853296
Unstake151959402022-07-23 1:22:14929 days ago1658539334IN
0xCF532428...e2cD8628a
0 ETH0.0056153135.33490551
Withdraw151959192022-07-23 1:18:56929 days ago1658539136IN
0xCF532428...e2cD8628a
0 ETH0.0006787610.81741022
Unstake151959172022-07-23 1:18:47929 days ago1658539127IN
0xCF532428...e2cD8628a
0 ETH0.0062469239.3152748
Withdraw151893082022-07-22 0:48:32930 days ago1658450912IN
0xCF532428...e2cD8628a
0 ETH0.0017694238.76327226
Unstake151892892022-07-22 0:44:49930 days ago1658450689IN
0xCF532428...e2cD8628a
0 ETH0.0054564937.13035859
Withdraw151829532022-07-21 1:17:54931 days ago1658366274IN
0xCF532428...e2cD8628a
0 ETH0.0010768125.60987693
Withdraw151829532022-07-21 1:17:54931 days ago1658366274IN
0xCF532428...e2cD8628a
0 ETH0.0008875419.44373276
Unstake151829452022-07-21 1:15:48931 days ago1658366148IN
0xCF532428...e2cD8628a
0 ETH0.0063557240
Withdraw151829292022-07-21 1:12:03931 days ago1658365923IN
0xCF532428...e2cD8628a
0 ETH0.0007253215.88985204
Unstake151829242022-07-21 1:11:15931 days ago1658365875IN
0xCF532428...e2cD8628a
0 ETH0.005878240
Withdraw151829172022-07-21 1:08:55931 days ago1658365735IN
0xCF532428...e2cD8628a
0 ETH0.0005050411.06416826
Unstake151829132022-07-21 1:07:55931 days ago1658365675IN
0xCF532428...e2cD8628a
0 ETH0.0059002837.607066
Withdraw151828962022-07-21 1:04:59931 days ago1658365499IN
0xCF532428...e2cD8628a
0 ETH0.0018258840
Unstake151828892022-07-21 1:03:28931 days ago1658365408IN
0xCF532428...e2cD8628a
0 ETH0.0063552440
Withdraw151631302022-07-17 23:36:40935 days ago1658101000IN
0xCF532428...e2cD8628a
0 ETH0.0010751717.13511211
Withdraw151557032022-07-16 19:53:32936 days ago1658001212IN
0xCF532428...e2cD8628a
0 ETH0.0011963119.06571607
Unstake151556662022-07-16 19:43:55936 days ago1658000635IN
0xCF532428...e2cD8628a
0 ETH0.0029608818.63302137
Withdraw151553642022-07-16 18:41:33936 days ago1657996893IN
0xCF532428...e2cD8628a
0 ETH0.0018284329.13978618
Unstake151553592022-07-16 18:40:58936 days ago1657996858IN
0xCF532428...e2cD8628a
0 ETH0.0042976327.0452954
Withdraw151553482022-07-16 18:38:29936 days ago1657996709IN
0xCF532428...e2cD8628a
0 ETH0.0021418434.13456829
Unstake151553152022-07-16 18:31:35936 days ago1657996295IN
0xCF532428...e2cD8628a
0 ETH0.0070943948.27302792
Withdraw151530342022-07-16 9:50:51936 days ago1657965051IN
0xCF532428...e2cD8628a
0 ETH0.0007210211.49093561
Unstake151530262022-07-16 9:49:07936 days ago1657964947IN
0xCF532428...e2cD8628a
0 ETH0.002224414.00043023
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
UniftyGovernance

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 4 : UniftyGovernance.sol
pragma solidity ^0.8.4;

import "./IUniftyGovernanceConsumer.sol";
import "./IERC20Simple.sol";
import "./IERC20Mintable.sol";

/* ################################
    #
    # UniftyGovernance
    #
    # Contract to propose and vote on community decisions.
    # Distributes proposed grants as UNT to accepted consumers.
    #
    ######################################## */

contract UniftyGovernance {

    /* ################################
    #
    # SETUP (partially proposable)
    #
    ######################################## */
    
    // nif address
    address public nifAddress = 0x7e291890B01E5181f7ecC98D79ffBe12Ad23df9e;

    // unt address
    address public untAddress = 0xF8fCC10506ae0734dfd2029959b93E6ACe5b2a70;
    
    // epoch duration as timestamp, consisting of epochDuration and epochDurationMult
    uint256 public epochDuration = 86400 * 30;

    // the initial reward at epoch 1
    uint256 public genesisReward = 50000000 * 10**18;
    
    // the maximum duration of a proposal
    uint256 public maxProposalDuration = 86400 * 7;

    // proposal duration
    // the duration a proposal will be kept open at minimum
    uint256 public minProposalDuration = 86400 * 2;
    
    // the max. amount of time a proposal may be executed after the proposal period has been accepted and ended
    uint256 public proposalExecutionLimit = 86400 * 7;
    
    // min amount of nif required for a proposal to conclude
    uint256 public quorum = 150000 * 10**18;
    
    // minimum nif staking for the governance per user.
    // if below, a staker cannot propose or vote but stake and allocate to peers
    uint256 public minNifStake = 10 * 10**18;

    // minimum nif staking for the governance
    uint256 public minNifOverallStake = 150000 * 10**18;

    // the min nif being staked in the governance required for consumers receiving UNT
    uint256 public minNifConsumptionStake = 150000 * 10**18;

    // the timelock that nif needs to stay locked at minimum
    uint256 public nifStakeTimelock = 86400 * 14;
    
    // for selected timestamp relevant lookups, we use a general gracetime
    uint public graceTime = 60 * 15;
    
    /* ################################
    #
    # RUNTIME MEMBERS
    #
    ######################################## */
    
    // all nif stakes of a user (user => stake)
    mapping(address => LUniftyGovernance.NifStake) public userNifStakes;
    
    // counts the amount of proposals
    uint256 public proposalCounter;

    // proposalID => proposal
    mapping(uint256 => LUniftyGovernance.Proposal) public proposals;

    // proposalID => proposal
    mapping(uint256 => LUniftyGovernance.Uint256Proposal) public uint256Proposal;

    // proposalID => address
    mapping(uint256 => LUniftyGovernance.AddressProposal) public addressProposal;

    // proposalID => votes
    mapping(uint256 => LUniftyGovernance.Vote[]) public votes;

    // counts the amount of votes
    // proposalID => vote count
    mapping(uint256 => uint256) public votesCounter;
    
    // all nif stakes within this governance
    uint256 public allNifStakes;

    // allocations for the different consumers and their peers
    mapping(IUniftyGovernanceConsumer => mapping( address => uint256 ) ) public consumerPeerNifAllocation;
    
    // the amount of allocators for the peer
    mapping(IUniftyGovernanceConsumer => mapping( address => uint256 ) ) public nifAllocationLength;
    
    // allocations for consumers
    mapping(IUniftyGovernanceConsumer => uint256) public consumerNifAllocation;
    uint256 public nifAllocation;

    // governance pause flag
    bool public pausing = false;

    // when the accrue started since contract creation
    uint256 public accrueStart;

    // consumers who may receive UNT for further processing
    mapping(uint256 => LUniftyGovernance.Consumer) public consumers;
    
    // flat list of peers, each peer is supposed to be unique to the governance
    mapping(address => bool) public peerExists;
    
    // counter to be used with consumers
    // unlike the proposalCounter, we start with 1 here as we need 0 to determine an empty consumer situation.
    uint256 public consumerCounter = 1;

    // returns the consumer id or 0 if not set
    mapping(IUniftyGovernanceConsumer => uint256) public consumerIdByType;
    
    // mapping consumer => peer for global use to check if those exist
    mapping(IUniftyGovernanceConsumer => mapping( address => bool )) public consumerPeerExists;
    
    // the currently granted unt across all consumers
    uint256 public grantedUnt;
    
    // the unt that has been minted so far across all consumers
    uint256 public mintedUnt;

    // how much UNT has a consumer minted so far
    mapping(IUniftyGovernanceConsumer => uint256) public mintedUntConsumer;
    
    // list of executives for the governance contracts.
    // execs may execute accepted proposals and pause the governance in case of emergencies.
    // they are obliged to obey to governance decision and supposed to execute accepted proposals.
    mapping(address => bool) public isExecutive;
    
    // the current credit after unlock requests per user
    mapping(address => uint256) public credit;

    /* ################################
    #
    # RE-ENTRANCY GUARD
    #
    ######################################## */

    // re-entrancy protection
    uint256 private unlocked = 1;

    modifier lock() {
        require(unlocked == 1, 'UniftyGovernance: LOCKED');
        unlocked = 0;
        _;
        unlocked = 1;
    }

    /* ################################
    #
    # EVENTS
    #
    ######################################## */

    event Allocated(address indexed user, IUniftyGovernanceConsumer consumer, address peer, uint256 untEarned);
    event Dellocated(address indexed user, IUniftyGovernanceConsumer consumer, address peer, uint256 untEarned);
    event Staked(address indexed user, uint256 stake, bool peerAccepted, uint256 untEarned);
    event Unstaked(address indexed user, uint256 unstake, bool peerAccepted, uint256 untEarned);
    event Withdrawn(address indexed user, uint256 amount);
    event Proposed(address indexed initiator, uint256 indexed proposalId, uint256 expires, uint256 actionId);
    event Voted(address indexed voter, uint256 indexed proposalId, uint256 indexed voteId, bool supporting, uint256 power);
    event Executed(address indexed executor, uint256 indexed proposalId);

    /**
     * Sets the accrueStart value, marking the begin of the first epoch.
     * 
     * */
    constructor(){

        accrueStart = block.timestamp;
        isExecutive[msg.sender] = true;
    }
    
    /* ################################
    #
    # NIF STAKING
    #
    ######################################## */

    /**
     * Simple NIF staking.
     *
     * If not paused, frozen and the minNif is being sent or already available, staking is allowed.
     *
     * No further state changes to anyone's staked nif is performed other than individual unstaking.
     *
     * This is to make sure that nif funds can be unstaked at any time after the timelock expired, under any circumstance.
     *
     * Returns false if an allocation update to a peer silently failed and the earned unt.
     * */
    function stake(uint256 _stake) external lock returns(bool, uint256){

        // here we ask for the pausing flag, not isPausing() as the latter is also true if overall nif stakes are too low
        // so we couldn't stake in the first place.
        require(!pausing, "stake: pausing, sorry.");
        require(_stake > 0, "stake: invalid staking amount.");

        bool accepted = true;
        uint256 untEarned = 0;

        uint256 prevAmount = userNifStakes[msg.sender].amount;
        userNifStakes[msg.sender].amount += _stake;
        userNifStakes[msg.sender].unstakableFrom = block.timestamp + nifStakeTimelock;
        
        allNifStakes += _stake;
        
        // adding new stakes will reset the allocation time if an allocation exists already
        if(address(userNifStakes[msg.sender].peerConsumer) != address(0) && consumerIdByType[ userNifStakes[msg.sender].peerConsumer ] != 0){

            uint256 prevAllocation = consumerPeerNifAllocation[ userNifStakes[msg.sender].peerConsumer ][ userNifStakes[msg.sender].peer ];
            consumerPeerNifAllocation[ userNifStakes[msg.sender].peerConsumer ][ userNifStakes[msg.sender].peer ] += _stake;
            consumerNifAllocation[ userNifStakes[msg.sender].peerConsumer ] += _stake;
            nifAllocation += _stake;
            userNifStakes[msg.sender].peerAllocationTime = block.timestamp;
            
            try userNifStakes[msg.sender].peerConsumer.allocationUpdate(
                msg.sender, 
                prevAmount, 
                prevAllocation, 
                userNifStakes[msg.sender].peer
            ) 
                returns(bool _accepted, uint256 _untEarned)
            {
                
                accepted = _accepted;
                untEarned = _untEarned;
                
            } catch {}
            
            require(accepted, "stake: allocation update has been rejected.");
        }
        
        IERC20Simple(nifAddress).transferFrom(msg.sender, address(this), _stake);

        emit Staked(msg.sender, _stake, accepted, untEarned);
        
        return (accepted, untEarned);
    }
    
    /**
     * Returns credited NIF after the cooldown period.
     * 
     * */
    function withdraw() external lock {
        
        require(pausing || block.timestamp >= userNifStakes[msg.sender].unstakableFrom + graceTime, "withdraw: nif still locked.");
        
        uint256 tmp = credit[msg.sender];
        credit[msg.sender] = 0;
        IERC20Simple(nifAddress).transfer(msg.sender, tmp);
        emit Withdrawn(msg.sender, tmp);
    }

    /**
     * Unstaking is allowed at any given time (after min period and if peers allow it signalled through frozen()).
     *
     * Unstaking removes voting power.
     *
     * returns potential unt earned and sends it to the account.
     * "potentially" as it depends on the consumer's implementation.
     * 
     * returns true or false if the allocationUpdate has been accepted by the peer and the earned unt from allocated peer.
     * */
    function unstake(uint256 _unstaking) external lock returns(bool, uint256){
        
        require(userNifStakes[msg.sender].amount > 0 && userNifStakes[msg.sender].amount >= _unstaking, "unstakeInternal: insufficient funds.");
        
        bool accepted = true;
        uint256 untEarned = 0;
        
        userNifStakes[msg.sender].unstakableFrom = block.timestamp + nifStakeTimelock;
        credit[msg.sender] += _unstaking;
        
        if(userNifStakes[msg.sender].amount - _unstaking == 0){
            
            untEarned = dellocateInternal(msg.sender);
            
            // dellocate above needs the current staking amounts prior removing them.
            // since we use re-entrancy guarding, the below is not exploitable.
            userNifStakes[msg.sender].amount -= _unstaking;
            allNifStakes -= _unstaking;
            
        }
        else if(
            userNifStakes[msg.sender].amount - _unstaking != 0 && 
            address(userNifStakes[msg.sender].peerConsumer) != address(0) && 
            consumerIdByType[ userNifStakes[msg.sender].peerConsumer ] != 0
        ) {
            
            uint256 prevAmount = userNifStakes[msg.sender].amount;
            userNifStakes[msg.sender].amount -= _unstaking;
            allNifStakes -= _unstaking;
            
            uint256 prevAllocation = consumerPeerNifAllocation[ userNifStakes[msg.sender].peerConsumer ][ userNifStakes[msg.sender].peer ];
            consumerPeerNifAllocation[ userNifStakes[msg.sender].peerConsumer ][ userNifStakes[msg.sender].peer ] -= _unstaking;
            consumerNifAllocation[ userNifStakes[msg.sender].peerConsumer ] -= _unstaking;
            nifAllocation -= _unstaking;
            
            userNifStakes[msg.sender].peerAllocationTime = block.timestamp;
            
            try userNifStakes[msg.sender].peerConsumer.allocationUpdate(
                msg.sender, 
                prevAmount, 
                prevAllocation, 
                userNifStakes[msg.sender].peer
            ) 
                returns(bool _accepted, uint256 _untEarned)
            {
                accepted = _accepted;
                untEarned = _untEarned;
                
            } catch {}
        }
        else
        {
            
            userNifStakes[msg.sender].amount -= _unstaking;
            allNifStakes -= _unstaking;
        }
        
        emit Unstaked(msg.sender, _unstaking, accepted, untEarned);
        return (accepted, untEarned);
    }
    
    /**
     * Allocates stakes to a consumer's peer.
     * Fails if an allocated peer does not accept the allocation.
     * 
     * returns the earned unt from the previous peer if any.
     * */
    function allocate(IUniftyGovernanceConsumer _consumer, address _peer) external lock returns(uint256) {
        
        require(!isPausing(), "allocate: pausing, sorry.");
        require(userNifStakes[msg.sender].amount > 0, "allocate: you must stake first.");
        require(_peer != address(0) && address(_consumer) != address(0), "allocate: peer and consumer mustn't be null." );
        require(consumerIdByType[ _consumer ] != 0, "allocate: consumer doesn't exist.");
        require(consumerPeerExists[ _consumer ][ _peer ], "allocate: peer doesn't exist.");
        require(userNifStakes[msg.sender].peer != _peer, "allocate: you are allocating to this peer already.");
        require(!frozen(msg.sender), "allocate: cannot dellocate, allocation still frozen by current consumer.");
        
        uint256 untEarned = dellocateInternal(msg.sender); 
        
        userNifStakes[msg.sender].peerConsumer = _consumer;
        userNifStakes[msg.sender].peer = _peer;
        userNifStakes[msg.sender].peerAllocationTime = block.timestamp;
        
        uint256 prevAllocation = consumerPeerNifAllocation[ _consumer ][ _peer ];
        consumerPeerNifAllocation[ _consumer ][ _peer ] += userNifStakes[msg.sender].amount;
        consumerNifAllocation[ _consumer ] += userNifStakes[msg.sender].amount;
        nifAllocation += userNifStakes[msg.sender].amount;
        nifAllocationLength[ userNifStakes[msg.sender].peerConsumer ][ userNifStakes[msg.sender].peer ] += 1;
        
        bool accepted = false;
        try _consumer.allocate(msg.sender, prevAllocation, _peer) returns(bool _accepted) { 
            accepted = _accepted;
        }
        catch{ }
        
        // we do NOT use assert() here because there is no reason to panic.
        require(accepted, "allocate: allocation denied by consumer/peer or consumer is faulty.");
        
        emit Allocated(msg.sender, _consumer, _peer, untEarned);
        return untEarned;
    }
    
    /**
     * Dellocates a user's peer-allocation
     * 
     * */
    function dellocate() external lock returns(uint256) {
        
        require(address(userNifStakes[msg.sender].peerConsumer) != address(0), "dellocatePeer: nothing to dellocate.");
        
        return dellocateInternal(msg.sender);
        
    }
    
    /**
     * dellocates from an account's peer.
     * 
     * consumer.dellocate() in the end is 
     * a) a trusted contract
     * b) never called outside of re-entrancy guard-protected function
     * 
     * returns potential unt earnings being sent to the wallet alongside the dellocation.
     * */
    function dellocateInternal(address _sender) internal returns(uint256){
        
        if(address(userNifStakes[_sender].peerConsumer) == address(0)) { return 0; }
        
        // we allow dellocation upon pausing as it would indicate major trouble 
        // and unstaking NIF should be possible at all costs.
        require(!frozen(_sender) || pausing, "dellocateInternal: cannot dellocate, allocation still frozen by consumer.");
        
        IUniftyGovernanceConsumer tmpConsumer = userNifStakes[_sender].peerConsumer;
        address tmpPeer = userNifStakes[_sender].peer;
        uint256 untEarned = 0;
        
        uint256 prevAllocation = consumerPeerNifAllocation[ tmpConsumer ][ tmpPeer ];
        consumerPeerNifAllocation[ tmpConsumer ][ tmpPeer ] -= userNifStakes[_sender].amount;
        consumerNifAllocation[ tmpConsumer ] -= userNifStakes[_sender].amount;
        nifAllocation -= userNifStakes[_sender].amount;
        nifAllocationLength[ tmpConsumer ][ tmpPeer ] -= 1;
        
        userNifStakes[_sender].peerConsumer = IUniftyGovernanceConsumer(address(0));
        userNifStakes[_sender].peer = address(0);
        userNifStakes[_sender].peerAllocationTime = block.timestamp;
        
        if(consumerIdByType[ tmpConsumer ] != 0){
            try tmpConsumer.dellocate(_sender, prevAllocation, tmpPeer) returns(uint256 _untEarned){ 
                untEarned = _untEarned;
            }catch{ }
        }
        
        emit Dellocated(_sender, tmpConsumer, tmpPeer, untEarned);
        return untEarned;
    }
    
    /**
     * Checks if the consumer and peer an account allocated funds are frozen or not.
     * 
     * */
    function frozen(address _account) public view returns(bool){
        
        bool exists = consumerPeerExists[ userNifStakes[_account].peerConsumer ][ userNifStakes[_account].peer ];
        
        if(exists){
            
            // this won't stop malicious consumers from not releasing allocations
            // but it will at least help unfreezing allocations if consumers didn't implement peer handling properly
            // or if a peer has been removed while the user is still allocating.
            //
            // malicious/broken consumers should be spotted prior acceptance through contract reviews or being removed through proposals if slipping through.
            
            bool existsInConsumer = false;
            
            try userNifStakes[_account].peerConsumer.peerWhitelisted( userNifStakes[_account].peer ) returns(bool result){
                
                existsInConsumer = result;
                
            }catch{}
            
            if(!existsInConsumer){
                
                return false;
            }
            
            // in case of missing or faulty implementation of frozen() in the consumer, we want to catch that and signal nothing is being frozen
            
            try userNifStakes[_account].peerConsumer.frozen(_account) returns(bool result){
                
                return result;
                
            }catch{}
        }
        
        return false;
    }
    
    /**
     * The userNifStakes struct as accountInfo as convenience function for external callers.
     * 
     * Returns nulled peer allocations if the peer doesn't exist any longer, 
     * so this should be called externally to get proper information about the current peer state of an account.
     * 
     * */
    function accountInfo(address _account) external view returns(IUniftyGovernanceConsumer, address, uint256, uint256, uint256){
        
        bool exists = consumerPeerExists[ userNifStakes[_account].peerConsumer ][ userNifStakes[_account].peer ];
        
        IUniftyGovernanceConsumer consumer = userNifStakes[_account].peerConsumer;
        address peer = userNifStakes[_account].peer;
        uint256 allocationTime = userNifStakes[_account].peerAllocationTime;
        
        if(!exists){
            
            consumer = IUniftyGovernanceConsumer(address(0));
            peer = address(0);
            allocationTime = 0;
        }
        
        return ( 
            consumer,
            peer,  
            allocationTime,
            userNifStakes[_account].unstakableFrom,
            userNifStakes[_account].amount
        );
    }
    
    /**
     * The consumer struct info as convenience function for external callers.
     * 
     * */
    function consumerInfo(IUniftyGovernanceConsumer _consumer) external view returns(uint256, uint256, uint256, address[] memory){
        
        LUniftyGovernance.Consumer memory con = consumers[ consumerIdByType[ _consumer ] ];
        
        return ( 
            con.grantStartTime,
            con.grantRateSeconds,
            con.grantSizeUnt,
            con.peers
        );
    }

    /* ################################
    #
    # PROPOSALS & VOTES
    #
    ######################################## */

    /**
     *
     * Action ID = 1
     *
     * */
    function proposeMinNifOverallStake(uint256 _minNifOverallStake, uint256 _duration, string calldata _url) external lock{

        /**
         * newProposal() is an internal call, not externally, so this does NOT cause risks.
         * Also re-entrancy guards are consistently used.
         * 
         * */
        uint256 pid = newProposal(msg.sender, _duration, _url, 1);
        uint256Proposal[pid].value = _minNifOverallStake;
    }

    /**
     *
     * Action ID = 2
     *
     * */
    function proposeMinNifStake(uint256 _minNifStake, uint256 _duration, string calldata _url) external lock{

        uint256 pid = newProposal(msg.sender, _duration, _url, 2);
        uint256Proposal[pid].value = _minNifStake;
    }

    /**
     *
     * Action ID = 3
     *
     * _percentages must be current consumers length + 1.
     *
     * The last item in _percentages is the percentage for the currently proposed consumer.
     *
     * */
    function proposeAddConsumer(IUniftyGovernanceConsumer _consumer, uint256 _sizeUnt, uint256 _rateSeconds, uint256 _startTime, uint256 _duration, string calldata _url) external lock{

        require(address(_consumer) != address(0), "proposeAddConsumer: consumer may not be the null address.");
        require(consumerIdByType[ _consumer ] == 0, "proposeAddConsumer: consumer exists already.");
        require(_rateSeconds != 0, "proposeAddConsumer: invalid rate");
        require(_sizeUnt != 0, "proposeAddConsumer: invalid grant size.");
      
        uint256 pid = newProposal(msg.sender, _duration, _url, 3);
        addressProposal[pid].value = address(_consumer);
        uint256Proposal[pid].value = _sizeUnt;
        uint256Proposal[pid].value3 = _rateSeconds;
        uint256Proposal[pid].value4 = _startTime;
    }

    /**
     *
     * Action ID = 4
     *
     * */
    function proposeRemoveConsumer(IUniftyGovernanceConsumer _consumer, uint256 _duration, string calldata _url) external lock{

        require(address(_consumer) != address(0), "proposeRemoveConsumer: consumer may not be the null address.");
        require(consumers[ consumerIdByType[ _consumer ] ].consumer == _consumer , "proposeRemoveConsumer: consumer not found.");
        uint256 pid = newProposal(msg.sender, _duration, _url, 4);
        addressProposal[pid].value = address(_consumer);
    }

    /**
     *
     * Action ID = 5
     *
     * */
    function proposeConsumerWhitelistPeer(IUniftyGovernanceConsumer _consumer, address _peer, uint256 _duration, string calldata _url) external lock{

        require(_peer != address(0), "proposeConsumerWhitelistPeer: peer may not be the null address.");
        require(!consumerPeerExists[ _consumer ][ _peer ], "proposeConsumerWhitelistPeer: peer exists already.");
        require(!peerExists[_peer], "proposeConsumerWhitelistPeer: peer exists already.");
        
        uint256 pid = newProposal(msg.sender, _duration, _url, 5);
        addressProposal[pid].value = _peer;
        addressProposal[pid].value3 = address(_consumer);
    }

    /**
     *
     * Action ID = 6
     *
     * */
    function proposeConsumerRemovePeerFromWhitelist(IUniftyGovernanceConsumer _consumer, address _peer, uint256 _duration, string calldata _url) external lock{

        require(address(_consumer) != address(0), "proposeConsumerRemovePeerFromWhitelist: consumer may not be the null address.");
        require(consumers[ consumerIdByType[ _consumer ] ].consumer == _consumer , "proposeConsumerRemovePeerFromWhitelist: consumer not found.");
        require(consumerPeerExists[ _consumer ][ _peer ], "proposeConsumerRemovePeerFromWhitelist: peer not found.");
        
        uint256 pid = newProposal(msg.sender, _duration, _url, 6);
        addressProposal[pid].value = _peer;
        addressProposal[pid].value2.push(address(_consumer));
    }
    
    /**
     *
     * Action ID = 7
     *
     * */
    function proposeUpdateConsumerGrant(IUniftyGovernanceConsumer _consumer, uint256 _sizeUnt, uint256 _rateSeconds, uint256 _startTime, uint256 _duration, string calldata _url) external lock{

        require(consumerIdByType[ _consumer ] != 0, "updateConsumerGrant: consumer doesn't exist.");
        require(_rateSeconds != 0, "updateConsumerGrant: invalid rate");
        require(_sizeUnt != 0, "proposeUpdateConsumerGrant: invalid grant size.");
        
        uint256 pid = newProposal(msg.sender, _duration, _url, 7);
        addressProposal[pid].value = address(_consumer);
        uint256Proposal[pid].value = _sizeUnt;
        uint256Proposal[pid].value3 = _rateSeconds;
        uint256Proposal[pid].value4 = _startTime;
    }
    
    /**
     *
     * Action ID = 8
     *
     * */
    function proposeMinNifConsumptionStake(uint256 _minNifConsumptionStake, uint256 _duration, string calldata _url) external lock{

        uint256 pid = newProposal(msg.sender, _duration, _url, 8);
        uint256Proposal[pid].value = _minNifConsumptionStake;
    }
    
    /**
     *
     * Action ID = 9
     *
     * */
    function proposeGeneral( uint256 _duration, string calldata _url) external lock{

       newProposal(msg.sender, _duration, _url, 9);
    }
    
    /**
     *
     * Action ID = 10
     *
     * */
    function proposeMaxProposalDuration( uint256 _maxProposalDuration, uint256 _duration, string calldata _url) external lock{

       uint256 pid = newProposal(msg.sender, _duration, _url, 10);
       uint256Proposal[pid].value = _maxProposalDuration;
    }
    
    /**
     *
     * Action ID = 11
     *
     * */
    function proposeMinProposalDuration( uint256 _minProposalDuration, uint256 _duration, string calldata _url) external lock{

       uint256 pid = newProposal(msg.sender, _duration, _url, 11);
       uint256Proposal[pid].value = _minProposalDuration;
    }
    
    /**
     *
     * Action ID = 12
     *
     * */
    function proposeProposalExecutionLimit(uint256 _proposalExecutionLimit, uint256 _duration, string calldata _url) external lock{

       uint256 pid = newProposal(msg.sender, _duration, _url, 12);
       uint256Proposal[pid].value = _proposalExecutionLimit;
    }
    
    /**
     *
     * Action ID = 13
     *
     * */
    function proposeQuorum(uint256 _quorum, uint256 _duration, string calldata _url) external lock{

       uint256 pid = newProposal(msg.sender, _duration, _url, 13);
       uint256Proposal[pid].value = _quorum;
    }
    
    /**
     *
     * Action ID = 14
     *
     * */
    function proposeNifStakeTimelock(uint256 _nifStakeTimelock, uint256 _duration, string calldata _url) external lock{

       uint256 pid = newProposal(msg.sender, _duration, _url, 14);
       uint256Proposal[pid].value = _nifStakeTimelock;
    }
    

    /**
     * A new proposal implies the initiator is in support of proposal (counts as vote already).
     * He does not, nor can't, vote once he placed a proposal.
     *
     * */
    function newProposal(address _sender, uint256 _duration, string memory _url, uint256 _actionId) internal returns(uint256){

        require(!isPausing(), "newProposal: pausing, sorry.");
        require(_duration <= maxProposalDuration, "newProposal: duration too long.");
        require(_duration >= minProposalDuration, "newProposal: min. duration too short.");
        require(userNifStakes[_sender].amount >= minNifStake, "newProposal: invalid stake.");

        // we assume the initiator is supporting the proposal when opening it
        proposals[ proposalCounter ].initiator = _sender;
        proposals[ proposalCounter ].url = _url;
        proposals[ proposalCounter ].numVotes += 1;
        proposals[ proposalCounter ].numSupporting += userNifStakes[_sender].amount;
        proposals[ proposalCounter ].proposalId = proposalCounter;
        proposals[ proposalCounter ].voted[_sender] = true;
        proposals[ proposalCounter ].openUntil = block.timestamp + _duration;
        proposals[ proposalCounter ].actionId = _actionId;

        emit Proposed(_sender, proposalCounter, proposals[ proposalCounter ].openUntil, _actionId);

        votes[ proposalCounter ].push(LUniftyGovernance.Vote({
            voter: _sender,
            supporting: true,
            power: userNifStakes[_sender].amount,
            proposalId: proposalCounter,
            voteTime: block.timestamp
        }));
        
        emit Voted(_sender, proposalCounter, votesCounter[ proposalCounter ] + 1, true, userNifStakes[_sender].amount);

        uint256 ret = proposalCounter;

        // starts at 0, not 1 as we can loop "normally" from 0 to n-1 with clients

        votesCounter[ proposalCounter ] += 1;

        // ...same for the proposal counter

        proposalCounter += 1;

        return ret;

    }

    /**
     * A vote for a proposal uses the user nif earned points as voting power.
     *
     * */
    function vote(uint256 _proposalId, bool _supporting) external lock {

        require(!isPausing(), "vote: pausing, sorry.");
        require(userNifStakes[msg.sender].amount >= minNifStake, "vote: invalid stake.");
        require(proposals[ _proposalId ].initiator != address(0) && block.timestamp <= proposals[ _proposalId ].openUntil, "vote: invalid or expired proposal.");
        require(!proposals[ _proposalId ].voted[msg.sender], "vote: you voted already.");

        proposals[ _proposalId ].numVotes += 1;

        if(_supporting){

            proposals[ _proposalId ].numSupporting += userNifStakes[msg.sender].amount;

        }else{

            proposals[ _proposalId ].numNotSupporting += userNifStakes[msg.sender].amount;
        }

        proposals[ _proposalId ].voted[msg.sender] = true;

        votes[ _proposalId ].push(LUniftyGovernance.Vote({
            voter: msg.sender,
            supporting: _supporting,
            power: userNifStakes[msg.sender].amount,
            proposalId: _proposalId,
            voteTime: block.timestamp
        }));

        emit Voted(msg.sender, _proposalId, votesCounter[ _proposalId ], _supporting, userNifStakes[msg.sender].amount);

        votesCounter[ _proposalId ] += 1;
    }
    
    /**
     * For clients with ABI v1 support
     * 
     * */
    function voted(uint256 _proposalId, address _account) external view returns(bool){
        
        return proposals[_proposalId].voted[_account];
    }
    
    /**
     * service function
     * 
     * */
    function uint256ProposalInfo(uint256 _proposalId) external view returns(uint256, uint256, uint256, uint256[] memory){
      
        return (
            uint256Proposal[_proposalId].value,
            uint256Proposal[_proposalId].value3,
            uint256Proposal[_proposalId].value4,
            uint256Proposal[_proposalId].value2
        );
    }
    
    function addressProposalInfo(uint256 _proposalId) external view returns(address, address, address[] memory){
      
        return (
            addressProposal[_proposalId].value,
            addressProposal[_proposalId].value3,
            addressProposal[_proposalId].value2
        );
    }
    
    /**
     * Triggers the corresponding action if the vote is concluded in favor of support and expired.
     *
     * */
    function execute(uint256 _proposalId) external lock{

        require(!isPausing(), "execute: pausing, sorry.");
        require(isExecutive[msg.sender], "execute: not an executive.");
        require(proposals[ _proposalId ].initiator != address(0), "execute: invalid proposal.");
        require(!proposals[ _proposalId ].executed, "execute: proposal has been executed already.");
        require(proposals[ _proposalId ].numSupporting + proposals[ _proposalId ].numNotSupporting >= quorum, "execute: quorum not reached.");
        require(proposals[ _proposalId ].numSupporting > proposals[ _proposalId ].numNotSupporting, "execute: not enough support.");
        require(proposals[ _proposalId ].numVotes > 1, "execute: need at least 2 votes.");
        require(block.timestamp > proposals[ _proposalId ].openUntil + graceTime, "execute: voting and grace time not yet ended.");
        require(block.timestamp < proposals[ _proposalId ].openUntil + graceTime + proposalExecutionLimit, "execute: execution window expired.");
        
        proposals[ _proposalId ].executed = true;

        // Action ID = 1
        if(proposals[ _proposalId ].actionId == 1){

            minNifOverallStake = uint256Proposal[_proposalId].value;

            // Action ID = 2
        } else if(proposals[ _proposalId ].actionId == 2){

            minNifStake = uint256Proposal[_proposalId].value;

            // Action ID = 8
        } else if(proposals[ _proposalId ].actionId == 8){

            minNifConsumptionStake = uint256Proposal[_proposalId].value;

            // Action ID = 10
        } else if(proposals[ _proposalId ].actionId == 10){

            maxProposalDuration = uint256Proposal[_proposalId].value;

            // Action ID = 11
        } else if(proposals[ _proposalId ].actionId == 11){

            minProposalDuration = uint256Proposal[_proposalId].value;

            // Action ID = 12
        } else if(proposals[ _proposalId ].actionId == 12){

            proposalExecutionLimit = uint256Proposal[_proposalId].value;

            // Action ID = 13
        } else if(proposals[ _proposalId ].actionId == 13){

            quorum = uint256Proposal[_proposalId].value;

            // Action ID = 14
        } else if(proposals[ _proposalId ].actionId == 14){

            nifStakeTimelock = uint256Proposal[_proposalId].value;

            // Action ID = 3
        } else if(proposals[ _proposalId ].actionId == 3){

            require(consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[ _proposalId ].value ) ] == 0, "execute: action id 3 => consumer exists already.");
            require(grantableUnt() >= uint256Proposal[_proposalId].value, "exeute: action id 3 => not enough available UNT." );
            require(uint256Proposal[_proposalId].value3 != 0, "execute: action id 3 => invalid rate");
            
            // setting the proposed startTime to now if it got in the past in the meanwhile 
            if(uint256Proposal[_proposalId].value4 < block.timestamp){
                
                uint256Proposal[_proposalId].value4 = block.timestamp;
            }

            grantedUnt += uint256Proposal[_proposalId].value;

            consumers[ consumerCounter ].consumer = IUniftyGovernanceConsumer( addressProposal[ _proposalId ].value );
            consumers[ consumerCounter ].grantSizeUnt = uint256Proposal[_proposalId].value;
            consumers[ consumerCounter ].grantRateSeconds = uint256Proposal[_proposalId].value3;
            consumers[ consumerCounter ].grantStartTime = uint256Proposal[_proposalId].value4;
            
            consumerIdByType[ consumers[ consumerCounter ].consumer ] = consumerCounter;
            
            consumerCounter += 1;

            // Action ID = 4
        } else if(proposals[ _proposalId ].actionId == 4){
            
            LUniftyGovernance.Consumer memory tmp = consumers[ consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[_proposalId].value ) ] ];
            
            require( address( tmp.consumer ) != address(0), "execute: action id 4 => consumer not found." );
            
            for(uint256 i = 0; i < tmp.peers.length; i++){
                
                consumerPeerExists[ tmp.consumer ][ tmp.peers[i] ] = false;
                peerExists[ tmp.peers[i] ] = false;
            }
            
            // upon consumer removal, the consumer has to give back the rest of his grant
            grantedUnt -= tmp.grantSizeUnt;
            
            consumerIdByType[ consumers[ consumerCounter ].consumer ] = consumerIdByType[ tmp.consumer ];
            
            consumers[ consumerIdByType[ tmp.consumer ] ] = consumers[ consumerCounter ];
            
            consumerIdByType[ tmp.consumer ] = 0;
            
            consumers[ consumerCounter ].consumer = IUniftyGovernanceConsumer(address(0));
            consumers[ consumerCounter ].grantSizeUnt = 0;
            consumers[ consumerCounter ].grantRateSeconds = 0;
            consumers[ consumerCounter ].grantStartTime = 0;
            
            delete consumers[ consumerCounter ].peers;

            consumerCounter -= 1;
            
            for(uint256 i = 0; i < tmp.peers.length; i++){
                
                try tmp.consumer.removePeerFromWhitelist( tmp.peers[i] ){
                    
                }catch{}
            }
        
            // Action ID = 5
        } else if(proposals[ _proposalId ].actionId == 5){
            
            require( address( consumers[ consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[_proposalId].value3 ) ] ].consumer ) != address(0), "execute: action id 5 => consumer not found." );
            require(!consumerPeerExists[ IUniftyGovernanceConsumer( addressProposal[_proposalId].value3 ) ][ addressProposal[ _proposalId ].value ], "execute: action id 5 => peer exists already.");
            require(!peerExists[addressProposal[ _proposalId ].value], "execute: action id 5 => peer exists already.");

            consumers[ consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[_proposalId].value3 ) ] ].peers.push( addressProposal[ _proposalId ].value );
            
            consumerPeerExists[ IUniftyGovernanceConsumer( addressProposal[_proposalId].value3 ) ][ addressProposal[ _proposalId ].value ] = true;
            peerExists[addressProposal[ _proposalId ].value] = true;
            
            consumers[ consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[_proposalId].value3 ) ] ].consumer.whitelistPeer( addressProposal[ _proposalId ].value );
            
            // Action ID = 6
        } else if(proposals[ _proposalId ].actionId == 6){

            LUniftyGovernance.Consumer memory tmp = consumers[ consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[_proposalId].value2[0] ) ] ];

            require( address( tmp.consumer ) != address(0), "execute: action id 6 => consumer not found." );
            require(consumerPeerExists[ tmp.consumer ][ addressProposal[ _proposalId ].value ], "execute: action id 6 => peer doesn't exist.");
            
            consumerPeerExists[ tmp.consumer ][ addressProposal[ _proposalId ].value ] = false;
            peerExists[addressProposal[ _proposalId ].value] = false;
           
            for(uint256 i = 0; i < tmp.peers.length; i++){
                
                if(addressProposal[ _proposalId ].value == tmp.peers[i]){
                    
                    consumers[ consumerIdByType[ tmp.consumer ] ].peers[i] = tmp.peers[ tmp.peers.length - 1 ];
                    
                    consumers[ consumerIdByType[ tmp.consumer ] ].peers.pop();
                   
                    try tmp.consumer.removePeerFromWhitelist( addressProposal[ _proposalId ].value ){
                        
                    }catch{}
                    
                    break;
                }
            }

            // Action ID = 7
        } else if(proposals[ _proposalId ].actionId == 7){
            
            require(consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[ _proposalId ].value ) ] != 0, "execute: action id 7 => consumer doesn't exist.");
            
            // before we re-calculate the grantable, we give back the rest of what we have
            grantedUnt -= consumers[ consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[ _proposalId ].value ) ] ].grantSizeUnt;
            
            // ...if then there is enough to grant...
            require(grantableUnt() >= uint256Proposal[_proposalId].value, "exeute: action id 7 => not enough available UNT.");
            
            // ...we gonna allow to accept the new grant
            grantedUnt += uint256Proposal[_proposalId].value;
            
            require(uint256Proposal[_proposalId].value3 != 0, "execute: action id 7 => invalid rate");
            
            // setting the proposed startTime to now if it got in the past in the meanwhile 
            if(uint256Proposal[_proposalId].value4 < block.timestamp){
                
                uint256Proposal[_proposalId].value4 = block.timestamp;
            }
            
            consumers[ consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[ _proposalId ].value ) ] ].grantSizeUnt = uint256Proposal[_proposalId].value;
            consumers[ consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[ _proposalId ].value ) ] ].grantRateSeconds = uint256Proposal[_proposalId].value3;
            consumers[ consumerIdByType[ IUniftyGovernanceConsumer( addressProposal[ _proposalId ].value ) ] ].grantStartTime = uint256Proposal[_proposalId].value4;
            
        }
        // proposal action id = 9 does not need to be executed, since it has no parameters. its execution is optional.
        // instead the client should signal if the voting has ended and display the voting results.

        emit Executed(msg.sender, _proposalId);

    }

    /* ################################
    #
    # EPOCHS & GRANTS
    #
    ######################################## */
    
    /**
     * Calculating the current epoch
     * 
     * */
    function epoch() public view returns(uint256){
        
        // we actually want flooring here
        return 1 + ( ( block.timestamp - accrueStart ) / epochDuration );
    }
    
    /**
     * Calculating the available UNT overall
     * based on past and current epochs minus what has been reserved for grants.
     * 
     * Amount of loops is expected to be small, taking hundreds of years before running into gas issues.
     * */
    function grantableUnt() public view returns(uint256){
        
        uint256 all = 0;
        uint256 _epoch = epoch();
        uint256 _prev = genesisReward;
        
        for(uint256 i = 0; i < _epoch; i++){
            
            all += _prev;
            _prev -= ( ( ( _prev * 10**18 ) / 100 ) * 5 ) / 10**18;
            
        }
        
        return all - grantedUnt;
    }
    
    function earnedUnt(IUniftyGovernanceConsumer _consumer) public view returns(uint256){
        
        if(consumerIdByType[ _consumer ] == 0) return 0;
        
        LUniftyGovernance.Consumer memory con = consumers[ consumerIdByType[ _consumer ] ];
        
        if(con.grantRateSeconds == 0) return 0;
        
        uint256 earned = ( ( ( ( block.timestamp - con.grantStartTime ) * 10 ** 18 ) / con.grantRateSeconds ) * con.grantSizeUnt ) / 10**18;
        
        // since the grants are capped, we need to make sure not to display earnings above the cap.
        if(earned > con.grantSizeUnt){
            
            return con.grantSizeUnt;
        }
        
        return earned;
    }
    
    /**
    * Not locked as it must be callable by authorized consumers at any time.
    * This is ok as we do not call any untrusted contract's function 
    * and update all items prior the mint function in the end.
    * 
    */
    function mintUnt(uint256 _amount) external {
        
        require(!isPausing(), "mintUnt: pausing, sorry.");
        require(consumerIdByType[ IUniftyGovernanceConsumer(msg.sender) ] != 0, "mintUnt: access denied.");
        require(allNifStakes >= minNifConsumptionStake, "mintUnt: not enough NIF staked in the governance yet.");
        
        uint256 mint = earnedUnt( IUniftyGovernanceConsumer(msg.sender) );
        
        require(mint != 0 && mint >= _amount, "mintUnt: nothing to mint.");
        
        consumers[ consumerIdByType[ IUniftyGovernanceConsumer(msg.sender) ] ].grantSizeUnt -= _amount;
        
        mintedUnt += _amount;
        mintedUntConsumer[IUniftyGovernanceConsumer(msg.sender)] += _amount;
        
        IERC20Mintable(untAddress).mint(msg.sender, _amount);
    }
    
    /* ################################
    #
    # EXECUTIVES
    # 
    # Executives are responsible for executing accepted proposals.
    # Executives are responsible for pausing the governance (e.g. in case of emergencies).
    #
    ######################################## */

    /**
     * True if either manually paused or overall nif stakes below minNifOverallStake
     *
     * */
    function isPausing() public view returns(bool){

        return pausing || allNifStakes < minNifOverallStake;
    }

    /**
     * Pausing the governance is the responsibility of the governance executives, not votable.
     *
     * */
    function setPaused(bool _pausing) external{

        require(isExecutive[msg.sender], "setPaused: not an executive.");

        pausing = _pausing;
    }

    /**
     * The current executives may add new executives.
     *
     * */
    function setExecutive(address _executive, bool _add) external{

        require(isExecutive[msg.sender], "addExecutive: not an executive.");
        
        if(_add){
            require(!isExecutive[_executive], "addExecutive: already an executive.");
        }else{
            require(msg.sender != _executive, "removeExecutive: you cannot remove yourself.");
        }
        
        isExecutive[_executive] = _add;
    }
}

/* ################################
    #
    # STRUCTS
    #
    ######################################## */

library LUniftyGovernance{

    struct Proposal{
        address initiator;              // the initializing party
        bool executed;                  // yet executed or not?
        uint256 numVotes;               // overall votes
        uint256 numSupporting;          // overall votes in support
        uint256 numNotSupporting;       // overall votes not in support
        uint256 openUntil;              // when will the proposal be expired? timestamp in the future
        uint256 proposalId;             // the proposal ID, value taken from proposalCounter
        uint256 actionId;               // the action id to be executed (resolves to use the right function, e.g. 1 is MinNifOverallStakeProposal)
        string url;                     // the url that points to a json file (in opensea format), containing further information like description
        mapping(address => bool) voted; // voter => bool (voting party has voted?)
    }

    struct Vote{
        address voter;                 // the actual voting party
        bool supporting;               // support yes/no
        uint256 power;                 // the power of this vote
        uint256 proposalId;            // referring proposalId
        uint256 voteTime;              // time of the vote
    }

    // struct that holds uint256 and uint256[] parameters
    // per proposal id for later execution
    struct Uint256Proposal{
        uint256 value;
        uint256 value3;
        uint256 value4;
        uint256[] value2;
    }

    // struct that holds address and address[] parameters
    // per proposal id for later execution
    struct AddressProposal{
        address value;
        address value3;
        address[] value2;
    }

    struct NifStake{

        address user;                  // the user who is staking
        IUniftyGovernanceConsumer peerConsumer; // the consumer of the peer below (optional but if, then both must be set)
        address peer;                  // the peer that this stake allocated to (optional)
        uint256 peerAllocationTime;    // the time when the allocation happened, else 0
        uint256 unstakableFrom;        // timestamp from which the user is allowed to unstake
        uint256 amount;                // the amount of nif that is being staked
    }

    struct Consumer{
 
        IUniftyGovernanceConsumer consumer;   // the consumer object
        uint256 grantStartTime;
        uint256 grantRateSeconds;
        uint256 grantSizeUnt;
        address[] peers;               // array of allowed consumer's peers to receive emissions
    }
}

File 2 of 4 : IERC20Mintable.sol
pragma solidity ^0.8.4;

interface IERC20Mintable{

    function mint(address to, uint256 amount) external;
}

File 3 of 4 : IERC20Simple.sol
pragma solidity ^0.8.4;

/**
 * @dev Simple Interface with a subset of the ERC20 standard as defined in the EIP needed by the DAO (and not more).
 */
interface IERC20Simple {

    /**
     * @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 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);
}

File 4 of 4 : IUniftyGovernanceConsumer.sol
pragma solidity ^0.8.4;

/**
 * Mandatory interface for a UniftyGovernanceConsumer.
 * 
 * */
interface IUniftyGovernanceConsumer{
    
    /**
     * Must be emitted in withdraw() function.
     * 
     * */
    event Withdrawn(address indexed user, uint256 untEarned);

    /**
     * The name of this consumer must be requestable.
     * 
     * This information is supposed to be used in clients.
     * 
     * */
    function name() external view returns(string calldata);
    
    /**
     * The description for this consumer must be requestable.
     * 
     * This information is supposed to be used in clients.
     * 
     * */
    function description() external view returns(string calldata);
    
    /**
     * Peer whitelist required to be implemented.
     * If no peers should be used, this can have an empty implementation.
     * 
     * Example would be to vote for farms in the governance being included.
     * Accepted peers can then be added to the consumer's internal whitelist and get further benefits like UNT.
     * 
     * Must contain a check if the caller has been the governance.
     * 
     * */
    function whitelistPeer(address _peer) external;
    
    /**
     * Peer whitelist removal required to be implemented.
     * If no peers should be used, this can have an empty implementation.
     * 
     * Example would be to vote for farms in the governance being removed and exluded.
     * 
     * Must contain a check if the caller has been the governance.
     * 
     * */
    function removePeerFromWhitelist(address _peer) external;
    
    /**
     * Called by the governance to signal an allocation event.
     * 
     * The implementation must limit calls to the governance and should
     * give the consumer a chance to handle allocations (like timestamp updates)
     * 
     * Returns true if the allocation has been accepted, false if not.
     * 
     * Must contain a check if the caller has been the governance.
     * */
    function allocate(address _account, uint256 prevAllocation, address _peer) external returns(bool);
    
    /**
     * Called by the governance upon staking if the allocation for a user and a peer changes.
     * The consumer has then the ability to check what has been changed and act accordingly.
     *
     * Must contain a check if the caller has been the governance.
     * */
    function allocationUpdate(address _account, uint256 prevAmount, uint256 prevAllocation, address _peer) external returns(bool, uint256);
    
    /**
     * Called by the governance to signal an dellocation event.
     * 
     * The implementation must limit calls to the governance and should
     * give the consumer a chance to handle allocations (like timestamp updates)
     * 
     * This functions is also called by the governance before it calls allocate.
     * This must be akten into account to avoid side-effects.
     * */
    function dellocate(address _account, uint256 prevAllocation, address _peer) external returns(uint256);
    
    /**
     * Called by the governance to determine if allocated stakes of an account in the governance should stay frozen.
     * If this returns true, the governance won't release NIF upon unstaking.
     * 
     * */
    function frozen(address _account) external view returns(bool);
    
    /**
     * Returns true if the peer is whitelisted, otherwise false.
     * 
     * */
    function peerWhitelisted(address _peer) external view returns(bool);
    
    /**
     * Should return a URI, pointing to a json file in the format:
     * 
     * {
     *   name : '',
     *   description : '',
     *   external_link : '',
     * }
     * 
     * Can throw an error if the peer is not whitelisted or return an empty string if there is no further information.
     * Since this is supposed to be called by clients, those have to catch errors and handle empty return values themselves.
     * 
     * */
    function peerUri(address _peer) external view returns(string calldata);
    
    /**
     * Must return the time in seconds that is left until the allocation 
     * of a user to the peer he is allocating to expires.
     * 
     * */
    function timeToUnfreeze(address _account) external view returns(uint256);
    
    /**
     * _peer parameter to apply the AP info for.
     * 
     * Frontend function to help displaying apr/apy and similar strategies.
     *
     * The first index of the returned tuple should return "r" if APR or "y" if APY.
     * 
     * The second index of the returned tuple should return the actual APR/Y value for the consumer.
     * 18 decimals precision required.
     *
     * The 2nd uint256[] array should return a list of proposed services for price discovery on the client-side.
     *
     * 0 = uni-v2 unt/eth
     * 1 = uni-v2 unt/usdt
     * 2 = uni-v2 unt/usdc
     * 3 = uni-v3 unt/eth
     * 4 = uni-v3 unt/usdt
     * 5 = uni-v3 unt/usdc
     * 6 = kucoin unt/usdt
     * 7 = binance unt/usdt
     *
     * The rate and list should be udpatable/extendible through an admin function due to possible updates on the client-side.
     * (e.g. adding more exchanges)
     *
     * */
    function apInfo(address _peer) external view returns(string memory, uint256, uint256[] memory);
    
    /**
     * Withdraws UNT rewards for accounts that stake in the governance and allocated their funds to this consumer and peer.
     * 
     * Must return the amount of withdrawn UNT.
     * 
     * */
    function withdraw() external returns(uint256);
    
    /**
     * Must return the account's _current_ UNT earnings (as of current blockchain state).
     * 
     * Used in the frontend.
     * */
    function earned(address _account) external view returns(uint256);
    
    /**
     * Same as earned() except adding a live component that may be inaccurate due to not yet occurred state-changes.
     * 
     * If unsure how to implement, call and return earned() inside.
     * 
     * Used in the frontend.
     * */
    function earnedLive(address _account) external view returns(uint256);
    
    /**
     * If there are any nif caps per peer, this function should return those.
     * 
     * */
    function peerNifCap(address _peer) external view returns(uint256);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"contract IUniftyGovernanceConsumer","name":"consumer","type":"address"},{"indexed":false,"internalType":"address","name":"peer","type":"address"},{"indexed":false,"internalType":"uint256","name":"untEarned","type":"uint256"}],"name":"Allocated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"contract IUniftyGovernanceConsumer","name":"consumer","type":"address"},{"indexed":false,"internalType":"address","name":"peer","type":"address"},{"indexed":false,"internalType":"uint256","name":"untEarned","type":"uint256"}],"name":"Dellocated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"Executed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"initiator","type":"address"},{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expires","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"actionId","type":"uint256"}],"name":"Proposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stake","type":"uint256"},{"indexed":false,"internalType":"bool","name":"peerAccepted","type":"bool"},{"indexed":false,"internalType":"uint256","name":"untEarned","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"unstake","type":"uint256"},{"indexed":false,"internalType":"bool","name":"peerAccepted","type":"bool"},{"indexed":false,"internalType":"uint256","name":"untEarned","type":"uint256"}],"name":"Unstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"voteId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"supporting","type":"bool"},{"indexed":false,"internalType":"uint256","name":"power","type":"uint256"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"accountInfo","outputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accrueStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"addressProposal","outputs":[{"internalType":"address","name":"value","type":"address"},{"internalType":"address","name":"value3","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"addressProposalInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allNifStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"_consumer","type":"address"},{"internalType":"address","name":"_peer","type":"address"}],"name":"allocate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"consumerCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"","type":"address"}],"name":"consumerIdByType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"_consumer","type":"address"}],"name":"consumerInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"","type":"address"}],"name":"consumerNifAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"consumerPeerExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"consumerPeerNifAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"consumers","outputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"consumer","type":"address"},{"internalType":"uint256","name":"grantStartTime","type":"uint256"},{"internalType":"uint256","name":"grantRateSeconds","type":"uint256"},{"internalType":"uint256","name":"grantSizeUnt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"credit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dellocate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"_consumer","type":"address"}],"name":"earnedUnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epochDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"frozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"graceTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"grantableUnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"grantedUnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isExecutive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPausing","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxProposalDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minNifConsumptionStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minNifOverallStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minNifStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minProposalDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintUnt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintedUnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"","type":"address"}],"name":"mintedUntConsumer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nifAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nifAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"nifAllocationLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nifStakeTimelock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pausing","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"peerExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalExecutionLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"address","name":"initiator","type":"address"},{"internalType":"bool","name":"executed","type":"bool"},{"internalType":"uint256","name":"numVotes","type":"uint256"},{"internalType":"uint256","name":"numSupporting","type":"uint256"},{"internalType":"uint256","name":"numNotSupporting","type":"uint256"},{"internalType":"uint256","name":"openUntil","type":"uint256"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"actionId","type":"uint256"},{"internalType":"string","name":"url","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"_consumer","type":"address"},{"internalType":"uint256","name":"_sizeUnt","type":"uint256"},{"internalType":"uint256","name":"_rateSeconds","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeAddConsumer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"_consumer","type":"address"},{"internalType":"address","name":"_peer","type":"address"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeConsumerRemovePeerFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"_consumer","type":"address"},{"internalType":"address","name":"_peer","type":"address"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeConsumerWhitelistPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeGeneral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxProposalDuration","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeMaxProposalDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minNifConsumptionStake","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeMinNifConsumptionStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minNifOverallStake","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeMinNifOverallStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minNifStake","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeMinNifStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minProposalDuration","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeMinProposalDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nifStakeTimelock","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeNifStakeTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalExecutionLimit","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeProposalExecutionLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quorum","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"_consumer","type":"address"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeRemoveConsumer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUniftyGovernanceConsumer","name":"_consumer","type":"address"},{"internalType":"uint256","name":"_sizeUnt","type":"uint256"},{"internalType":"uint256","name":"_rateSeconds","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"string","name":"_url","type":"string"}],"name":"proposeUpdateConsumerGrant","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"quorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_executive","type":"address"},{"internalType":"bool","name":"_add","type":"bool"}],"name":"setExecutive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_pausing","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stake","type":"uint256"}],"name":"stake","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uint256Proposal","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"value3","type":"uint256"},{"internalType":"uint256","name":"value4","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"}],"name":"uint256ProposalInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_unstaking","type":"uint256"}],"name":"unstake","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"untAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userNifStakes","outputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"contract IUniftyGovernanceConsumer","name":"peerConsumer","type":"address"},{"internalType":"address","name":"peer","type":"address"},{"internalType":"uint256","name":"peerAllocationTime","type":"uint256"},{"internalType":"uint256","name":"unstakableFrom","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"bool","name":"_supporting","type":"bool"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"address","name":"_account","type":"address"}],"name":"voted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"votes","outputs":[{"internalType":"address","name":"voter","type":"address"},{"internalType":"bool","name":"supporting","type":"bool"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"voteTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"votesCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600080546001600160a01b0319908116737e291890b01e5181f7ecc98d79ffbe12ad23df9e179091556001805490911673f8fcc10506ae0734dfd2029959b93e6ace5b2a7017815562278d006002556a295be96e6406697200000060035562093a8060048190556202a300600555600655691fc3842bd1f071c000006007819055678ac7230489e800006008556009819055600a5562127500600b55610384600c556019805460ff19169055601d8190556025553480156100c457600080fd5b5042601a55336000908152602360205260409020805460ff19166001179055615f9a80620000f36000396000f3fe608060405234801561001057600080fd5b506004361061041d5760003560e01c806373bd0cc91161022b578063c919c5be11610130578063d7d500af116100b8578063e78a0e4b11610087578063e78a0e4b14610b3f578063ed3c246614610b52578063f79e735414610b5b578063fe0d94c114610b64578063fea47d0614610b7757600080fd5b8063d7d500af14610b07578063dd71387614610b10578063e03eaf6614610b23578063e7743fbe14610b3657600080fd5b8063d0516650116100ff578063d051665014610a95578063d3ecabd514610aa8578063d5d44d8014610abb578063d6165e9b14610adb578063d6eba1d214610afe57600080fd5b8063c919c5be14610a54578063c9d27afe14610a67578063ce30463614610a7a578063cebd96ce14610a8257600080fd5b80639e11c99c116101b3578063abb612ad11610182578063abb612ad146109bd578063ae512e15146109d0578063c29566d5146109f3578063c4a61fa4146109fc578063c6e36a3214610a0f57600080fd5b80639e11c99c146108e5578063a5b168d214610910578063a694fc3a14610964578063a7310b581461097757600080fd5b806383b7b1cf116101fa57806383b7b1cf1461088e5780638d616e44146108ae578063900cf0cf146108c157806391d488ad146108c957806395c950be146108d257600080fd5b806373bd0cc9146107b857806377948c46146108475780637a27dc58146108725780637ffbe0ae1461088557600080fd5b80633ccfd60b116103315780635af05dcf116102b95780636eef0a56116102885780636eef0a561461071c5780636f9334681461072f57806370e592b81461074257806371de587f146107655780637383ace51461076e57600080fd5b80635af05dcf146106e457806360eac3c0146106ed578063638943eb146107005780636a6fde121461071357600080fd5b80634ff0876a116103005780634ff0876a1461066c5780635277b4ae1461067557806357522ab6146106b257806359ac48ba146106d25780635a9133f7146106db57600080fd5b80633ccfd60b146105df5780634651ed3d146105e75780634699c99b146106505780634921d76d1461066357600080fd5b80631703a018116103b4578063270c404711610383578063270c40471461056d5780632a07a0bf146105755780632bf077e3146105825780632c980a14146105a25780632e17de78146105b557600080fd5b80631703a018146105035780631cafb6651461050c5780631e6627741461051f57806323717fe51461054257600080fd5b80630d34b79c116103f05780630d34b79c146104885780630f6258f6146104a05780631397a6e7146104c257806316c38b3c146104f057600080fd5b8063013cf08b146104225780630526ea14146104535780630a7950e1146104685780630c0512e91461047f575b600080fd5b610435610430366004615ad5565b610b97565b60405161044a99989796959493929190615c69565b60405180910390f35b61046661046136600461598f565b610c70565b005b610471601d5481565b60405190815260200161044a565b610471600e5481565b610490610e2b565b604051901515815260200161044a565b6104b36104ae366004615ad5565b610e47565b60405161044a93929190615c34565b6104906104d0366004615962565b601f60209081526000928352604080842090915290825290205460ff1681565b6104666104fe3660046158fd565b610eda565b61047160075481565b61046661051a3660046158c5565b610f4c565b61053261052d3660046158a9565b6110c4565b60405161044a9493929190615ddd565b600054610555906001600160a01b031681565b6040516001600160a01b03909116815260200161044a565b6104716111ad565b6019546104909060ff1681565b6104716105903660046158a9565b60226020526000908152604090205481565b6104666105b0366004615bb8565b61125c565b6105c86105c3366004615ad5565b6112e9565b60408051921515835260208301919091520161044a565b61046661170f565b6106266105f5366004615ad5565b601b6020526000908152604090208054600182015460028301546003909301546001600160a01b0390921692909184565b604080516001600160a01b039095168552602085019390935291830152606082015260800161044a565b61046661065e366004615bb8565b61188d565b610471600b5481565b61047160025481565b610490610683366004615b05565b6000828152600f602090815260408083206001600160a01b038516845260080190915290205460ff1692915050565b6104716106c0366004615ad5565b60136020526000908152604090205481565b61047160215481565b61047160055481565b610471600c5481565b6104666106fb366004615bb8565b6118fd565b61046661070e366004615ad5565b61196d565b61047160045481565b61046661072a366004615bb8565b611bd1565b61046661073d366004615bb8565b611c41565b6104906107503660046158a9565b601c6020526000908152604090205460ff1681565b61047160205481565b61079d61077c366004615ad5565b60106020526000908152604090208054600182015460029092015490919083565b6040805193845260208401929092529082015260600161044a565b6108096107c63660046158a9565b600d602052600090815260409020805460018201546002830154600384015460048501546005909501546001600160a01b03948516959385169490921692909186565b604080516001600160a01b039788168152958716602087015293909516928401929092526060830152608082015260a081019190915260c00161044a565b610471610855366004615962565b601660209081526000928352604080842090915290825290205481565b610466610880366004615bb8565b611cb1565b610471600a5481565b61047161089c3660046158a9565b601e6020526000908152604090205481565b6104666108bc366004615b4d565b611d21565b610471611d9a565b61047160085481565b6104666108e0366004615a5a565b611dc2565b6104716108f3366004615962565b601560209081526000928352604080842090915290825290205481565b61094461091e366004615ad5565b601160205260009081526040902080546001909101546001600160a01b03918216911682565b604080516001600160a01b0393841681529290911660208301520161044a565b6105c8610972366004615ad5565b612026565b61098a6109853660046158a9565b612443565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a00161044a565b6104666109cb366004615a5a565b6124e6565b6109e36109de366004615ad5565b612688565b60405161044a9493929190615e0c565b61047160145481565b610466610a0a366004615a00565b61270e565b610a22610a1d366004615b97565b6128b9565b604080516001600160a01b0390961686529315156020860152928401919091526060830152608082015260a00161044a565b610466610a62366004615bb8565b612915565b610466610a75366004615b29565b612985565b610471612d4d565b610471610a90366004615962565b612dde565b610490610aa33660046158a9565b6133df565b610471610ab63660046158a9565b613576565b610471610ac93660046158a9565b60246020526000908152604090205481565b610490610ae93660046158a9565b60236020526000908152604090205460ff1681565b610471601a5481565b61047160185481565b600154610555906001600160a01b031681565b610466610b3136600461598f565b6136dc565b61047160095481565b610466610b4d366004615bb8565b613972565b61047160065481565b61047160035481565b610466610b72366004615ad5565b6139e2565b610471610b853660046158a9565b60176020526000908152604090205481565b600f60205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007880180546001600160a01b03891699600160a01b90990460ff16989190610bed90615ed5565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1990615ed5565b8015610c665780601f10610c3b57610100808354040283529160200191610c66565b820191906000526020600020905b815481529060010190602001808311610c4957829003601f168201915b5050505050905089565b602554600114610c9b5760405162461bcd60e51b8152600401610c9290615d5a565b60405180910390fd5b60006025556001600160a01b038416610d1c5760405162461bcd60e51b815260206004820152603f60248201527f70726f706f7365436f6e73756d657257686974656c697374506565723a20706560448201527f6572206d6179206e6f7420626520746865206e756c6c20616464726573732e006064820152608401610c92565b6001600160a01b038086166000908152601f602090815260408083209388168352929052205460ff1615610d625760405162461bcd60e51b8152600401610c9290615d08565b6001600160a01b0384166000908152601c602052604090205460ff1615610d9b5760405162461bcd60e51b8152600401610c9290615d08565b6000610de1338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060059250615006915050565b600090815260116020526040902080546001600160a01b039687166001600160a01b0319918216178255600191820180549890971697169690961790945550505060259190915550565b60195460009060ff1680610e425750600954601454105b905090565b6000818152601160209081526040808320805460018201546002909201805484518187028101870190955280855286956060956001600160a01b039485169590941693918391830182828015610ec657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ea8575b505050505090509250925092509193909250565b3360009081526023602052604090205460ff16610f395760405162461bcd60e51b815260206004820152601c60248201527f7365745061757365643a206e6f7420616e206578656375746976652e000000006044820152606401610c92565b6019805460ff1916911515919091179055565b3360009081526023602052604090205460ff16610fab5760405162461bcd60e51b815260206004820152601f60248201527f6164644578656375746976653a206e6f7420616e206578656375746976652e006044820152606401610c92565b801561102b576001600160a01b03821660009081526023602052604090205460ff16156110265760405162461bcd60e51b815260206004820152602360248201527f6164644578656375746976653a20616c726561647920616e20657865637574696044820152623b329760e91b6064820152608401610c92565b611099565b336001600160a01b03831614156110995760405162461bcd60e51b815260206004820152602c60248201527f72656d6f76654578656375746976653a20796f752063616e6e6f742072656d6f60448201526b3b32903cb7bab939b2b6331760a11b6064820152608401610c92565b6001600160a01b03919091166000908152602360205260409020805460ff1916911515919091179055565b6001600160a01b038082166000908152601e60209081526040808320548352601b8252808320815160a081018352815490951685526001810154858401526002810154858301526003810154606086810191909152600482018054845181870281018701909552808552959687968796939587959294929360808601939192909183018282801561117e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611160575b505050505081525050905080602001518160400151826060015183608001519450945094509450509193509193565b60006025546001146111d15760405162461bcd60e51b8152600401610c9290615d5a565b60006025819055338152600d60205260409020600101546001600160a01b03166112495760405162461bcd60e51b8152602060048201526024808201527f64656c6c6f63617465506565723a206e6f7468696e6720746f2064656c6c6f6360448201526330ba329760e11b6064820152608401610c92565b6112523361545a565b9050600160255590565b60255460011461127e5760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600e9250615006915050565b600090815260106020526040902094909455505060016025555050565b60008060255460011461130e5760405162461bcd60e51b8152600401610c9290615d5a565b60006025819055338152600d6020526040902060050154158015906113455750336000908152600d60205260409020600501548311155b61139d5760405162461bcd60e51b8152602060048201526024808201527f756e7374616b65496e7465726e616c3a20696e73756666696369656e742066756044820152633732399760e11b6064820152608401610c92565b600b546001906000906113b09042615e67565b336000908152600d60209081526040808320600401939093556024905290812080548792906113e0908490615e67565b9091555050336000908152600d6020526040902060050154611403908690615ebe565b61145b576114103361545a565b336000908152600d6020526040812060050180549293508792909190611437908490615ebe565b9250508190555084601460008282546114509190615ebe565b909155506116bc9050565b336000908152600d6020526040902060050154611479908690615ebe565b158015906114a15750336000908152600d60205260409020600101546001600160a01b031615155b80156114d45750336000908152600d60209081526040808320600101546001600160a01b03168352601e90915290205415155b1561167b57336000908152600d602052604081206005018054918791906114fb8385615ebe565b9250508190555085601460008282546115149190615ebe565b9091555050336000908152600d6020908152604080832060018101546001600160a01b0390811685526015845282852060029092015416845290915281208054918891906115628385615ebe565b9091555050336000908152600d60209081526040808320600101546001600160a01b0316835260179091528120805489929061159f908490615ebe565b9250508190555086601860008282546115b89190615ebe565b9091555050336000818152600d6020526040908190204260038201556001810154600290910154915163038cf3c360e51b8152600481019390935260248301859052604483018490526001600160a01b039182166064840152169063719e7860906084016040805180830381600087803b15801561163557600080fd5b505af1925050508015611665575060408051601f3d908101601f1916820190925261166291810190615935565b60015b61166e57611674565b90945092505b50506116bc565b336000908152600d60205260408120600501805487929061169d908490615ebe565b9250508190555084601460008282546116b69190615ebe565b90915550505b60408051868152831515602082015290810182905233907fb870217905665894c8434c46e122702ec5e8a7f6c5f6751b58ee4d4668c7ad859060600160405180910390a260016025559094909350915050565b6025546001146117315760405162461bcd60e51b8152600401610c9290615d5a565b600060255560195460ff16806117665750600c54336000908152600d60205260409020600401546117629190615e67565b4210155b6117b25760405162461bcd60e51b815260206004820152601b60248201527f77697468647261773a206e6966207374696c6c206c6f636b65642e00000000006044820152606401610c92565b3360008181526024602081905260408083208054908490559254905163a9059cbb60e01b8152600481019490945290830182905290916001600160a01b039091169063a9059cbb90604401602060405180830381600087803b15801561181757600080fd5b505af115801561182b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184f9190615919565b5060405181815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d59060200160405180910390a2506001602555565b6025546001146118af5760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060089250615006915050565b60255460011461191f5760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060029250615006915050565b611975610e2b565b156119c25760405162461bcd60e51b815260206004820152601860248201527f6d696e74556e743a2070617573696e672c20736f7272792e00000000000000006044820152606401610c92565b336000908152601e6020526040902054611a1e5760405162461bcd60e51b815260206004820152601760248201527f6d696e74556e743a206163636573732064656e6965642e0000000000000000006044820152606401610c92565b600a546014541015611a905760405162461bcd60e51b815260206004820152603560248201527f6d696e74556e743a206e6f7420656e6f756768204e4946207374616b6564206960448201527437103a34329033b7bb32b93730b731b2903cb2ba1760591b6064820152608401610c92565b6000611a9b33613576565b90508015801590611aac5750818110155b611af85760405162461bcd60e51b815260206004820152601960248201527f6d696e74556e743a206e6f7468696e6720746f206d696e742e000000000000006044820152606401610c92565b336000908152601e60209081526040808320548352601b90915281206003018054849290611b27908490615ebe565b925050819055508160216000828254611b409190615e67565b90915550503360009081526022602052604081208054849290611b64908490615e67565b90915550506001546040516340c10f1960e01b8152336004820152602481018490526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015611bb557600080fd5b505af1158015611bc9573d6000803e3d6000fd5b505050505050565b602554600114611bf35760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600a9250615006915050565b602554600114611c635760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600d9250615006915050565b602554600114611cd35760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600b9250615006915050565b602554600114611d435760405162461bcd60e51b8152600401610c9290615d5a565b6000602581905550611d8f338484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060099250615006915050565b505060016025555050565b6000600254601a5442611dad9190615ebe565b611db79190615e7f565b610e42906001615e67565b602554600114611de45760405162461bcd60e51b8152600401610c9290615d5a565b60006025556001600160a01b038716611e655760405162461bcd60e51b815260206004820152603960248201527f70726f706f7365416464436f6e73756d65723a20636f6e73756d6572206d617960448201527f206e6f7420626520746865206e756c6c20616464726573732e000000000000006064820152608401610c92565b6001600160a01b0387166000908152601e602052604090205415611ee05760405162461bcd60e51b815260206004820152602c60248201527f70726f706f7365416464436f6e73756d65723a20636f6e73756d65722065786960448201526b39ba399030b63932b0b23c9760a11b6064820152608401610c92565b84611f2d5760405162461bcd60e51b815260206004820181905260248201527f70726f706f7365416464436f6e73756d65723a20696e76616c696420726174656044820152606401610c92565b85611f8a5760405162461bcd60e51b815260206004820152602760248201527f70726f706f7365416464436f6e73756d65723a20696e76616c6964206772616e6044820152663a1039b4bd329760c91b6064820152608401610c92565b6000611fd0338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060039250615006915050565b600090815260116020908152604080832080546001600160a01b0319166001600160a01b039c909c169b909b17909a55601090529790972095865550505060018381019290925560029092019190915560255550565b60008060255460011461204b5760405162461bcd60e51b8152600401610c9290615d5a565b600060255560195460ff161561209c5760405162461bcd60e51b815260206004820152601660248201527539ba30b5b29d103830bab9b4b733961039b7b9393c9760511b6044820152606401610c92565b600083116120ec5760405162461bcd60e51b815260206004820152601e60248201527f7374616b653a20696e76616c6964207374616b696e6720616d6f756e742e00006044820152606401610c92565b336000908152600d602052604081206005018054600192918690836121118385615e67565b9091555050600b546121239042615e67565b336000908152600d60205260408120600401919091556014805488929061214b908490615e67565b9091555050336000908152600d60205260409020600101546001600160a01b0316158015906121a15750336000908152600d60209081526040808320600101546001600160a01b03168352601e90915290205415155b1561236457336000908152600d6020908152604080832060018101546001600160a01b0390811685526015845282852060029092015416845290915281208054918891906121ef8385615e67565b9091555050336000908152600d60209081526040808320600101546001600160a01b0316835260179091528120805489929061222c908490615e67565b9250508190555086601860008282546122459190615e67565b9091555050336000818152600d6020526040908190204260038201556001810154600290910154915163038cf3c360e51b8152600481019390935260248301859052604483018490526001600160a01b039182166064840152169063719e7860906084016040805180830381600087803b1580156122c257600080fd5b505af19250505080156122f2575060408051601f3d908101601f191682019092526122ef91810190615935565b60015b6122fb57612301565b90945092505b836123625760405162461bcd60e51b815260206004820152602b60248201527f7374616b653a20616c6c6f636174696f6e20757064617465206861732062656560448201526a37103932b532b1ba32b21760a91b6064820152608401610c92565b505b6000546040516323b872dd60e01b8152336004820152306024820152604481018890526001600160a01b03909116906323b872dd90606401602060405180830381600087803b1580156123b657600080fd5b505af11580156123ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ee9190615919565b5060408051878152841515602082015290810183905233907fb090af6b9902ba8a7bc46486cd082be61763b3decc7be5ab48dc26422860230c9060600160405180910390a25060016025559094909350915050565b6001600160a01b038082166000818152600d6020818152604080842060018101548716808652601f8452828620600283015490981680875297845291852054958552929091526003909101549193849384938493849360ff909316929091836124b0575060009150819050805b6001600160a01b03999099166000908152600d602052604090206004810154600590910154929a91999850965090945092505050565b6025546001146125085760405162461bcd60e51b8152600401610c9290615d5a565b600060258190556001600160a01b0388168152601e60205260409020546125865760405162461bcd60e51b815260206004820152602c60248201527f757064617465436f6e73756d65724772616e743a20636f6e73756d657220646f60448201526b32b9b713ba1032bc34b9ba1760a11b6064820152608401610c92565b846125dd5760405162461bcd60e51b815260206004820152602160248201527f757064617465436f6e73756d65724772616e743a20696e76616c6964207261746044820152606560f81b6064820152608401610c92565b856126425760405162461bcd60e51b815260206004820152602f60248201527f70726f706f7365557064617465436f6e73756d65724772616e743a20696e766160448201526e3634b21033b930b73a1039b4bd329760891b6064820152608401610c92565b6000611fd0338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060079250615006915050565b60008181526010602090815260408083208054600182015460028301546003909301805485518188028101880190965280865287968796606096939290918391908301828280156126f857602002820191906000526020600020905b8154815260200190600101908083116126e4575b5050505050905093509350935093509193509193565b6025546001146127305760405162461bcd60e51b8152600401610c9290615d5a565b60006025556001600160a01b0384166127b15760405162461bcd60e51b815260206004820152603c60248201527f70726f706f736552656d6f7665436f6e73756d65723a20636f6e73756d65722060448201527f6d6179206e6f7420626520746865206e756c6c20616464726573732e000000006064820152608401610c92565b6001600160a01b038085166000818152601e60209081526040808320548352601b9091529020549091161461283b5760405162461bcd60e51b815260206004820152602a60248201527f70726f706f736552656d6f7665436f6e73756d65723a20636f6e73756d6572206044820152693737ba103337bab7321760b11b6064820152608401610c92565b6000612881338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060049250615006915050565b600090815260116020526040902080546001600160a01b0319166001600160a01b039690961695909517909455505060016025555050565b601260205281600052604060002081815481106128d557600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0383169550600160a01b90920460ff169350919085565b6025546001146129375760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250615006915050565b6025546001146129a75760405162461bcd60e51b8152600401610c9290615d5a565b60006025556129b4610e2b565b156129f95760405162461bcd60e51b81526020600482015260156024820152743b37ba329d103830bab9b4b733961039b7b9393c9760591b6044820152606401610c92565b600854336000908152600d60205260409020600501541015612a545760405162461bcd60e51b81526020600482015260146024820152733b37ba329d1034b73b30b634b21039ba30b5b29760611b6044820152606401610c92565b6000828152600f60205260409020546001600160a01b031615801590612a8b57506000828152600f60205260409020600401544211155b612ae25760405162461bcd60e51b815260206004820152602260248201527f766f74653a20696e76616c6964206f7220657870697265642070726f706f7361604482015261361760f11b6064820152608401610c92565b6000828152600f6020908152604080832033845260080190915290205460ff1615612b4f5760405162461bcd60e51b815260206004820152601860248201527f766f74653a20796f7520766f74656420616c72656164792e00000000000000006044820152606401610c92565b6001600f60008481526020019081526020016000206001016000828254612b769190615e67565b90915550508015612bc057336000908152600d6020908152604080832060050154858452600f9092528220600201805491929091612bb5908490615e67565b90915550612bfa9050565b336000908152600d6020908152604080832060050154858452600f9092528220600301805491929091612bf4908490615e67565b90915550505b6000828152600f602090815260408083203380855260089091018352818420805460ff1916600190811790915586855260128452828520835160a081018552838152871515818701908152848852600d8088528689206005018054848901908152606085018d815242608087019081528754808a018955978d528b8d2096516004909802909601805495511515600160a01b026001600160a81b03199096166001600160a01b0398909816979097179490941786555195850195909555905160028401559051600390920191909155878652601385528386205495839052909352915490518592917fd58cd2f260be6feac853baa17bd79162b96a96fde5d48d8a1e456fdf09f06d5391612d18918715158252602082015260400190565b60405180910390a46000828152601360205260408120805460019290612d3f908490615e67565b909155505060016025555050565b60008080612d59611d9a565b60035490915060005b82811015612dc857612d748285615e67565b9350670de0b6b3a76400006064612d8b8483615e9f565b612d959190615e7f565b612da0906005615e9f565b612daa9190615e7f565b612db49083615ebe565b915080612dc081615f10565b915050612d62565b50602054612dd69084615ebe565b935050505090565b6000602554600114612e025760405162461bcd60e51b8152600401610c9290615d5a565b6000602555612e0f610e2b565b15612e5c5760405162461bcd60e51b815260206004820152601960248201527f616c6c6f636174653a2070617573696e672c20736f7272792e000000000000006044820152606401610c92565b336000908152600d6020526040902060050154612ebb5760405162461bcd60e51b815260206004820152601f60248201527f616c6c6f636174653a20796f75206d757374207374616b652066697273742e006044820152606401610c92565b6001600160a01b03821615801590612edb57506001600160a01b03831615155b612f3c5760405162461bcd60e51b815260206004820152602c60248201527f616c6c6f636174653a207065657220616e6420636f6e73756d6572206d75737460448201526b3713ba10313290373ab6361760a11b6064820152608401610c92565b6001600160a01b0383166000908152601e6020526040902054612fab5760405162461bcd60e51b815260206004820152602160248201527f616c6c6f636174653a20636f6e73756d657220646f65736e27742065786973746044820152601760f91b6064820152608401610c92565b6001600160a01b038084166000908152601f602090815260408083209386168352929052205460ff166130205760405162461bcd60e51b815260206004820152601d60248201527f616c6c6f636174653a207065657220646f65736e27742065786973742e0000006044820152606401610c92565b336000908152600d60205260409020600201546001600160a01b03838116911614156130a95760405162461bcd60e51b815260206004820152603260248201527f616c6c6f636174653a20796f752061726520616c6c6f636174696e6720746f206044820152713a3434b9903832b2b91030b63932b0b23c9760711b6064820152608401610c92565b6130b2336133df565b156131365760405162461bcd60e51b815260206004820152604860248201527f616c6c6f636174653a2063616e6e6f742064656c6c6f636174652c20616c6c6f60448201527f636174696f6e207374696c6c2066726f7a656e2062792063757272656e74206360648201526737b739bab6b2b91760c11b608482015260a401610c92565b60006131413361545a565b336000908152600d602090815260408083206001810180546001600160a01b03199081166001600160a01b038c8116918217909355600284018054909216928b16928317909155426003840155855260158452828520908552909252822080546005909201549394509092916131b78385615e67565b9091555050336000908152600d60209081526040808320600501546001600160a01b0389168452601790925282208054919290916131f6908490615e67565b9091555050336000908152600d60205260408120600501546018805491929091613221908490615e67565b9091555050336000908152600d602090815260408083206001818101546001600160a01b0390811686526016855283862060029093015416855292528220805491929091613270908490615e67565b9091555050604051632531fdad60e01b8152336004820152602481018290526001600160a01b03858116604483015260009190871690632531fdad90606401602060405180830381600087803b1580156132c957600080fd5b505af19250505080156132f9575060408051601f3d908101601f191682019092526132f691810190615919565b60015b61330257613305565b90505b806133845760405162461bcd60e51b815260206004820152604360248201527f616c6c6f636174653a20616c6c6f636174696f6e2064656e696564206279206360448201527f6f6e73756d65722f70656572206f7220636f6e73756d6572206973206661756c6064820152623a3c9760e91b608482015260a401610c92565b604080516001600160a01b0388811682528716602082015290810184905233907f7519d597df1b9f51919758c22c20c3efcb772fb7c5ce2b2ac37729890aaf50f49060600160405180910390a2505060016025559392505050565b6001600160a01b038082166000908152600d60209081526040808320600181015485168452601f835281842060029091015490941683529290529081205460ff16801561356d576001600160a01b038381166000908152600d602052604080822060018101546002909101549151635c5e552b60e01b8152918416600483015291929190911690635c5e552b9060240160206040518083038186803b15801561348757600080fd5b505afa9250505080156134b7575060408051601f3d908101601f191682019092526134b491810190615919565b60015b6134c0576134c3565b90505b806134d2575060009392505050565b6001600160a01b038481166000818152600d602052604090819020600101549051630d05166560e41b815260048101929092529091169063d05166509060240160206040518083038186803b15801561352a57600080fd5b505afa92505050801561355a575060408051601f3d908101601f1916820190925261355791810190615919565b60015b6135635761356b565b949350505050565b505b50600092915050565b6001600160a01b0381166000908152601e602052604081205461359b57506000919050565b6001600160a01b038083166000908152601e60209081526040808320548352601b8252808320815160a081018352815490951685526001810154858401526002810154858301526003810154606086015260048101805483518186028101860190945280845294959491936080860193929083018282801561364657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613628575b50505050508152505090508060400151600014156136675750600092915050565b6000670de0b6b3a76400008260600151836040015184602001514261368c9190615ebe565b61369e90670de0b6b3a7640000615e9f565b6136a89190615e7f565b6136b29190615e9f565b6136bc9190615e7f565b905081606001518111156136d557506060015192915050565b9392505050565b6025546001146136fe5760405162461bcd60e51b8152600401610c9290615d5a565b60006025556001600160a01b0385166137955760405162461bcd60e51b815260206004820152604d60248201527f70726f706f7365436f6e73756d657252656d6f76655065657246726f6d57686960448201527f74656c6973743a20636f6e73756d6572206d6179206e6f74206265207468652060648201526c373ab6361030b2323932b9b99760991b608482015260a401610c92565b6001600160a01b038086166000818152601e60209081526040808320548352601b909152902054909116146138325760405162461bcd60e51b815260206004820152603b60248201527f70726f706f7365436f6e73756d657252656d6f76655065657246726f6d57686960448201527f74656c6973743a20636f6e73756d6572206e6f7420666f756e642e00000000006064820152608401610c92565b6001600160a01b038086166000908152601f602090815260408083209388168352929052205460ff166138cd5760405162461bcd60e51b815260206004820152603760248201527f70726f706f7365436f6e73756d657252656d6f76655065657246726f6d57686960448201527f74656c6973743a2070656572206e6f7420666f756e642e0000000000000000006064820152608401610c92565b6000613913338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060069250615006915050565b6000908152601160209081526040822080546001600160a01b039889166001600160a01b031991821617825560029091018054600181810183559185529290932090910180549890971697169690961790945550505060259190915550565b6025546001146139945760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600c9250615006915050565b602554600114613a045760405162461bcd60e51b8152600401610c9290615d5a565b6000602555613a11610e2b565b15613a5e5760405162461bcd60e51b815260206004820152601860248201527f657865637574653a2070617573696e672c20736f7272792e00000000000000006044820152606401610c92565b3360009081526023602052604090205460ff16613abd5760405162461bcd60e51b815260206004820152601a60248201527f657865637574653a206e6f7420616e206578656375746976652e0000000000006044820152606401610c92565b6000818152600f60205260409020546001600160a01b0316613b215760405162461bcd60e51b815260206004820152601a60248201527f657865637574653a20696e76616c69642070726f706f73616c2e0000000000006044820152606401610c92565b6000818152600f6020526040902054600160a01b900460ff1615613b9c5760405162461bcd60e51b815260206004820152602c60248201527f657865637574653a2070726f706f73616c20686173206265656e20657865637560448201526b3a32b21030b63932b0b23c9760a11b6064820152608401610c92565b6007546000828152600f602052604090206003810154600290910154613bc29190615e67565b1015613c105760405162461bcd60e51b815260206004820152601c60248201527f657865637574653a2071756f72756d206e6f7420726561636865642e000000006044820152606401610c92565b6000818152600f60205260409020600381015460029091015411613c765760405162461bcd60e51b815260206004820152601c60248201527f657865637574653a206e6f7420656e6f75676820737570706f72742e000000006044820152606401610c92565b6000818152600f6020526040902060019081015411613cd75760405162461bcd60e51b815260206004820152601f60248201527f657865637574653a206e656564206174206c65617374203220766f7465732e006044820152606401610c92565b600c546000828152600f6020526040902060040154613cf69190615e67565b4211613d5a5760405162461bcd60e51b815260206004820152602d60248201527f657865637574653a20766f74696e6720616e642067726163652074696d65206e60448201526c37ba103cb2ba1032b73232b21760991b6064820152608401610c92565b600654600c546000838152600f6020526040902060040154613d7c9190615e67565b613d869190615e67565b4210613ddf5760405162461bcd60e51b815260206004820152602260248201527f657865637574653a20657865637574696f6e2077696e646f7720657870697265604482015261321760f11b6064820152608401610c92565b6000818152600f60205260409020805460ff60a01b1916600160a01b1781556006015460011415613e2157600081815260106020526040902054600955614fd1565b6000818152600f602052604090206006015460021415613e5257600081815260106020526040902054600855614fd1565b6000818152600f602052604090206006015460081415613e8357600081815260106020526040902054600a55614fd1565b6000818152600f6020526040902060060154600a1415613eb457600081815260106020526040902054600455614fd1565b6000818152600f6020526040902060060154600b1415613ee557600081815260106020526040902054600555614fd1565b6000818152600f6020526040902060060154600c1415613f1657600081815260106020526040902054600655614fd1565b6000818152600f6020526040902060060154600d1415613f4757600081815260106020526040902054600755614fd1565b6000818152600f6020526040902060060154600e1415613f7857600081815260106020526040902054600b55614fd1565b6000818152600f602052604090206006015460031415614208576000818152601160209081526040808320546001600160a01b03168352601e9091529020541561401d5760405162461bcd60e51b815260206004820152603060248201527f657865637574653a20616374696f6e2069642033203d3e20636f6e73756d657260448201526f1032bc34b9ba399030b63932b0b23c9760811b6064820152608401610c92565b600081815260106020526040902054614034612d4d565b101561409b5760405162461bcd60e51b815260206004820152603060248201527f6578657574653a20616374696f6e2069642033203d3e206e6f7420656e6f756760448201526f341030bb30b4b630b13632902aa72a1760811b6064820152608401610c92565b6000818152601060205260409020600101546141055760405162461bcd60e51b8152602060048201526024808201527f657865637574653a20616374696f6e2069642033203d3e20696e76616c6964206044820152637261746560e01b6064820152608401610c92565b600081815260106020526040902060020154421115614134576000818152601060205260409020426002909101555b60008181526010602090815260408220548154909290614155908490615e67565b9091555050600081815260116020908152604080832054601d80548552601b80855283862080546001600160a01b0319166001600160a01b0394851617905586865260108552838620805483548852918652848720600301919091556001818101548354885285882060029081019190915590910154825487528487208201558154808752848720549093168652601e909452918420819055919290916141fd908490615e67565b90915550614fd19050565b6000818152600f60205260409020600601546004141561465d576000818152601160209081526040808320546001600160a01b039081168452601e8352818420548452601b8352818420825160a081018452815490921682526001810154828501526002810154828401526003810154606083015260048101805484518187028101870190955280855292949193608086019390928301828280156142d657602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116142b8575b5050509190925250508151919250506001600160a01b031661434e5760405162461bcd60e51b815260206004820152602b60248201527f657865637574653a20616374696f6e2069642034203d3e20636f6e73756d657260448201526a103737ba103337bab7321760a91b6064820152608401610c92565b60005b81608001515181101561444c5781516001600160a01b03166000908152601f60205260408120608084015180518391908590811061439f57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055506000601c60008460800151848151811061440857634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790558061444481615f10565b915050614351565b508060600151602060008282546144639190615ebe565b909155505080516001600160a01b039081166000908152601e6020818152604080842054601d80548652601b808552838720548816875285855283872092909255548552808352818520875187168652938352818520548552909152909120815481546001600160a01b03191693169290921782556001818101549083015560028082015490830155600380820154908301556004808201805492939261450d9284019190615768565b505081516001600160a01b03166000908152601e60209081526040808320839055601d80548452601b90925280832080546001600160a01b03191690558154835280832060030183905581548352808320600201839055815483528083206001018390559054825281206145859250600401906157b8565b6001601d60008282546145989190615ebe565b90915550600090505b8160800151518110156146565781600001516001600160a01b0316635b00ce54836080015183815181106145e557634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b815260040161461891906001600160a01b0391909116815260200190565b600060405180830381600087803b15801561463257600080fd5b505af1925050508015614643575060015b508061464e81615f10565b9150506145a1565b5050614fd1565b6000818152600f6020526040902060060154600514156148bd576000818152601160209081526040808320600101546001600160a01b039081168452601e8352818420548452601b909252909120541661470d5760405162461bcd60e51b815260206004820152602b60248201527f657865637574653a20616374696f6e2069642035203d3e20636f6e73756d657260448201526a103737ba103337bab7321760a91b6064820152608401610c92565b600081815260116020908152604080832060018101546001600160a01b039081168552601f8452828520915416845290915290205460ff16156147625760405162461bcd60e51b8152600401610c9290615d91565b6000818152601160209081526040808320546001600160a01b03168352601c90915290205460ff16156147a75760405162461bcd60e51b8152600401610c9290615d91565b6000818152601160208181526040808420600180820180546001600160a01b039081168852601e808752858920548952601b808852868a208654600491820180548089018255908d528a8d200180546001600160a01b031916918616919091179055845484168b52601f8952878b20875485168c528952878b20805460ff199081168817909155875485168c52601c8a52888c20805490911690961790955592548216895286528488205488529085528387205496889052949093525490516376e30c0360e11b81529083169181019190915291169063edc6180690602401600060405180830381600087803b1580156148a057600080fd5b505af11580156148b4573d6000803e3d6000fd5b50505050614fd1565b6000818152600f602052604090206006908101541415614d28576000601b6000601e60006011600087815260200190815260200160002060020160008154811061491757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b039081168452838201949094526040928301822054855284810195909552928101909220825160a081018452815490921682526001810154828501526002810154828401526003810154606083015260048101805484518187028101870190955280855292949193608086019390928301828280156149d457602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116149b6575b5050509190925250508151919250506001600160a01b0316614a4c5760405162461bcd60e51b815260206004820152602b60248201527f657865637574653a20616374696f6e2069642036203d3e20636f6e73756d657260448201526a103737ba103337bab7321760a91b6064820152608401610c92565b80516001600160a01b039081166000908152601f6020908152604080832086845260118352818420549094168352929052205460ff16614ae25760405162461bcd60e51b815260206004820152602b60248201527f657865637574653a20616374696f6e2069642036203d3e207065657220646f6560448201526a39b713ba1032bc34b9ba1760a91b6064820152608401610c92565b80516001600160a01b039081166000908152601f6020908152604080832086845260118352818420805486168552908352818420805460ff1990811690915590549094168352601c909152812080549092169091555b8160800151518110156146565781608001518181518110614b6957634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600085815260119092526040909120546001600160a01b0390811691161415614d165760808201518051614bab90600190615ebe565b81518110614bc957634e487b7160e01b600052603260045260246000fd5b60209081029190910181015183516001600160a01b03166000908152601e83526040808220548252601b90935291909120600401805483908110614c1d57634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905584519092168152601e82526040808220548252601b90925220600401805480614c7e57634e487b7160e01b600052603160045260246000fd5b60008281526020808220600019908401810180546001600160a01b0319169055909201909255835185835260119091526040918290205491516316c0339560e21b81526001600160a01b039283166004820152911690635b00ce5490602401600060405180830381600087803b158015614cf757600080fd5b505af1925050508015614d08575060015b614d1157614656565b614656565b80614d2081615f10565b915050614b38565b6000818152600f602052604090206006015460071415614fd1576000818152601160209081526040808320546001600160a01b03168352601e909152902054614dcb5760405162461bcd60e51b815260206004820152602f60248201527f657865637574653a20616374696f6e2069642037203d3e20636f6e73756d657260448201526e103237b2b9b713ba1032bc34b9ba1760891b6064820152608401610c92565b6000818152601160209081526040808320546001600160a01b03168352601e8252808320548352601b82528220600301548154909290614e0c908490615ebe565b9091555050600081815260106020526040902054614e28612d4d565b1015614e8f5760405162461bcd60e51b815260206004820152603060248201527f6578657574653a20616374696f6e2069642037203d3e206e6f7420656e6f756760448201526f341030bb30b4b630b13632902aa72a1760811b6064820152608401610c92565b60008181526010602090815260408220548154909290614eb0908490615e67565b9091555050600081815260106020526040902060010154614f1f5760405162461bcd60e51b8152602060048201526024808201527f657865637574653a20616374696f6e2069642037203d3e20696e76616c6964206044820152637261746560e01b6064820152608401610c92565b600081815260106020526040902060020154421115614f4e576000818152601060205260409020426002909101555b600081815260106020908152604080832080546011845282852080546001600160a01b039081168752601e808752858820548852601b80885286892060030194909455600180860154845484168a52828952878a20548a52858952878a206002908101919091559095015492549091168752855283862054865293529220909101555b604051819033907f6f6c6d78a4851d4c222c8404fc92372ee84b7b81054305ae8ea3c83c2dabd42e90600090a3506001602555565b6000615010610e2b565b1561505d5760405162461bcd60e51b815260206004820152601c60248201527f6e657750726f706f73616c3a2070617573696e672c20736f7272792e000000006044820152606401610c92565b6004548411156150af5760405162461bcd60e51b815260206004820152601f60248201527f6e657750726f706f73616c3a206475726174696f6e20746f6f206c6f6e672e006044820152606401610c92565b60055484101561510f5760405162461bcd60e51b815260206004820152602560248201527f6e657750726f706f73616c3a206d696e2e206475726174696f6e20746f6f20736044820152643437b93a1760d91b6064820152608401610c92565b6008546001600160a01b0386166000908152600d6020526040902060050154101561517c5760405162461bcd60e51b815260206004820152601b60248201527f6e657750726f706f73616c3a20696e76616c6964207374616b652e00000000006044820152606401610c92565b600e80546000908152600f6020908152604080832080546001600160a01b0319166001600160a01b038b161790559254825291902084516151c5926007909201918601906157d9565b506001600f6000600e54815260200190815260200160002060010160008282546151ef9190615e67565b90915550506001600160a01b0385166000908152600d6020908152604080832060050154600e548452600f9092528220600201805491929091615233908490615e67565b9091555050600e546000818152600f6020908152604080832060058101949094556001600160a01b03891683526008909301905220805460ff1916600117905561527d8442615e67565b600e80546000908152600f6020908152604080832060049081019590955583548352808320600601879055925480835291839020909301548251908152928301859052916001600160a01b038816917ff97c8990c1edf2d023da24ff6e6f77566a9513d2e0a2184483479f60b192ab18910160405180910390a3600e80546000818152601260209081526040808320815160a0810183526001600160a01b03808d168083526001838701818152918852600d87528588206005015484870190815260608501998a52426080860190815286548084018855968a52888a2095516004909702909501805493511515600160a01b026001600160a81b031990941696909416959095179190911782559251818401559551600287015551600390950194909455935482526013905291909120546153b791615e67565b600e546001600160a01b0387166000818152600d602090815260409182902060050154825160018152918201527fd58cd2f260be6feac853baa17bd79162b96a96fde5d48d8a1e456fdf09f06d53910160405180910390a4600e546000818152601360205260408120805460019290615431908490615e67565b925050819055506001600e600082825461544b9190615e67565b90915550909695505050505050565b6001600160a01b038181166000908152600d602052604081206001015490911661548657506000919050565b61548f826133df565b158061549d575060195460ff165b6155215760405162461bcd60e51b815260206004820152604960248201527f64656c6c6f63617465496e7465726e616c3a2063616e6e6f742064656c6c6f6360448201527f6174652c20616c6c6f636174696f6e207374696c6c2066726f7a656e2062792060648201526831b7b739bab6b2b91760b91b608482015260a401610c92565b6001600160a01b038281166000908152600d602090815260408083206001810154600282015490861680865260158552838620919096168086529352908320805460059092015492939290836155778385615ebe565b90915550506001600160a01b038087166000908152600d602090815260408083206005015493881683526017909152812080549091906155b8908490615ebe565b90915550506001600160a01b0386166000908152600d602052604081206005015460188054919290916155ec908490615ebe565b90915550506001600160a01b0380851660009081526016602090815260408083209387168352929052908120805460019290615629908490615ebe565b90915550506001600160a01b038087166000908152600d602090815260408083206001810180546001600160a01b03199081169091556002820180549091169055426003909101559287168252601e905220541561570f5760405163143343d960e11b81526001600160a01b03878116600483015260248201839052848116604483015285169063286687b290606401602060405180830381600087803b1580156156d357600080fd5b505af1925050508015615703575060408051601f3d908101601f1916820190925261570091810190615aed565b60015b61570c5761570f565b91505b604080516001600160a01b0386811682528581166020830152918101849052908716907f63c76c2cce809bac86aa71be83c1849232efe3e2976c649eb4e44613442682ff9060600160405180910390a250949350505050565b8280548282559060005260206000209081019282156157a85760005260206000209182015b828111156157a857825482559160010191906001019061578d565b506157b492915061584d565b5090565b50805460008255906000526020600020908101906157d6919061584d565b50565b8280546157e590615ed5565b90600052602060002090601f01602090048101928261580757600085556157a8565b82601f1061582057805160ff19168380011785556157a8565b828001600101855582156157a8579182015b828111156157a8578251825591602001919060010190615832565b5b808211156157b4576000815560010161584e565b60008083601f840112615873578182fd5b50813567ffffffffffffffff81111561588a578182fd5b6020830191508360208285010111156158a257600080fd5b9250929050565b6000602082840312156158ba578081fd5b81356136d581615f41565b600080604083850312156158d7578081fd5b82356158e281615f41565b915060208301356158f281615f56565b809150509250929050565b60006020828403121561590e578081fd5b81356136d581615f56565b60006020828403121561592a578081fd5b81516136d581615f56565b60008060408385031215615947578182fd5b825161595281615f56565b6020939093015192949293505050565b60008060408385031215615974578182fd5b823561597f81615f41565b915060208301356158f281615f41565b6000806000806000608086880312156159a6578081fd5b85356159b181615f41565b945060208601356159c181615f41565b935060408601359250606086013567ffffffffffffffff8111156159e3578182fd5b6159ef88828901615862565b969995985093965092949392505050565b60008060008060608587031215615a15578384fd5b8435615a2081615f41565b935060208501359250604085013567ffffffffffffffff811115615a42578283fd5b615a4e87828801615862565b95989497509550505050565b600080600080600080600060c0888a031215615a74578182fd5b8735615a7f81615f41565b96506020880135955060408801359450606088013593506080880135925060a088013567ffffffffffffffff811115615ab6578283fd5b615ac28a828b01615862565b989b979a50959850939692959293505050565b600060208284031215615ae6578081fd5b5035919050565b600060208284031215615afe578081fd5b5051919050565b60008060408385031215615b17578182fd5b8235915060208301356158f281615f41565b60008060408385031215615b3b578182fd5b8235915060208301356158f281615f56565b600080600060408486031215615b61578081fd5b83359250602084013567ffffffffffffffff811115615b7e578182fd5b615b8a86828701615862565b9497909650939450505050565b60008060408385031215615ba9578182fd5b50508035926020909101359150565b60008060008060608587031215615bcd578182fd5b8435935060208501359250604085013567ffffffffffffffff811115615a42578283fd5b6000815180845260208085019450808401835b83811015615c295781516001600160a01b031687529582019590820190600101615c04565b509495945050505050565b6001600160a01b03848116825283166020820152606060408201819052600090615c6090830184615bf1565b95945050505050565b600061012060018060a01b038c16835260208b1515818501528a60408501528960608501528860808501528760a08501528660c08501528560e085015281610100850152845180838601528392505b80831015615cd757858301820151858401610140015291810191615cb8565b80831115615ce9578361014082870101525b601f01601f191693909301610140019c9b505050505050505050505050565b60208082526032908201527f70726f706f7365436f6e73756d657257686974656c697374506565723a20706560408201527132b91032bc34b9ba399030b63932b0b23c9760711b606082015260800190565b60208082526018908201527f556e69667479476f7665726e616e63653a204c4f434b45440000000000000000604082015260600190565b6020808252602c908201527f657865637574653a20616374696f6e2069642035203d3e20706565722065786960408201526b39ba399030b63932b0b23c9760a11b606082015260800190565b848152836020820152826040820152608060608201526000615e026080830184615bf1565b9695505050505050565b600060808201868352602086818501528560408501526080606085015281855180845260a0860191508287019350845b81811015615e5857845183529383019391830191600101615e3c565b50909998505050505050505050565b60008219821115615e7a57615e7a615f2b565b500190565b600082615e9a57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615615eb957615eb9615f2b565b500290565b600082821015615ed057615ed0615f2b565b500390565b600181811c90821680615ee957607f821691505b60208210811415615f0a57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615f2457615f24615f2b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146157d657600080fd5b80151581146157d657600080fdfea264697066735822122060e503fe7d2b00567d7f9967e2a3a3a234c976d2a6be3be4971ffa2d4d14c99e64736f6c63430008040033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061041d5760003560e01c806373bd0cc91161022b578063c919c5be11610130578063d7d500af116100b8578063e78a0e4b11610087578063e78a0e4b14610b3f578063ed3c246614610b52578063f79e735414610b5b578063fe0d94c114610b64578063fea47d0614610b7757600080fd5b8063d7d500af14610b07578063dd71387614610b10578063e03eaf6614610b23578063e7743fbe14610b3657600080fd5b8063d0516650116100ff578063d051665014610a95578063d3ecabd514610aa8578063d5d44d8014610abb578063d6165e9b14610adb578063d6eba1d214610afe57600080fd5b8063c919c5be14610a54578063c9d27afe14610a67578063ce30463614610a7a578063cebd96ce14610a8257600080fd5b80639e11c99c116101b3578063abb612ad11610182578063abb612ad146109bd578063ae512e15146109d0578063c29566d5146109f3578063c4a61fa4146109fc578063c6e36a3214610a0f57600080fd5b80639e11c99c146108e5578063a5b168d214610910578063a694fc3a14610964578063a7310b581461097757600080fd5b806383b7b1cf116101fa57806383b7b1cf1461088e5780638d616e44146108ae578063900cf0cf146108c157806391d488ad146108c957806395c950be146108d257600080fd5b806373bd0cc9146107b857806377948c46146108475780637a27dc58146108725780637ffbe0ae1461088557600080fd5b80633ccfd60b116103315780635af05dcf116102b95780636eef0a56116102885780636eef0a561461071c5780636f9334681461072f57806370e592b81461074257806371de587f146107655780637383ace51461076e57600080fd5b80635af05dcf146106e457806360eac3c0146106ed578063638943eb146107005780636a6fde121461071357600080fd5b80634ff0876a116103005780634ff0876a1461066c5780635277b4ae1461067557806357522ab6146106b257806359ac48ba146106d25780635a9133f7146106db57600080fd5b80633ccfd60b146105df5780634651ed3d146105e75780634699c99b146106505780634921d76d1461066357600080fd5b80631703a018116103b4578063270c404711610383578063270c40471461056d5780632a07a0bf146105755780632bf077e3146105825780632c980a14146105a25780632e17de78146105b557600080fd5b80631703a018146105035780631cafb6651461050c5780631e6627741461051f57806323717fe51461054257600080fd5b80630d34b79c116103f05780630d34b79c146104885780630f6258f6146104a05780631397a6e7146104c257806316c38b3c146104f057600080fd5b8063013cf08b146104225780630526ea14146104535780630a7950e1146104685780630c0512e91461047f575b600080fd5b610435610430366004615ad5565b610b97565b60405161044a99989796959493929190615c69565b60405180910390f35b61046661046136600461598f565b610c70565b005b610471601d5481565b60405190815260200161044a565b610471600e5481565b610490610e2b565b604051901515815260200161044a565b6104b36104ae366004615ad5565b610e47565b60405161044a93929190615c34565b6104906104d0366004615962565b601f60209081526000928352604080842090915290825290205460ff1681565b6104666104fe3660046158fd565b610eda565b61047160075481565b61046661051a3660046158c5565b610f4c565b61053261052d3660046158a9565b6110c4565b60405161044a9493929190615ddd565b600054610555906001600160a01b031681565b6040516001600160a01b03909116815260200161044a565b6104716111ad565b6019546104909060ff1681565b6104716105903660046158a9565b60226020526000908152604090205481565b6104666105b0366004615bb8565b61125c565b6105c86105c3366004615ad5565b6112e9565b60408051921515835260208301919091520161044a565b61046661170f565b6106266105f5366004615ad5565b601b6020526000908152604090208054600182015460028301546003909301546001600160a01b0390921692909184565b604080516001600160a01b039095168552602085019390935291830152606082015260800161044a565b61046661065e366004615bb8565b61188d565b610471600b5481565b61047160025481565b610490610683366004615b05565b6000828152600f602090815260408083206001600160a01b038516845260080190915290205460ff1692915050565b6104716106c0366004615ad5565b60136020526000908152604090205481565b61047160215481565b61047160055481565b610471600c5481565b6104666106fb366004615bb8565b6118fd565b61046661070e366004615ad5565b61196d565b61047160045481565b61046661072a366004615bb8565b611bd1565b61046661073d366004615bb8565b611c41565b6104906107503660046158a9565b601c6020526000908152604090205460ff1681565b61047160205481565b61079d61077c366004615ad5565b60106020526000908152604090208054600182015460029092015490919083565b6040805193845260208401929092529082015260600161044a565b6108096107c63660046158a9565b600d602052600090815260409020805460018201546002830154600384015460048501546005909501546001600160a01b03948516959385169490921692909186565b604080516001600160a01b039788168152958716602087015293909516928401929092526060830152608082015260a081019190915260c00161044a565b610471610855366004615962565b601660209081526000928352604080842090915290825290205481565b610466610880366004615bb8565b611cb1565b610471600a5481565b61047161089c3660046158a9565b601e6020526000908152604090205481565b6104666108bc366004615b4d565b611d21565b610471611d9a565b61047160085481565b6104666108e0366004615a5a565b611dc2565b6104716108f3366004615962565b601560209081526000928352604080842090915290825290205481565b61094461091e366004615ad5565b601160205260009081526040902080546001909101546001600160a01b03918216911682565b604080516001600160a01b0393841681529290911660208301520161044a565b6105c8610972366004615ad5565b612026565b61098a6109853660046158a9565b612443565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a00161044a565b6104666109cb366004615a5a565b6124e6565b6109e36109de366004615ad5565b612688565b60405161044a9493929190615e0c565b61047160145481565b610466610a0a366004615a00565b61270e565b610a22610a1d366004615b97565b6128b9565b604080516001600160a01b0390961686529315156020860152928401919091526060830152608082015260a00161044a565b610466610a62366004615bb8565b612915565b610466610a75366004615b29565b612985565b610471612d4d565b610471610a90366004615962565b612dde565b610490610aa33660046158a9565b6133df565b610471610ab63660046158a9565b613576565b610471610ac93660046158a9565b60246020526000908152604090205481565b610490610ae93660046158a9565b60236020526000908152604090205460ff1681565b610471601a5481565b61047160185481565b600154610555906001600160a01b031681565b610466610b3136600461598f565b6136dc565b61047160095481565b610466610b4d366004615bb8565b613972565b61047160065481565b61047160035481565b610466610b72366004615ad5565b6139e2565b610471610b853660046158a9565b60176020526000908152604090205481565b600f60205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007880180546001600160a01b03891699600160a01b90990460ff16989190610bed90615ed5565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1990615ed5565b8015610c665780601f10610c3b57610100808354040283529160200191610c66565b820191906000526020600020905b815481529060010190602001808311610c4957829003601f168201915b5050505050905089565b602554600114610c9b5760405162461bcd60e51b8152600401610c9290615d5a565b60405180910390fd5b60006025556001600160a01b038416610d1c5760405162461bcd60e51b815260206004820152603f60248201527f70726f706f7365436f6e73756d657257686974656c697374506565723a20706560448201527f6572206d6179206e6f7420626520746865206e756c6c20616464726573732e006064820152608401610c92565b6001600160a01b038086166000908152601f602090815260408083209388168352929052205460ff1615610d625760405162461bcd60e51b8152600401610c9290615d08565b6001600160a01b0384166000908152601c602052604090205460ff1615610d9b5760405162461bcd60e51b8152600401610c9290615d08565b6000610de1338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060059250615006915050565b600090815260116020526040902080546001600160a01b039687166001600160a01b0319918216178255600191820180549890971697169690961790945550505060259190915550565b60195460009060ff1680610e425750600954601454105b905090565b6000818152601160209081526040808320805460018201546002909201805484518187028101870190955280855286956060956001600160a01b039485169590941693918391830182828015610ec657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ea8575b505050505090509250925092509193909250565b3360009081526023602052604090205460ff16610f395760405162461bcd60e51b815260206004820152601c60248201527f7365745061757365643a206e6f7420616e206578656375746976652e000000006044820152606401610c92565b6019805460ff1916911515919091179055565b3360009081526023602052604090205460ff16610fab5760405162461bcd60e51b815260206004820152601f60248201527f6164644578656375746976653a206e6f7420616e206578656375746976652e006044820152606401610c92565b801561102b576001600160a01b03821660009081526023602052604090205460ff16156110265760405162461bcd60e51b815260206004820152602360248201527f6164644578656375746976653a20616c726561647920616e20657865637574696044820152623b329760e91b6064820152608401610c92565b611099565b336001600160a01b03831614156110995760405162461bcd60e51b815260206004820152602c60248201527f72656d6f76654578656375746976653a20796f752063616e6e6f742072656d6f60448201526b3b32903cb7bab939b2b6331760a11b6064820152608401610c92565b6001600160a01b03919091166000908152602360205260409020805460ff1916911515919091179055565b6001600160a01b038082166000908152601e60209081526040808320548352601b8252808320815160a081018352815490951685526001810154858401526002810154858301526003810154606086810191909152600482018054845181870281018701909552808552959687968796939587959294929360808601939192909183018282801561117e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611160575b505050505081525050905080602001518160400151826060015183608001519450945094509450509193509193565b60006025546001146111d15760405162461bcd60e51b8152600401610c9290615d5a565b60006025819055338152600d60205260409020600101546001600160a01b03166112495760405162461bcd60e51b8152602060048201526024808201527f64656c6c6f63617465506565723a206e6f7468696e6720746f2064656c6c6f6360448201526330ba329760e11b6064820152608401610c92565b6112523361545a565b9050600160255590565b60255460011461127e5760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600e9250615006915050565b600090815260106020526040902094909455505060016025555050565b60008060255460011461130e5760405162461bcd60e51b8152600401610c9290615d5a565b60006025819055338152600d6020526040902060050154158015906113455750336000908152600d60205260409020600501548311155b61139d5760405162461bcd60e51b8152602060048201526024808201527f756e7374616b65496e7465726e616c3a20696e73756666696369656e742066756044820152633732399760e11b6064820152608401610c92565b600b546001906000906113b09042615e67565b336000908152600d60209081526040808320600401939093556024905290812080548792906113e0908490615e67565b9091555050336000908152600d6020526040902060050154611403908690615ebe565b61145b576114103361545a565b336000908152600d6020526040812060050180549293508792909190611437908490615ebe565b9250508190555084601460008282546114509190615ebe565b909155506116bc9050565b336000908152600d6020526040902060050154611479908690615ebe565b158015906114a15750336000908152600d60205260409020600101546001600160a01b031615155b80156114d45750336000908152600d60209081526040808320600101546001600160a01b03168352601e90915290205415155b1561167b57336000908152600d602052604081206005018054918791906114fb8385615ebe565b9250508190555085601460008282546115149190615ebe565b9091555050336000908152600d6020908152604080832060018101546001600160a01b0390811685526015845282852060029092015416845290915281208054918891906115628385615ebe565b9091555050336000908152600d60209081526040808320600101546001600160a01b0316835260179091528120805489929061159f908490615ebe565b9250508190555086601860008282546115b89190615ebe565b9091555050336000818152600d6020526040908190204260038201556001810154600290910154915163038cf3c360e51b8152600481019390935260248301859052604483018490526001600160a01b039182166064840152169063719e7860906084016040805180830381600087803b15801561163557600080fd5b505af1925050508015611665575060408051601f3d908101601f1916820190925261166291810190615935565b60015b61166e57611674565b90945092505b50506116bc565b336000908152600d60205260408120600501805487929061169d908490615ebe565b9250508190555084601460008282546116b69190615ebe565b90915550505b60408051868152831515602082015290810182905233907fb870217905665894c8434c46e122702ec5e8a7f6c5f6751b58ee4d4668c7ad859060600160405180910390a260016025559094909350915050565b6025546001146117315760405162461bcd60e51b8152600401610c9290615d5a565b600060255560195460ff16806117665750600c54336000908152600d60205260409020600401546117629190615e67565b4210155b6117b25760405162461bcd60e51b815260206004820152601b60248201527f77697468647261773a206e6966207374696c6c206c6f636b65642e00000000006044820152606401610c92565b3360008181526024602081905260408083208054908490559254905163a9059cbb60e01b8152600481019490945290830182905290916001600160a01b039091169063a9059cbb90604401602060405180830381600087803b15801561181757600080fd5b505af115801561182b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184f9190615919565b5060405181815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d59060200160405180910390a2506001602555565b6025546001146118af5760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060089250615006915050565b60255460011461191f5760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060029250615006915050565b611975610e2b565b156119c25760405162461bcd60e51b815260206004820152601860248201527f6d696e74556e743a2070617573696e672c20736f7272792e00000000000000006044820152606401610c92565b336000908152601e6020526040902054611a1e5760405162461bcd60e51b815260206004820152601760248201527f6d696e74556e743a206163636573732064656e6965642e0000000000000000006044820152606401610c92565b600a546014541015611a905760405162461bcd60e51b815260206004820152603560248201527f6d696e74556e743a206e6f7420656e6f756768204e4946207374616b6564206960448201527437103a34329033b7bb32b93730b731b2903cb2ba1760591b6064820152608401610c92565b6000611a9b33613576565b90508015801590611aac5750818110155b611af85760405162461bcd60e51b815260206004820152601960248201527f6d696e74556e743a206e6f7468696e6720746f206d696e742e000000000000006044820152606401610c92565b336000908152601e60209081526040808320548352601b90915281206003018054849290611b27908490615ebe565b925050819055508160216000828254611b409190615e67565b90915550503360009081526022602052604081208054849290611b64908490615e67565b90915550506001546040516340c10f1960e01b8152336004820152602481018490526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015611bb557600080fd5b505af1158015611bc9573d6000803e3d6000fd5b505050505050565b602554600114611bf35760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600a9250615006915050565b602554600114611c635760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600d9250615006915050565b602554600114611cd35760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600b9250615006915050565b602554600114611d435760405162461bcd60e51b8152600401610c9290615d5a565b6000602581905550611d8f338484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060099250615006915050565b505060016025555050565b6000600254601a5442611dad9190615ebe565b611db79190615e7f565b610e42906001615e67565b602554600114611de45760405162461bcd60e51b8152600401610c9290615d5a565b60006025556001600160a01b038716611e655760405162461bcd60e51b815260206004820152603960248201527f70726f706f7365416464436f6e73756d65723a20636f6e73756d6572206d617960448201527f206e6f7420626520746865206e756c6c20616464726573732e000000000000006064820152608401610c92565b6001600160a01b0387166000908152601e602052604090205415611ee05760405162461bcd60e51b815260206004820152602c60248201527f70726f706f7365416464436f6e73756d65723a20636f6e73756d65722065786960448201526b39ba399030b63932b0b23c9760a11b6064820152608401610c92565b84611f2d5760405162461bcd60e51b815260206004820181905260248201527f70726f706f7365416464436f6e73756d65723a20696e76616c696420726174656044820152606401610c92565b85611f8a5760405162461bcd60e51b815260206004820152602760248201527f70726f706f7365416464436f6e73756d65723a20696e76616c6964206772616e6044820152663a1039b4bd329760c91b6064820152608401610c92565b6000611fd0338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060039250615006915050565b600090815260116020908152604080832080546001600160a01b0319166001600160a01b039c909c169b909b17909a55601090529790972095865550505060018381019290925560029092019190915560255550565b60008060255460011461204b5760405162461bcd60e51b8152600401610c9290615d5a565b600060255560195460ff161561209c5760405162461bcd60e51b815260206004820152601660248201527539ba30b5b29d103830bab9b4b733961039b7b9393c9760511b6044820152606401610c92565b600083116120ec5760405162461bcd60e51b815260206004820152601e60248201527f7374616b653a20696e76616c6964207374616b696e6720616d6f756e742e00006044820152606401610c92565b336000908152600d602052604081206005018054600192918690836121118385615e67565b9091555050600b546121239042615e67565b336000908152600d60205260408120600401919091556014805488929061214b908490615e67565b9091555050336000908152600d60205260409020600101546001600160a01b0316158015906121a15750336000908152600d60209081526040808320600101546001600160a01b03168352601e90915290205415155b1561236457336000908152600d6020908152604080832060018101546001600160a01b0390811685526015845282852060029092015416845290915281208054918891906121ef8385615e67565b9091555050336000908152600d60209081526040808320600101546001600160a01b0316835260179091528120805489929061222c908490615e67565b9250508190555086601860008282546122459190615e67565b9091555050336000818152600d6020526040908190204260038201556001810154600290910154915163038cf3c360e51b8152600481019390935260248301859052604483018490526001600160a01b039182166064840152169063719e7860906084016040805180830381600087803b1580156122c257600080fd5b505af19250505080156122f2575060408051601f3d908101601f191682019092526122ef91810190615935565b60015b6122fb57612301565b90945092505b836123625760405162461bcd60e51b815260206004820152602b60248201527f7374616b653a20616c6c6f636174696f6e20757064617465206861732062656560448201526a37103932b532b1ba32b21760a91b6064820152608401610c92565b505b6000546040516323b872dd60e01b8152336004820152306024820152604481018890526001600160a01b03909116906323b872dd90606401602060405180830381600087803b1580156123b657600080fd5b505af11580156123ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ee9190615919565b5060408051878152841515602082015290810183905233907fb090af6b9902ba8a7bc46486cd082be61763b3decc7be5ab48dc26422860230c9060600160405180910390a25060016025559094909350915050565b6001600160a01b038082166000818152600d6020818152604080842060018101548716808652601f8452828620600283015490981680875297845291852054958552929091526003909101549193849384938493849360ff909316929091836124b0575060009150819050805b6001600160a01b03999099166000908152600d602052604090206004810154600590910154929a91999850965090945092505050565b6025546001146125085760405162461bcd60e51b8152600401610c9290615d5a565b600060258190556001600160a01b0388168152601e60205260409020546125865760405162461bcd60e51b815260206004820152602c60248201527f757064617465436f6e73756d65724772616e743a20636f6e73756d657220646f60448201526b32b9b713ba1032bc34b9ba1760a11b6064820152608401610c92565b846125dd5760405162461bcd60e51b815260206004820152602160248201527f757064617465436f6e73756d65724772616e743a20696e76616c6964207261746044820152606560f81b6064820152608401610c92565b856126425760405162461bcd60e51b815260206004820152602f60248201527f70726f706f7365557064617465436f6e73756d65724772616e743a20696e766160448201526e3634b21033b930b73a1039b4bd329760891b6064820152608401610c92565b6000611fd0338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060079250615006915050565b60008181526010602090815260408083208054600182015460028301546003909301805485518188028101880190965280865287968796606096939290918391908301828280156126f857602002820191906000526020600020905b8154815260200190600101908083116126e4575b5050505050905093509350935093509193509193565b6025546001146127305760405162461bcd60e51b8152600401610c9290615d5a565b60006025556001600160a01b0384166127b15760405162461bcd60e51b815260206004820152603c60248201527f70726f706f736552656d6f7665436f6e73756d65723a20636f6e73756d65722060448201527f6d6179206e6f7420626520746865206e756c6c20616464726573732e000000006064820152608401610c92565b6001600160a01b038085166000818152601e60209081526040808320548352601b9091529020549091161461283b5760405162461bcd60e51b815260206004820152602a60248201527f70726f706f736552656d6f7665436f6e73756d65723a20636f6e73756d6572206044820152693737ba103337bab7321760b11b6064820152608401610c92565b6000612881338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060049250615006915050565b600090815260116020526040902080546001600160a01b0319166001600160a01b039690961695909517909455505060016025555050565b601260205281600052604060002081815481106128d557600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0383169550600160a01b90920460ff169350919085565b6025546001146129375760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250615006915050565b6025546001146129a75760405162461bcd60e51b8152600401610c9290615d5a565b60006025556129b4610e2b565b156129f95760405162461bcd60e51b81526020600482015260156024820152743b37ba329d103830bab9b4b733961039b7b9393c9760591b6044820152606401610c92565b600854336000908152600d60205260409020600501541015612a545760405162461bcd60e51b81526020600482015260146024820152733b37ba329d1034b73b30b634b21039ba30b5b29760611b6044820152606401610c92565b6000828152600f60205260409020546001600160a01b031615801590612a8b57506000828152600f60205260409020600401544211155b612ae25760405162461bcd60e51b815260206004820152602260248201527f766f74653a20696e76616c6964206f7220657870697265642070726f706f7361604482015261361760f11b6064820152608401610c92565b6000828152600f6020908152604080832033845260080190915290205460ff1615612b4f5760405162461bcd60e51b815260206004820152601860248201527f766f74653a20796f7520766f74656420616c72656164792e00000000000000006044820152606401610c92565b6001600f60008481526020019081526020016000206001016000828254612b769190615e67565b90915550508015612bc057336000908152600d6020908152604080832060050154858452600f9092528220600201805491929091612bb5908490615e67565b90915550612bfa9050565b336000908152600d6020908152604080832060050154858452600f9092528220600301805491929091612bf4908490615e67565b90915550505b6000828152600f602090815260408083203380855260089091018352818420805460ff1916600190811790915586855260128452828520835160a081018552838152871515818701908152848852600d8088528689206005018054848901908152606085018d815242608087019081528754808a018955978d528b8d2096516004909802909601805495511515600160a01b026001600160a81b03199096166001600160a01b0398909816979097179490941786555195850195909555905160028401559051600390920191909155878652601385528386205495839052909352915490518592917fd58cd2f260be6feac853baa17bd79162b96a96fde5d48d8a1e456fdf09f06d5391612d18918715158252602082015260400190565b60405180910390a46000828152601360205260408120805460019290612d3f908490615e67565b909155505060016025555050565b60008080612d59611d9a565b60035490915060005b82811015612dc857612d748285615e67565b9350670de0b6b3a76400006064612d8b8483615e9f565b612d959190615e7f565b612da0906005615e9f565b612daa9190615e7f565b612db49083615ebe565b915080612dc081615f10565b915050612d62565b50602054612dd69084615ebe565b935050505090565b6000602554600114612e025760405162461bcd60e51b8152600401610c9290615d5a565b6000602555612e0f610e2b565b15612e5c5760405162461bcd60e51b815260206004820152601960248201527f616c6c6f636174653a2070617573696e672c20736f7272792e000000000000006044820152606401610c92565b336000908152600d6020526040902060050154612ebb5760405162461bcd60e51b815260206004820152601f60248201527f616c6c6f636174653a20796f75206d757374207374616b652066697273742e006044820152606401610c92565b6001600160a01b03821615801590612edb57506001600160a01b03831615155b612f3c5760405162461bcd60e51b815260206004820152602c60248201527f616c6c6f636174653a207065657220616e6420636f6e73756d6572206d75737460448201526b3713ba10313290373ab6361760a11b6064820152608401610c92565b6001600160a01b0383166000908152601e6020526040902054612fab5760405162461bcd60e51b815260206004820152602160248201527f616c6c6f636174653a20636f6e73756d657220646f65736e27742065786973746044820152601760f91b6064820152608401610c92565b6001600160a01b038084166000908152601f602090815260408083209386168352929052205460ff166130205760405162461bcd60e51b815260206004820152601d60248201527f616c6c6f636174653a207065657220646f65736e27742065786973742e0000006044820152606401610c92565b336000908152600d60205260409020600201546001600160a01b03838116911614156130a95760405162461bcd60e51b815260206004820152603260248201527f616c6c6f636174653a20796f752061726520616c6c6f636174696e6720746f206044820152713a3434b9903832b2b91030b63932b0b23c9760711b6064820152608401610c92565b6130b2336133df565b156131365760405162461bcd60e51b815260206004820152604860248201527f616c6c6f636174653a2063616e6e6f742064656c6c6f636174652c20616c6c6f60448201527f636174696f6e207374696c6c2066726f7a656e2062792063757272656e74206360648201526737b739bab6b2b91760c11b608482015260a401610c92565b60006131413361545a565b336000908152600d602090815260408083206001810180546001600160a01b03199081166001600160a01b038c8116918217909355600284018054909216928b16928317909155426003840155855260158452828520908552909252822080546005909201549394509092916131b78385615e67565b9091555050336000908152600d60209081526040808320600501546001600160a01b0389168452601790925282208054919290916131f6908490615e67565b9091555050336000908152600d60205260408120600501546018805491929091613221908490615e67565b9091555050336000908152600d602090815260408083206001818101546001600160a01b0390811686526016855283862060029093015416855292528220805491929091613270908490615e67565b9091555050604051632531fdad60e01b8152336004820152602481018290526001600160a01b03858116604483015260009190871690632531fdad90606401602060405180830381600087803b1580156132c957600080fd5b505af19250505080156132f9575060408051601f3d908101601f191682019092526132f691810190615919565b60015b61330257613305565b90505b806133845760405162461bcd60e51b815260206004820152604360248201527f616c6c6f636174653a20616c6c6f636174696f6e2064656e696564206279206360448201527f6f6e73756d65722f70656572206f7220636f6e73756d6572206973206661756c6064820152623a3c9760e91b608482015260a401610c92565b604080516001600160a01b0388811682528716602082015290810184905233907f7519d597df1b9f51919758c22c20c3efcb772fb7c5ce2b2ac37729890aaf50f49060600160405180910390a2505060016025559392505050565b6001600160a01b038082166000908152600d60209081526040808320600181015485168452601f835281842060029091015490941683529290529081205460ff16801561356d576001600160a01b038381166000908152600d602052604080822060018101546002909101549151635c5e552b60e01b8152918416600483015291929190911690635c5e552b9060240160206040518083038186803b15801561348757600080fd5b505afa9250505080156134b7575060408051601f3d908101601f191682019092526134b491810190615919565b60015b6134c0576134c3565b90505b806134d2575060009392505050565b6001600160a01b038481166000818152600d602052604090819020600101549051630d05166560e41b815260048101929092529091169063d05166509060240160206040518083038186803b15801561352a57600080fd5b505afa92505050801561355a575060408051601f3d908101601f1916820190925261355791810190615919565b60015b6135635761356b565b949350505050565b505b50600092915050565b6001600160a01b0381166000908152601e602052604081205461359b57506000919050565b6001600160a01b038083166000908152601e60209081526040808320548352601b8252808320815160a081018352815490951685526001810154858401526002810154858301526003810154606086015260048101805483518186028101860190945280845294959491936080860193929083018282801561364657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613628575b50505050508152505090508060400151600014156136675750600092915050565b6000670de0b6b3a76400008260600151836040015184602001514261368c9190615ebe565b61369e90670de0b6b3a7640000615e9f565b6136a89190615e7f565b6136b29190615e9f565b6136bc9190615e7f565b905081606001518111156136d557506060015192915050565b9392505050565b6025546001146136fe5760405162461bcd60e51b8152600401610c9290615d5a565b60006025556001600160a01b0385166137955760405162461bcd60e51b815260206004820152604d60248201527f70726f706f7365436f6e73756d657252656d6f76655065657246726f6d57686960448201527f74656c6973743a20636f6e73756d6572206d6179206e6f74206265207468652060648201526c373ab6361030b2323932b9b99760991b608482015260a401610c92565b6001600160a01b038086166000818152601e60209081526040808320548352601b909152902054909116146138325760405162461bcd60e51b815260206004820152603b60248201527f70726f706f7365436f6e73756d657252656d6f76655065657246726f6d57686960448201527f74656c6973743a20636f6e73756d6572206e6f7420666f756e642e00000000006064820152608401610c92565b6001600160a01b038086166000908152601f602090815260408083209388168352929052205460ff166138cd5760405162461bcd60e51b815260206004820152603760248201527f70726f706f7365436f6e73756d657252656d6f76655065657246726f6d57686960448201527f74656c6973743a2070656572206e6f7420666f756e642e0000000000000000006064820152608401610c92565b6000613913338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060069250615006915050565b6000908152601160209081526040822080546001600160a01b039889166001600160a01b031991821617825560029091018054600181810183559185529290932090910180549890971697169690961790945550505060259190915550565b6025546001146139945760405162461bcd60e51b8152600401610c9290615d5a565b600060258190555060006112cc338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600c9250615006915050565b602554600114613a045760405162461bcd60e51b8152600401610c9290615d5a565b6000602555613a11610e2b565b15613a5e5760405162461bcd60e51b815260206004820152601860248201527f657865637574653a2070617573696e672c20736f7272792e00000000000000006044820152606401610c92565b3360009081526023602052604090205460ff16613abd5760405162461bcd60e51b815260206004820152601a60248201527f657865637574653a206e6f7420616e206578656375746976652e0000000000006044820152606401610c92565b6000818152600f60205260409020546001600160a01b0316613b215760405162461bcd60e51b815260206004820152601a60248201527f657865637574653a20696e76616c69642070726f706f73616c2e0000000000006044820152606401610c92565b6000818152600f6020526040902054600160a01b900460ff1615613b9c5760405162461bcd60e51b815260206004820152602c60248201527f657865637574653a2070726f706f73616c20686173206265656e20657865637560448201526b3a32b21030b63932b0b23c9760a11b6064820152608401610c92565b6007546000828152600f602052604090206003810154600290910154613bc29190615e67565b1015613c105760405162461bcd60e51b815260206004820152601c60248201527f657865637574653a2071756f72756d206e6f7420726561636865642e000000006044820152606401610c92565b6000818152600f60205260409020600381015460029091015411613c765760405162461bcd60e51b815260206004820152601c60248201527f657865637574653a206e6f7420656e6f75676820737570706f72742e000000006044820152606401610c92565b6000818152600f6020526040902060019081015411613cd75760405162461bcd60e51b815260206004820152601f60248201527f657865637574653a206e656564206174206c65617374203220766f7465732e006044820152606401610c92565b600c546000828152600f6020526040902060040154613cf69190615e67565b4211613d5a5760405162461bcd60e51b815260206004820152602d60248201527f657865637574653a20766f74696e6720616e642067726163652074696d65206e60448201526c37ba103cb2ba1032b73232b21760991b6064820152608401610c92565b600654600c546000838152600f6020526040902060040154613d7c9190615e67565b613d869190615e67565b4210613ddf5760405162461bcd60e51b815260206004820152602260248201527f657865637574653a20657865637574696f6e2077696e646f7720657870697265604482015261321760f11b6064820152608401610c92565b6000818152600f60205260409020805460ff60a01b1916600160a01b1781556006015460011415613e2157600081815260106020526040902054600955614fd1565b6000818152600f602052604090206006015460021415613e5257600081815260106020526040902054600855614fd1565b6000818152600f602052604090206006015460081415613e8357600081815260106020526040902054600a55614fd1565b6000818152600f6020526040902060060154600a1415613eb457600081815260106020526040902054600455614fd1565b6000818152600f6020526040902060060154600b1415613ee557600081815260106020526040902054600555614fd1565b6000818152600f6020526040902060060154600c1415613f1657600081815260106020526040902054600655614fd1565b6000818152600f6020526040902060060154600d1415613f4757600081815260106020526040902054600755614fd1565b6000818152600f6020526040902060060154600e1415613f7857600081815260106020526040902054600b55614fd1565b6000818152600f602052604090206006015460031415614208576000818152601160209081526040808320546001600160a01b03168352601e9091529020541561401d5760405162461bcd60e51b815260206004820152603060248201527f657865637574653a20616374696f6e2069642033203d3e20636f6e73756d657260448201526f1032bc34b9ba399030b63932b0b23c9760811b6064820152608401610c92565b600081815260106020526040902054614034612d4d565b101561409b5760405162461bcd60e51b815260206004820152603060248201527f6578657574653a20616374696f6e2069642033203d3e206e6f7420656e6f756760448201526f341030bb30b4b630b13632902aa72a1760811b6064820152608401610c92565b6000818152601060205260409020600101546141055760405162461bcd60e51b8152602060048201526024808201527f657865637574653a20616374696f6e2069642033203d3e20696e76616c6964206044820152637261746560e01b6064820152608401610c92565b600081815260106020526040902060020154421115614134576000818152601060205260409020426002909101555b60008181526010602090815260408220548154909290614155908490615e67565b9091555050600081815260116020908152604080832054601d80548552601b80855283862080546001600160a01b0319166001600160a01b0394851617905586865260108552838620805483548852918652848720600301919091556001818101548354885285882060029081019190915590910154825487528487208201558154808752848720549093168652601e909452918420819055919290916141fd908490615e67565b90915550614fd19050565b6000818152600f60205260409020600601546004141561465d576000818152601160209081526040808320546001600160a01b039081168452601e8352818420548452601b8352818420825160a081018452815490921682526001810154828501526002810154828401526003810154606083015260048101805484518187028101870190955280855292949193608086019390928301828280156142d657602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116142b8575b5050509190925250508151919250506001600160a01b031661434e5760405162461bcd60e51b815260206004820152602b60248201527f657865637574653a20616374696f6e2069642034203d3e20636f6e73756d657260448201526a103737ba103337bab7321760a91b6064820152608401610c92565b60005b81608001515181101561444c5781516001600160a01b03166000908152601f60205260408120608084015180518391908590811061439f57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055506000601c60008460800151848151811061440857634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790558061444481615f10565b915050614351565b508060600151602060008282546144639190615ebe565b909155505080516001600160a01b039081166000908152601e6020818152604080842054601d80548652601b808552838720548816875285855283872092909255548552808352818520875187168652938352818520548552909152909120815481546001600160a01b03191693169290921782556001818101549083015560028082015490830155600380820154908301556004808201805492939261450d9284019190615768565b505081516001600160a01b03166000908152601e60209081526040808320839055601d80548452601b90925280832080546001600160a01b03191690558154835280832060030183905581548352808320600201839055815483528083206001018390559054825281206145859250600401906157b8565b6001601d60008282546145989190615ebe565b90915550600090505b8160800151518110156146565781600001516001600160a01b0316635b00ce54836080015183815181106145e557634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b815260040161461891906001600160a01b0391909116815260200190565b600060405180830381600087803b15801561463257600080fd5b505af1925050508015614643575060015b508061464e81615f10565b9150506145a1565b5050614fd1565b6000818152600f6020526040902060060154600514156148bd576000818152601160209081526040808320600101546001600160a01b039081168452601e8352818420548452601b909252909120541661470d5760405162461bcd60e51b815260206004820152602b60248201527f657865637574653a20616374696f6e2069642035203d3e20636f6e73756d657260448201526a103737ba103337bab7321760a91b6064820152608401610c92565b600081815260116020908152604080832060018101546001600160a01b039081168552601f8452828520915416845290915290205460ff16156147625760405162461bcd60e51b8152600401610c9290615d91565b6000818152601160209081526040808320546001600160a01b03168352601c90915290205460ff16156147a75760405162461bcd60e51b8152600401610c9290615d91565b6000818152601160208181526040808420600180820180546001600160a01b039081168852601e808752858920548952601b808852868a208654600491820180548089018255908d528a8d200180546001600160a01b031916918616919091179055845484168b52601f8952878b20875485168c528952878b20805460ff199081168817909155875485168c52601c8a52888c20805490911690961790955592548216895286528488205488529085528387205496889052949093525490516376e30c0360e11b81529083169181019190915291169063edc6180690602401600060405180830381600087803b1580156148a057600080fd5b505af11580156148b4573d6000803e3d6000fd5b50505050614fd1565b6000818152600f602052604090206006908101541415614d28576000601b6000601e60006011600087815260200190815260200160002060020160008154811061491757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b039081168452838201949094526040928301822054855284810195909552928101909220825160a081018452815490921682526001810154828501526002810154828401526003810154606083015260048101805484518187028101870190955280855292949193608086019390928301828280156149d457602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116149b6575b5050509190925250508151919250506001600160a01b0316614a4c5760405162461bcd60e51b815260206004820152602b60248201527f657865637574653a20616374696f6e2069642036203d3e20636f6e73756d657260448201526a103737ba103337bab7321760a91b6064820152608401610c92565b80516001600160a01b039081166000908152601f6020908152604080832086845260118352818420549094168352929052205460ff16614ae25760405162461bcd60e51b815260206004820152602b60248201527f657865637574653a20616374696f6e2069642036203d3e207065657220646f6560448201526a39b713ba1032bc34b9ba1760a91b6064820152608401610c92565b80516001600160a01b039081166000908152601f6020908152604080832086845260118352818420805486168552908352818420805460ff1990811690915590549094168352601c909152812080549092169091555b8160800151518110156146565781608001518181518110614b6957634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600085815260119092526040909120546001600160a01b0390811691161415614d165760808201518051614bab90600190615ebe565b81518110614bc957634e487b7160e01b600052603260045260246000fd5b60209081029190910181015183516001600160a01b03166000908152601e83526040808220548252601b90935291909120600401805483908110614c1d57634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905584519092168152601e82526040808220548252601b90925220600401805480614c7e57634e487b7160e01b600052603160045260246000fd5b60008281526020808220600019908401810180546001600160a01b0319169055909201909255835185835260119091526040918290205491516316c0339560e21b81526001600160a01b039283166004820152911690635b00ce5490602401600060405180830381600087803b158015614cf757600080fd5b505af1925050508015614d08575060015b614d1157614656565b614656565b80614d2081615f10565b915050614b38565b6000818152600f602052604090206006015460071415614fd1576000818152601160209081526040808320546001600160a01b03168352601e909152902054614dcb5760405162461bcd60e51b815260206004820152602f60248201527f657865637574653a20616374696f6e2069642037203d3e20636f6e73756d657260448201526e103237b2b9b713ba1032bc34b9ba1760891b6064820152608401610c92565b6000818152601160209081526040808320546001600160a01b03168352601e8252808320548352601b82528220600301548154909290614e0c908490615ebe565b9091555050600081815260106020526040902054614e28612d4d565b1015614e8f5760405162461bcd60e51b815260206004820152603060248201527f6578657574653a20616374696f6e2069642037203d3e206e6f7420656e6f756760448201526f341030bb30b4b630b13632902aa72a1760811b6064820152608401610c92565b60008181526010602090815260408220548154909290614eb0908490615e67565b9091555050600081815260106020526040902060010154614f1f5760405162461bcd60e51b8152602060048201526024808201527f657865637574653a20616374696f6e2069642037203d3e20696e76616c6964206044820152637261746560e01b6064820152608401610c92565b600081815260106020526040902060020154421115614f4e576000818152601060205260409020426002909101555b600081815260106020908152604080832080546011845282852080546001600160a01b039081168752601e808752858820548852601b80885286892060030194909455600180860154845484168a52828952878a20548a52858952878a206002908101919091559095015492549091168752855283862054865293529220909101555b604051819033907f6f6c6d78a4851d4c222c8404fc92372ee84b7b81054305ae8ea3c83c2dabd42e90600090a3506001602555565b6000615010610e2b565b1561505d5760405162461bcd60e51b815260206004820152601c60248201527f6e657750726f706f73616c3a2070617573696e672c20736f7272792e000000006044820152606401610c92565b6004548411156150af5760405162461bcd60e51b815260206004820152601f60248201527f6e657750726f706f73616c3a206475726174696f6e20746f6f206c6f6e672e006044820152606401610c92565b60055484101561510f5760405162461bcd60e51b815260206004820152602560248201527f6e657750726f706f73616c3a206d696e2e206475726174696f6e20746f6f20736044820152643437b93a1760d91b6064820152608401610c92565b6008546001600160a01b0386166000908152600d6020526040902060050154101561517c5760405162461bcd60e51b815260206004820152601b60248201527f6e657750726f706f73616c3a20696e76616c6964207374616b652e00000000006044820152606401610c92565b600e80546000908152600f6020908152604080832080546001600160a01b0319166001600160a01b038b161790559254825291902084516151c5926007909201918601906157d9565b506001600f6000600e54815260200190815260200160002060010160008282546151ef9190615e67565b90915550506001600160a01b0385166000908152600d6020908152604080832060050154600e548452600f9092528220600201805491929091615233908490615e67565b9091555050600e546000818152600f6020908152604080832060058101949094556001600160a01b03891683526008909301905220805460ff1916600117905561527d8442615e67565b600e80546000908152600f6020908152604080832060049081019590955583548352808320600601879055925480835291839020909301548251908152928301859052916001600160a01b038816917ff97c8990c1edf2d023da24ff6e6f77566a9513d2e0a2184483479f60b192ab18910160405180910390a3600e80546000818152601260209081526040808320815160a0810183526001600160a01b03808d168083526001838701818152918852600d87528588206005015484870190815260608501998a52426080860190815286548084018855968a52888a2095516004909702909501805493511515600160a01b026001600160a81b031990941696909416959095179190911782559251818401559551600287015551600390950194909455935482526013905291909120546153b791615e67565b600e546001600160a01b0387166000818152600d602090815260409182902060050154825160018152918201527fd58cd2f260be6feac853baa17bd79162b96a96fde5d48d8a1e456fdf09f06d53910160405180910390a4600e546000818152601360205260408120805460019290615431908490615e67565b925050819055506001600e600082825461544b9190615e67565b90915550909695505050505050565b6001600160a01b038181166000908152600d602052604081206001015490911661548657506000919050565b61548f826133df565b158061549d575060195460ff165b6155215760405162461bcd60e51b815260206004820152604960248201527f64656c6c6f63617465496e7465726e616c3a2063616e6e6f742064656c6c6f6360448201527f6174652c20616c6c6f636174696f6e207374696c6c2066726f7a656e2062792060648201526831b7b739bab6b2b91760b91b608482015260a401610c92565b6001600160a01b038281166000908152600d602090815260408083206001810154600282015490861680865260158552838620919096168086529352908320805460059092015492939290836155778385615ebe565b90915550506001600160a01b038087166000908152600d602090815260408083206005015493881683526017909152812080549091906155b8908490615ebe565b90915550506001600160a01b0386166000908152600d602052604081206005015460188054919290916155ec908490615ebe565b90915550506001600160a01b0380851660009081526016602090815260408083209387168352929052908120805460019290615629908490615ebe565b90915550506001600160a01b038087166000908152600d602090815260408083206001810180546001600160a01b03199081169091556002820180549091169055426003909101559287168252601e905220541561570f5760405163143343d960e11b81526001600160a01b03878116600483015260248201839052848116604483015285169063286687b290606401602060405180830381600087803b1580156156d357600080fd5b505af1925050508015615703575060408051601f3d908101601f1916820190925261570091810190615aed565b60015b61570c5761570f565b91505b604080516001600160a01b0386811682528581166020830152918101849052908716907f63c76c2cce809bac86aa71be83c1849232efe3e2976c649eb4e44613442682ff9060600160405180910390a250949350505050565b8280548282559060005260206000209081019282156157a85760005260206000209182015b828111156157a857825482559160010191906001019061578d565b506157b492915061584d565b5090565b50805460008255906000526020600020908101906157d6919061584d565b50565b8280546157e590615ed5565b90600052602060002090601f01602090048101928261580757600085556157a8565b82601f1061582057805160ff19168380011785556157a8565b828001600101855582156157a8579182015b828111156157a8578251825591602001919060010190615832565b5b808211156157b4576000815560010161584e565b60008083601f840112615873578182fd5b50813567ffffffffffffffff81111561588a578182fd5b6020830191508360208285010111156158a257600080fd5b9250929050565b6000602082840312156158ba578081fd5b81356136d581615f41565b600080604083850312156158d7578081fd5b82356158e281615f41565b915060208301356158f281615f56565b809150509250929050565b60006020828403121561590e578081fd5b81356136d581615f56565b60006020828403121561592a578081fd5b81516136d581615f56565b60008060408385031215615947578182fd5b825161595281615f56565b6020939093015192949293505050565b60008060408385031215615974578182fd5b823561597f81615f41565b915060208301356158f281615f41565b6000806000806000608086880312156159a6578081fd5b85356159b181615f41565b945060208601356159c181615f41565b935060408601359250606086013567ffffffffffffffff8111156159e3578182fd5b6159ef88828901615862565b969995985093965092949392505050565b60008060008060608587031215615a15578384fd5b8435615a2081615f41565b935060208501359250604085013567ffffffffffffffff811115615a42578283fd5b615a4e87828801615862565b95989497509550505050565b600080600080600080600060c0888a031215615a74578182fd5b8735615a7f81615f41565b96506020880135955060408801359450606088013593506080880135925060a088013567ffffffffffffffff811115615ab6578283fd5b615ac28a828b01615862565b989b979a50959850939692959293505050565b600060208284031215615ae6578081fd5b5035919050565b600060208284031215615afe578081fd5b5051919050565b60008060408385031215615b17578182fd5b8235915060208301356158f281615f41565b60008060408385031215615b3b578182fd5b8235915060208301356158f281615f56565b600080600060408486031215615b61578081fd5b83359250602084013567ffffffffffffffff811115615b7e578182fd5b615b8a86828701615862565b9497909650939450505050565b60008060408385031215615ba9578182fd5b50508035926020909101359150565b60008060008060608587031215615bcd578182fd5b8435935060208501359250604085013567ffffffffffffffff811115615a42578283fd5b6000815180845260208085019450808401835b83811015615c295781516001600160a01b031687529582019590820190600101615c04565b509495945050505050565b6001600160a01b03848116825283166020820152606060408201819052600090615c6090830184615bf1565b95945050505050565b600061012060018060a01b038c16835260208b1515818501528a60408501528960608501528860808501528760a08501528660c08501528560e085015281610100850152845180838601528392505b80831015615cd757858301820151858401610140015291810191615cb8565b80831115615ce9578361014082870101525b601f01601f191693909301610140019c9b505050505050505050505050565b60208082526032908201527f70726f706f7365436f6e73756d657257686974656c697374506565723a20706560408201527132b91032bc34b9ba399030b63932b0b23c9760711b606082015260800190565b60208082526018908201527f556e69667479476f7665726e616e63653a204c4f434b45440000000000000000604082015260600190565b6020808252602c908201527f657865637574653a20616374696f6e2069642035203d3e20706565722065786960408201526b39ba399030b63932b0b23c9760a11b606082015260800190565b848152836020820152826040820152608060608201526000615e026080830184615bf1565b9695505050505050565b600060808201868352602086818501528560408501526080606085015281855180845260a0860191508287019350845b81811015615e5857845183529383019391830191600101615e3c565b50909998505050505050505050565b60008219821115615e7a57615e7a615f2b565b500190565b600082615e9a57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615615eb957615eb9615f2b565b500290565b600082821015615ed057615ed0615f2b565b500390565b600181811c90821680615ee957607f821691505b60208210811415615f0a57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615f2457615f24615f2b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146157d657600080fd5b80151581146157d657600080fdfea264697066735822122060e503fe7d2b00567d7f9967e2a3a3a234c976d2a6be3be4971ffa2d4d14c99e64736f6c63430008040033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.