ETH Price: $3,289.46 (+2.28%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Migrate121389902021-03-30 6:21:501403 days ago1617085310IN
0x04B51297...23B506a95
0 ETH0.0022659994.7600015
Migrate121389892021-03-30 6:21:461403 days ago1617085306IN
0x04B51297...23B506a95
0 ETH0.0023195697
Migrate119161412021-02-23 22:39:521438 days ago1614119992IN
0x04B51297...23B506a95
0 ETH0.00282173118
Submit Mining So...119160822021-02-23 22:27:371438 days ago1614119257IN
0x04B51297...23B506a95
0 ETH0.04447187171.0456597
Submit Mining So...119160452021-02-23 22:19:381438 days ago1614118778IN
0x04B51297...23B506a95
0 ETH0.04784184
Submit Mining So...119160012021-02-23 22:07:501438 days ago1614118070IN
0x04B51297...23B506a95
0 ETH0.04134159

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Tellor

Compiler Version
v0.7.4+commit.3f05b770

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion
File 1 of 9 : Tellor.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;

import "./TellorStake.sol";
import "./TellorGetters.sol";
import "./Utilities.sol";
import "./ITellor.sol";
import "./SafeMath.sol";

/**
 * @title Tellor Oracle System
 * @dev Oracle contract where miners can submit the proof of work along with the value.
 */
contract Tellor is TellorStake {
    using SafeMath for uint256;

    event TipAdded(
        address indexed _sender,
        uint256 indexed _requestId,
        uint256 _tip,
        uint256 _totalTips
    );
    //emits when a new challenge is created (either on mined block or when a new request is pushed forward on waiting system)
    event NewChallenge(
        bytes32 indexed _currentChallenge,
        uint256[5] _currentRequestId,
        uint256 _difficulty,
        uint256 _totalTips
    );
    //Emits upon a successful Mine, indicates the blockTime at point of the mine and the value mined
    event NewValue(
        uint256[5] _requestId,
        uint256 _time,
        uint256[5] _value,
        uint256 _totalTips,
        bytes32 indexed _currentChallenge
    );
    //Emits upon each mine (5 total) and shows the miner, nonce, and value submitted
    event NonceSubmitted(
        address indexed _miner,
        string _nonce,
        uint256[5] _requestId,
        uint256[5] _value,
        bytes32 indexed _currentChallenge,
        uint256 _slot
    );

    /**
     * @dev This is an internal function used by the function migrate  that helps to
     *  swap old trb tokens for new ones based on the user's old Tellor balance
     * @param _user is the msg.sender address of the user to migrate the balance from
     */
    function _migrate(address _user) internal {
        require(!migrated[_user], "alredy migrated");
        _doMint(_user, ITellor(addresses[_OLD_TELLOR]).balanceOf(_user));
        migrated[_user] = true;
    }

    /**
     * @dev This function allows users to swap old trb tokens for new ones based
     * on the user's old Tellor balance
     */
    function migrate() external {
        _migrate(msg.sender);
    }

    /**
     * @dev  allows for the deity to update the TellorStake contract address
     * @param _tGetters the address of the new Tellor Contract
     */
    function changeTellorGetters(address _tGetters) external {
        require(msg.sender == addresses[_DEITY]);
        addresses[_TELLOR_GETTERS] = _tGetters;
    }

    /**
     * @dev This function allows miners to submit their mining solution and data requested
     * @param _nonce is the mining solution
     * @param _requestIds iare the 5 request ids being mined
     * @param _values are the 5 values correspoding to the 5 request ids
     */
    function submitMiningSolution(
        string calldata _nonce,
        uint256[5] calldata _requestIds,
        uint256[5] calldata _values
    ) external {
        bytes32 _hashMsgSender = keccak256(abi.encode(msg.sender));
        require(
            uints[_hashMsgSender] == 0 ||
                block.timestamp - uints[_hashMsgSender] > 15 minutes,
            "Miner can only win rewards once per 15 min"
        );
        if (uints[_SLOT_PROGRESS] != 4) {
            _verifyNonce(_nonce);
        }
        uints[_hashMsgSender] = block.timestamp;
        _submitMiningSolution(_nonce, _requestIds, _values);
    }

    /**
     * @dev This is an internal function used by submitMiningSolution to  allows miners to submit
     * their mining solution and data requested. It checks the miner is staked, has not
     * won in the las 15 min, and checks they are submitting all the correct requestids
     * @param _nonce is the mining solution
     * @param _requestIds iare the 5 request ids being mined
     * @param _values are the 5 values correspoding to the 5 request ids
     */
    function _submitMiningSolution(
        string memory _nonce,
        uint256[5] memory _requestIds,
        uint256[5] memory _values
    ) internal {
        //Verifying Miner Eligibility
        bytes32 _hashMsgSender = keccak256(abi.encode(msg.sender));
        require(
            stakerDetails[msg.sender].currentStatus == 1,
            "Miner status is not staker"
        );

        require(
            _requestIds[0] == currentMiners[0].value,
            "Request ID is wrong"
        );
        require(
            _requestIds[1] == currentMiners[1].value,
            "Request ID is wrong"
        );
        require(
            _requestIds[2] == currentMiners[2].value,
            "Request ID is wrong"
        );
        require(
            _requestIds[3] == currentMiners[3].value,
            "Request ID is wrong"
        );
        require(
            _requestIds[4] == currentMiners[4].value,
            "Request ID is wrong"
        );
        uints[_hashMsgSender] = block.timestamp;

        bytes32 _currChallenge = bytesVars[_CURRENT_CHALLENGE];
        uint256 _slotP = uints[_SLOT_PROGRESS];
        //Checking and updating Miner Status
        require(
            minersByChallenge[_currChallenge][msg.sender] == false,
            "Miner already submitted the value"
        );
        //Update the miner status to true once they submit a value so they don't submit more than once
        minersByChallenge[_currChallenge][msg.sender] = true;
        //Updating Request
        Request storage _tblock = requestDetails[uints[_T_BLOCK]];
        //Assigning directly is cheaper than using a for loop
        _tblock.valuesByTimestamp[0][_slotP] = _values[0];
        _tblock.valuesByTimestamp[1][_slotP] = _values[1];
        _tblock.valuesByTimestamp[2][_slotP] = _values[2];
        _tblock.valuesByTimestamp[3][_slotP] = _values[3];
        _tblock.valuesByTimestamp[4][_slotP] = _values[4];
        _tblock.minersByValue[0][_slotP] = msg.sender;
        _tblock.minersByValue[1][_slotP] = msg.sender;
        _tblock.minersByValue[2][_slotP] = msg.sender;
        _tblock.minersByValue[3][_slotP] = msg.sender;
        _tblock.minersByValue[4][_slotP] = msg.sender;

        if (_slotP + 1 == 4) {
            _adjustDifficulty();
        }

        if (_slotP + 1 == 5) {
            //slotProgress has been incremented, but we're using the variable on stack to save gas
            _newBlock(_nonce, _requestIds);
            uints[_SLOT_PROGRESS] = 0;
        } else {
            uints[_SLOT_PROGRESS]++;
        }
        emit NonceSubmitted(
            msg.sender,
            _nonce,
            _requestIds,
            _values,
            _currChallenge,
            _slotP
        );
    }

    /**
     * @dev This is an internal function used by submitMiningSolution to allows miners to submit
     * their mining solution and data requested. It checks the miner has submitted a
     * valid nonce or allows any solution if 15 minutes or more have passed since last
     *  mine values
     * @param _nonce is the mining solution
     */
    function _verifyNonce(string memory _nonce) internal view {
        require(
            uint256(
                sha256(
                    abi.encodePacked(
                        ripemd160(
                            abi.encodePacked(
                                keccak256(
                                    abi.encodePacked(
                                        bytesVars[_CURRENT_CHALLENGE],
                                        msg.sender,
                                        _nonce
                                    )
                                )
                            )
                        )
                    )
                )
            ) %
                uints[_DIFFICULTY] ==
                0 ||
                block.timestamp - uints[_TIME_OF_LAST_NEW_VALUE] >= 15 minutes,
            "Incorrect nonce for current challenge"
        );
    }

    /**
     * @dev This is an internal function used by submitMiningSolution and adjusts the difficulty
     * based on the the difference between the target time and how long it took to solve
     * the previous challenge otherwise it sets it to 1
     */
    function _adjustDifficulty() internal {
        // If the difference between the timeTarget and how long it takes to solve the challenge this updates the challenge
        //difficulty up or down by the difference between the target time and how long it took to solve the previous challenge
        //otherwise it sets it to 1
        uint256 timeDiff = block.timestamp - uints[_TIME_OF_LAST_NEW_VALUE];
        int256 _change = int256(SafeMath.min(1200, timeDiff));
        int256 _diff = int256(uints[_DIFFICULTY]);
        _change = (_diff * (int256(uints[_TIME_TARGET]) - _change)) / 4000;
        if (_change == 0) {
            _change = 1;
        }
        uints[_DIFFICULTY] = uint256(SafeMath.max(_diff + _change, 1));
    }

    /**
     * @dev This is an internal function used by submitMiningSolution to
     * calculate and pay rewards to miners
     * @param miners are the 5 miners to reward
     * @param _previousTime is the previous mine time based on the 4th entry
     */
    function _payReward(address[5] memory miners, uint256 _previousTime)
        internal
    {
        //_timeDiff is how many seconds passed since last block
        uint256 _timeDiff = block.timestamp - _previousTime;
        uint256 reward = (_timeDiff * uints[_CURRENT_REWARD]) / 300;
        uint256 _tip = uints[_CURRENT_TOTAL_TIPS] / 10;
        uint256 _devShare = reward / 2;

        _doMint(miners[0], reward + _tip);
        _doMint(miners[1], reward + _tip);
        _doMint(miners[2], reward + _tip);
        _doMint(miners[3], reward + _tip);
        _doMint(miners[4], reward + _tip);

        _doMint(addresses[_OWNER], _devShare);
        uints[_CURRENT_TOTAL_TIPS] = 0;
    }

    /**
     * @dev This is an internal function called by submitMiningSolution and adjusts the difficulty,
     * sorts and stores the first 5 values received, pays the miners, the dev share and
     * assigns a new challenge
     * @param _nonce or solution for the PoW  for the requestId
     * @param _requestIds for the current request being mined
     */
    function _newBlock(string memory _nonce, uint256[5] memory _requestIds)
        internal
    {
        Request storage _tblock = requestDetails[uints[_T_BLOCK]];
        bytes32 _currChallenge = bytesVars[_CURRENT_CHALLENGE];
        uint256 _previousTime = uints[_TIME_OF_LAST_NEW_VALUE];
        uint256 _timeOfLastNewValueVar = block.timestamp;
        uints[_TIME_OF_LAST_NEW_VALUE] = _timeOfLastNewValueVar;
        //this loop sorts the values and stores the median as the official value
        uint256[5] memory a;
        uint256[5] memory b;
        for (uint256 k = 0; k < 5; k++) {
            for (uint256 i = 1; i < 5; i++) {
                uint256 temp = _tblock.valuesByTimestamp[k][i];
                address temp2 = _tblock.minersByValue[k][i];
                uint256 j = i;
                while (j > 0 && temp < _tblock.valuesByTimestamp[k][j - 1]) {
                    _tblock.valuesByTimestamp[k][j] = _tblock.valuesByTimestamp[
                        k
                    ][j - 1];
                    _tblock.minersByValue[k][j] = _tblock.minersByValue[k][
                        j - 1
                    ];
                    j--;
                }
                if (j < i) {
                    _tblock.valuesByTimestamp[k][j] = temp;
                    _tblock.minersByValue[k][j] = temp2;
                }
            }
            Request storage _request = requestDetails[_requestIds[k]];
            //Save the official(finalValue), timestamp of it, 5 miners and their submitted values for it, and its block number
            a = _tblock.valuesByTimestamp[k];
            _request.finalValues[_timeOfLastNewValueVar] = a[2];
            b[k] = a[2];
            _request.minersByValue[_timeOfLastNewValueVar] = _tblock
                .minersByValue[k];
            _request.valuesByTimestamp[_timeOfLastNewValueVar] = _tblock
                .valuesByTimestamp[k];
            delete _tblock.minersByValue[k];
            delete _tblock.valuesByTimestamp[k];
            _request.requestTimestamps.push(_timeOfLastNewValueVar);
            _request.minedBlockNum[_timeOfLastNewValueVar] = block.number;
            _request.apiUintVars[_TOTAL_TIP] = 0;
        }
        emit NewValue(
            _requestIds,
            _timeOfLastNewValueVar,
            b,
            uints[_CURRENT_TOTAL_TIPS],
            _currChallenge
        );
        //add timeOfLastValue to the newValueTimestamps array
        newValueTimestamps.push(_timeOfLastNewValueVar);
        address[5] memory miners =
            requestDetails[_requestIds[0]].minersByValue[
                _timeOfLastNewValueVar
            ];
        //pay Miners Rewards
        _payReward(miners, _previousTime);
        uints[_T_BLOCK]++;
        uint256[5] memory _topId = _getTopRequestIDs();
        for (uint256 i = 0; i < 5; i++) {
            currentMiners[i].value = _topId[i];
            requestQ[
                requestDetails[_topId[i]].apiUintVars[_REQUEST_Q_POSITION]
            ] = 0;
            uints[_CURRENT_TOTAL_TIPS] += requestDetails[_topId[i]].apiUintVars[
                _TOTAL_TIP
            ];
        }
        //Issue the the next challenge
        _currChallenge = keccak256(
            abi.encode(_nonce, _currChallenge, blockhash(block.number - 1))
        );
        bytesVars[_CURRENT_CHALLENGE] = _currChallenge; // Save hash for next proof
        emit NewChallenge(
            _currChallenge,
            _topId,
            uints[_DIFFICULTY],
            uints[_CURRENT_TOTAL_TIPS]
        );
    }

    /**
     * @dev Add tip to Request value from oracle
     * @param _requestId being requested to be mined
     * @param _tip amount the requester is willing to pay to be get on queue. Miners
     * mine the onDeckQueryHash, or the api with the highest payout pool
     */
    function addTip(uint256 _requestId, uint256 _tip) external {
        require(_requestId != 0, "RequestId is 0");
        require(_tip != 0, "Tip should be greater than 0");
        uint256 _count = uints[_REQUEST_COUNT] + 1;
        if (_requestId == _count) {
            uints[_REQUEST_COUNT] = _count;
        } else {
            require(_requestId < _count, "RequestId is not less than count");
        }
        _doBurn(msg.sender, _tip);
        //Update the information for the request that should be mined next based on the tip submitted
        updateOnDeck(_requestId, _tip);
        emit TipAdded(
            msg.sender,
            _requestId,
            _tip,
            requestDetails[_requestId].apiUintVars[_TOTAL_TIP]
        );
    }

    /**
     * @dev This function updates the requestQ when addTip are ran
     * @param _requestId being requested
     * @param _tip is the tip to add
     */
    function updateOnDeck(uint256 _requestId, uint256 _tip) internal {
        Request storage _request = requestDetails[_requestId];
        _request.apiUintVars[_TOTAL_TIP] = _request.apiUintVars[_TOTAL_TIP].add(
            _tip
        );
        if (
            currentMiners[0].value == _requestId ||
            currentMiners[1].value == _requestId ||
            currentMiners[2].value == _requestId ||
            currentMiners[3].value == _requestId ||
            currentMiners[4].value == _requestId
        ) {
            uints[_CURRENT_TOTAL_TIPS] += _tip;
        } else {
            //if the request is not part of the requestQ[51] array
            //then add to the requestQ[51] only if the _payout/tip is greater than the minimum(tip) in the requestQ[51] array
            if (_request.apiUintVars[_REQUEST_Q_POSITION] == 0) {
                uint256 _min;
                uint256 _index;
                (_min, _index) = _getMin(requestQ);
                //we have to zero out the oldOne
                //if the _payout is greater than the current minimum payout in the requestQ[51] or if the minimum is zero
                //then add it to the requestQ array and map its index information to the requestId and the apiUintVars
                if (_request.apiUintVars[_TOTAL_TIP] > _min || _min == 0) {
                    requestQ[_index] = _request.apiUintVars[_TOTAL_TIP];
                    requestDetails[requestIdByRequestQIndex[_index]]
                        .apiUintVars[_REQUEST_Q_POSITION] = 0;
                    requestIdByRequestQIndex[_index] = _requestId;
                    _request.apiUintVars[_REQUEST_Q_POSITION] = _index;
                }
                // else if the requestId is part of the requestQ[51] then update the tip for it
            } else {
                requestQ[_request.apiUintVars[_REQUEST_Q_POSITION]] += _tip;
            }
        }
    }

    /**
     * @dev This is an internal function called by updateOnDeck that gets the min value
     * @param data is an array [51] to determine the min from
     * @return min the min value and it's index  in the data array
     */
    function _getMin(uint256[51] memory data)
        internal
        pure
        returns (uint256 min, uint256 minIndex)
    {
        minIndex = data.length - 1;
        min = data[minIndex];
        for (uint256 i = data.length - 2; i > 0; i--) {
            if (data[i] < min) {
                min = data[i];
                minIndex = i;
            }
        }
    }

    /**
     * @dev This is an internal function called by updateOnDeck that gets the top 5 values
     * @param data is an array [51] to determine the top 5 values from
     * @return max the top 5 values and their index values in the data array
     */
    function _getMax5(uint256[51] memory data)
        internal
        pure
        returns (uint256[5] memory max, uint256[5] memory maxIndex)
    {
        uint256 min5 = data[1];
        uint256 minI = 0;
        for (uint256 j = 0; j < 5; j++) {
            max[j] = data[j + 1]; //max[0]=data[1]
            maxIndex[j] = j + 1; //maxIndex[0]= 1
            if (max[j] < min5) {
                min5 = max[j];
                minI = j;
            }
        }
        for (uint256 i = 6; i < data.length; i++) {
            if (data[i] > min5) {
                max[minI] = data[i];
                maxIndex[minI] = i;
                min5 = data[i];
                for (uint256 j = 0; j < 5; j++) {
                    if (max[j] < min5) {
                        min5 = max[j];
                        minI = j;
                    }
                }
            }
        }
    }

    /**
     * @dev Getter function for the top 5 requests with highest payouts.
     * This function is used within the newBlock function
     * @return _requestIds the top 5 requests ids based on tips or the last 5 requests ids mined
     */
    function _getTopRequestIDs()
        internal
        view
        returns (uint256[5] memory _requestIds)
    {
        uint256[5] memory _max;
        uint256[5] memory _index;
        (_max, _index) = _getMax5(requestQ);
        for (uint256 i = 0; i < 5; i++) {
            if (_max[i] != 0) {
                _requestIds[i] = requestIdByRequestQIndex[_index[i]];
            } else {
                _requestIds[i] = currentMiners[4 - i].value;
            }
        }
    }

    /**
     * @dev This is an internal function called within the fallback function to help delegate calls.
     * This functions helps delegate calls to the TellorGetters
     * contract.
     */
    function _delegate(address implementation)
        internal
        virtual
        returns (bool succ, bytes memory ret)
    {
        (succ, ret) = implementation.delegatecall(msg.data);
    }

    /**
     * @dev The tellor logic does not fit in one contract so it has been split into two:
     * Tellor and TellorGetters This functions helps delegate calls to the TellorGetters
     * contract.
     */
    fallback() external payable {
        address addr = addresses[_TELLOR_GETTERS];
        (bool result, ) = _delegate(addr);
        assembly {
            returndatacopy(0, 0, returndatasize())

            switch result
                // delegatecall returns 0 on error.
                case 0 {
                    revert(0, returndatasize())
                }
                default {
                    return(0, returndatasize())
                }
        }
    }
}

File 2 of 9 : TellorStake.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;

import "./TellorTransfer.sol";
import "./TellorGetters.sol";
import "./Utilities.sol";

/**
 * title Tellor Stake
 * @dev Contains the methods related to miners staking, unstaking, initiating disputes,
 * voting on them. Tellor.sol
 * references this library for function's logic.
 */

contract TellorStake is TellorTransfer {
    using SafeMath for uint256;
    using SafeMath for int256;

    //emitted when a new dispute is initialized
    event NewDispute(
        uint256 indexed _disputeId,
        uint256 indexed _requestId,
        uint256 _timestamp,
        address _miner
    );
    //emitted when a new vote happens
    event Voted(
        uint256 indexed _disputeID,
        bool _position,
        address indexed _voter,
        uint256 indexed _voteWeight
    );
    //emitted upon dispute tally
    event DisputeVoteTallied(
        uint256 indexed _disputeID,
        int256 _result,
        address indexed _reportedMiner,
        address _reportingParty,
        bool _active
    );
    event NewStake(address indexed _sender); //Emits upon new staker
    event StakeWithdrawn(address indexed _sender); //Emits when a staker is block.timestamp no longer staked
    event StakeWithdrawRequested(address indexed _sender); //Emits when a staker begins the 7 day withdraw period

    /*Functions*/
    /**
     * @dev This function allows stakers to request to withdraw their stake (no longer stake)
     * once they lock for withdraw(stakes.currentStatus = 2) they are locked for 7 days before they
     * can withdraw the deposit
     */
    function requestStakingWithdraw() public {
        StakeInfo storage stakes = stakerDetails[msg.sender];
        //Require that the miner is staked
        require(stakes.currentStatus == 1, "Miner is not staked");

        //Change the miner staked to locked to be withdrawStake
        stakes.currentStatus = 2;

        //Change the startDate to block.timestamp since the lock up period begins block.timestamp
        //and the miner can only withdraw 7 days later from block.timestamp(check the withdraw function)
        stakes.startDate = block.timestamp - (block.timestamp % 86400);

        //Reduce the staker count
        uints[_STAKE_COUNT] -= 1;

        //Update the minimum dispute fee that is based on the number of stakers
        updateMinDisputeFee();
        emit StakeWithdrawRequested(msg.sender);
    }

    /**
     * @dev This function allows users to withdraw their stake after a 7 day waiting
     * period from request
     */
    function withdrawStake() public {
        StakeInfo storage stakes = stakerDetails[msg.sender];
        //Require the staker has locked for withdraw(currentStatus ==2) and that 7 days have
        //passed by since they locked for withdraw
        require(
            block.timestamp - (block.timestamp % 86400) - stakes.startDate >=
                7 days,
            "7 days didn't pass"
        );
        require(
            stakes.currentStatus == 2,
            "Miner was not locked for withdrawal"
        );
        stakes.currentStatus = 0;
        emit StakeWithdrawn(msg.sender);
    }

    /**
     * @dev This function allows miners to deposit their stake.
     */
    function depositStake() public {
        newStake(msg.sender);
        updateMinDisputeFee();
    }

    /**
     * @dev This internal function is used the depositStake function to successfully stake miners.
     * The function updates their status/state and status start date so they are locked it so they can't withdraw
     * and updates the number of stakers in the system.
     */
    function newStake(address _staker) internal {
        require(
            balanceOf(_staker) >= uints[_STAKE_AMOUNT],
            "Balance is lower than stake amount"
        );
        //Ensure they can only stake if they are not currently staked or if their stake time frame has ended
        //and they are currently locked for withdraw
        require(
            stakerDetails[_staker].currentStatus == 0 ||
                stakerDetails[_staker].currentStatus == 2,
            "Miner is in the wrong state"
        );
        uints[_STAKE_COUNT] += 1;
        stakerDetails[_staker] = StakeInfo({
            currentStatus: 1, //this resets their stake start date to today
            startDate: block.timestamp - (block.timestamp % 86400)
        });
        emit NewStake(_staker);
    }

    /**
     * @dev Helps initialize a dispute by assigning it a disputeId
     * when a miner returns a false/bad value on the validate array(in Tellor.ProofOfWork) it sends the
     * invalidated value information to POS voting
     * @param _requestId being disputed
     * @param _timestamp being disputed
     * @param _minerIndex the index of the miner that submitted the value being disputed. Since each official value
     * requires 5 miners to submit a value.
     */
    function beginDispute(
        uint256 _requestId,
        uint256 _timestamp,
        uint256 _minerIndex
    ) public {
        Request storage _request = requestDetails[_requestId];
        require(_request.minedBlockNum[_timestamp] != 0, "Mined block is 0");
        require(_minerIndex < 5, "Miner index is wrong");

        //_miner is the miner being disputed. For every mined value 5 miners are saved in an array and the _minerIndex
        //provided by the party initiating the dispute
        address _miner = _request.minersByValue[_timestamp][_minerIndex];
        bytes32 _hash =
            keccak256(abi.encodePacked(_miner, _requestId, _timestamp));

        //Increase the dispute count by 1
        uint256 disputeId = uints[_DISPUTE_COUNT] + 1;
        uints[_DISPUTE_COUNT] = disputeId;

        //Ensures that a dispute is not already open for the that miner, requestId and timestamp
        uint256 hashId = disputeIdByDisputeHash[_hash];
        if (hashId != 0) {
            disputesById[disputeId].disputeUintVars[_ORIGINAL_ID] = hashId;
        } else {
            disputeIdByDisputeHash[_hash] = disputeId;
            hashId = disputeId;
        }
        uint256 origID = hashId;
        uint256 dispRounds =
            disputesById[origID].disputeUintVars[_DISPUTE_ROUNDS] + 1;
        disputesById[origID].disputeUintVars[_DISPUTE_ROUNDS] = dispRounds;
        disputesById[origID].disputeUintVars[
            keccak256(abi.encode(dispRounds))
        ] = disputeId;
        if (disputeId != origID) {
            uint256 lastID =
                disputesById[origID].disputeUintVars[
                    keccak256(abi.encode(dispRounds - 1))
                ];
            require(
                disputesById[lastID].disputeUintVars[_MIN_EXECUTION_DATE] <=
                    block.timestamp,
                "Dispute is already open"
            );
            if (disputesById[lastID].executed) {
                require(
                    block.timestamp -
                        disputesById[lastID].disputeUintVars[_TALLY_DATE] <=
                        1 days,
                    "Time for voting haven't elapsed"
                );
            }
        }
        uint256 _fee;
        if (_minerIndex == 2) {
            requestDetails[_requestId].apiUintVars[_DISPUTE_COUNT] =
                requestDetails[_requestId].apiUintVars[_DISPUTE_COUNT] +
                1;
            //update dispute fee for this case
            _fee =
                uints[_STAKE_AMOUNT] *
                requestDetails[_requestId].apiUintVars[_DISPUTE_COUNT];
        } else {
            _fee = uints[_DISPUTE_FEE] * dispRounds;
        }

        //maps the dispute to the Dispute struct
        disputesById[disputeId].hash = _hash;
        disputesById[disputeId].isPropFork = false;
        disputesById[disputeId].reportedMiner = _miner;
        disputesById[disputeId].reportingParty = msg.sender;
        disputesById[disputeId].proposedForkAddress = address(0);
        disputesById[disputeId].executed = false;
        disputesById[disputeId].disputeVotePassed = false;
        disputesById[disputeId].tally = 0;

        //Saves all the dispute variables for the disputeId
        disputesById[disputeId].disputeUintVars[_REQUEST_ID] = _requestId;
        disputesById[disputeId].disputeUintVars[_TIMESTAMP] = _timestamp;
        disputesById[disputeId].disputeUintVars[_VALUE] = _request
            .valuesByTimestamp[_timestamp][_minerIndex];
        disputesById[disputeId].disputeUintVars[_MIN_EXECUTION_DATE] =
            block.timestamp +
            2 days *
            dispRounds;
        disputesById[disputeId].disputeUintVars[_BLOCK_NUMBER] = block.number;
        disputesById[disputeId].disputeUintVars[_MINER_SLOT] = _minerIndex;
        disputesById[disputeId].disputeUintVars[_FEE] = _fee;
        _doTransfer(msg.sender, address(this), _fee);

        //Values are sorted as they come in and the official value is the median of the first five
        //So the "official value" miner is always minerIndex==2. If the official value is being
        //disputed, it sets its status to inDispute(currentStatus = 3) so that users are made aware it is under dispute
        if (_minerIndex == 2) {
            _request.inDispute[_timestamp] = true;
            _request.finalValues[_timestamp] = 0;
        }
        stakerDetails[_miner].currentStatus = 3;
        emit NewDispute(disputeId, _requestId, _timestamp, _miner);
    }

    /**
     * @dev Allows token holders to vote
     * @param _disputeId is the dispute id
     * @param _supportsDispute is the vote (true=the dispute has basis false = vote against dispute)
     */
    function vote(uint256 _disputeId, bool _supportsDispute) public {
        Dispute storage disp = disputesById[_disputeId];

        //Get the voteWeight or the balance of the user at the time/blockNumber the dispute began
        uint256 voteWeight =
            balanceOfAt(msg.sender, disp.disputeUintVars[_BLOCK_NUMBER]);

        //Require that the msg.sender has not voted
        require(disp.voted[msg.sender] != true, "Sender has already voted");

        //Require that the user had a balance >0 at time/blockNumber the dispute began
        require(voteWeight != 0, "User balance is 0");

        //ensures miners that are under dispute cannot vote
        require(
            stakerDetails[msg.sender].currentStatus != 3,
            "Miner is under dispute"
        );

        //Update user voting status to true
        disp.voted[msg.sender] = true;

        //Update the number of votes for the dispute
        disp.disputeUintVars[_NUM_OF_VOTES] += 1;

        //If the user supports the dispute increase the tally for the dispute by the voteWeight
        //otherwise decrease it
        if (_supportsDispute) {
            disp.tally = disp.tally.add(int256(voteWeight));
        } else {
            disp.tally = disp.tally.sub(int256(voteWeight));
        }

        //Let the network kblock.timestamp the user has voted on the dispute and their casted vote
        emit Voted(_disputeId, _supportsDispute, msg.sender, voteWeight);
    }

    /**
     * @dev tallies the votes and locks the stake disbursement(currentStatus = 4) if the vote passes
     * @param _disputeId is the dispute id
     */
    function tallyVotes(uint256 _disputeId) public {
        Dispute storage disp = disputesById[_disputeId];
        //Ensure this has not already been executed/tallied
        require(disp.executed == false, "Dispute has been already executed");
        require(
            block.timestamp >= disp.disputeUintVars[_MIN_EXECUTION_DATE],
            "Time for voting haven't elapsed"
        );
        require(
            disp.reportingParty != address(0),
            "reporting Party is address 0"
        );
        int256 _tally = disp.tally;
        if (_tally > 0) {
            //Set the dispute state to passed/true
            disp.disputeVotePassed = true;
        }
        //If the vote is not a proposed fork
        if (disp.isPropFork == false) {
            //Ensure the time for voting has elapsed
            StakeInfo storage stakes = stakerDetails[disp.reportedMiner];
            //If the vote for disputing a value is successful(disp.tally >0) then unstake the reported
            // miner and transfer the stakeAmount and dispute fee to the reporting party
            if (stakes.currentStatus == 3) {
                stakes.currentStatus = 4;
            }
        }
        disp.disputeUintVars[_TALLY_DATE] = block.timestamp;
        disp.executed = true;
        emit DisputeVoteTallied(
            _disputeId,
            _tally,
            disp.reportedMiner,
            disp.reportingParty,
            disp.disputeVotePassed
        );
    }

    /**
     * @dev Allows disputer to unlock the dispute fee
     * @param _disputeId to unlock fee from
     */
    function unlockDisputeFee(uint256 _disputeId) public {
        uint256 origID = disputeIdByDisputeHash[disputesById[_disputeId].hash];
        uint256 lastID =
            disputesById[origID].disputeUintVars[
                keccak256(
                    abi.encode(
                        disputesById[origID].disputeUintVars[_DISPUTE_ROUNDS]
                    )
                )
            ];
        if (lastID == 0) {
            lastID = origID;
        }
        Dispute storage disp = disputesById[origID];
        Dispute storage last = disputesById[lastID];
        //disputeRounds is increased by 1 so that the _id is not a negative number when it is the first time a dispute is initiated
        uint256 dispRounds = disp.disputeUintVars[_DISPUTE_ROUNDS];
        if (dispRounds == 0) {
            dispRounds = 1;
        }
        uint256 _id;
        require(disp.disputeUintVars[_PAID] == 0, "already paid out");
        require(
            block.timestamp - last.disputeUintVars[_TALLY_DATE] > 1 days,
            "Time for voting haven't elapsed"
        );
        StakeInfo storage stakes = stakerDetails[disp.reportedMiner];
        disp.disputeUintVars[_PAID] = 1;
        if (last.disputeVotePassed == true) {
            //Changing the currentStatus and startDate unstakes the reported miner and transfers the stakeAmount
            stakes.startDate = block.timestamp - (block.timestamp % 86400);

            //Reduce the staker count
            uints[_STAKE_COUNT] -= 1;

            //Update the minimum dispute fee that is based on the number of stakers
            updateMinDisputeFee();
            //Decreases the stakerCount since the miner's stake is being slashed
            if (stakes.currentStatus == 4) {
                stakes.currentStatus = 5;
                _doTransfer(
                    disp.reportedMiner,
                    disp.reportingParty,
                    uints[_STAKE_AMOUNT]
                );
                stakes.currentStatus = 0;
            }
            for (uint256 i = 0; i < dispRounds; i++) {
                _id = disp.disputeUintVars[
                    keccak256(abi.encode(dispRounds - i))
                ];
                if (_id == 0) {
                    _id = origID;
                }
                Dispute storage disp2 = disputesById[_id];
                //transfer fee adjusted based on number of miners if the minerIndex is not 2(official value)
                _doTransfer(
                    address(this),
                    disp2.reportingParty,
                    disp2.disputeUintVars[_FEE]
                );
            }
        } else {
            stakes.currentStatus = 1;
            TellorStorage.Request storage _request =
                requestDetails[disp.disputeUintVars[_REQUEST_ID]];
            if (disp.disputeUintVars[_MINER_SLOT] == 2) {
                //note we still don't put timestamp back into array (is this an issue? (shouldn't be))
                _request.finalValues[disp.disputeUintVars[_TIMESTAMP]] = disp
                    .disputeUintVars[_VALUE];
            }
            if (_request.inDispute[disp.disputeUintVars[_TIMESTAMP]] == true) {
                _request.inDispute[disp.disputeUintVars[_TIMESTAMP]] = false;
            }
            for (uint256 i = 0; i < dispRounds; i++) {
                _id = disp.disputeUintVars[
                    keccak256(abi.encode(dispRounds - i))
                ];
                if (_id != 0) {
                    last = disputesById[_id]; //handling if happens during an upgrade
                }
                _doTransfer(
                    address(this),
                    last.reportedMiner,
                    disputesById[_id].disputeUintVars[_FEE]
                );
            }
        }

        if (disp.disputeUintVars[_MINER_SLOT] == 2) {
            requestDetails[disp.disputeUintVars[_REQUEST_ID]].apiUintVars[
                _DISPUTE_COUNT
            ]--;
        }
    }

    /**
     * @dev This function updates the minimum dispute fee as a function of the amount
     * of staked miners
     */
    function updateMinDisputeFee() public {
        uint256 _stakeAmt = uints[_STAKE_AMOUNT];
        uint256 _trgtMiners = uints[_TARGET_MINERS];
        uints[_DISPUTE_FEE] = SafeMath.max(
            15e18,
            (_stakeAmt -
                ((_stakeAmt *
                    (SafeMath.min(_trgtMiners, uints[_STAKE_COUNT]) * 1000)) /
                    _trgtMiners) /
                1000)
        );
    }
}

File 3 of 9 : TellorGetters.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
import "./SafeMath.sol";
import "./TellorStorage.sol";
import "./TellorVariables.sol";
import "./Utilities.sol";

/**
 * @title Tellor Getters
 * @dev Oracle contract with all tellor getter functions
 */
contract TellorGetters is TellorStorage, TellorVariables, Utilities {
    using SafeMath for uint256;

    /**
     * @dev This function tells you if a given challenge has been completed by a given miner
     * @param _challenge the challenge to search for
     * @param _miner address that you want to know if they solved the challenge
     * @return true if the _miner address provided solved the
     */
    function didMine(bytes32 _challenge, address _miner)
        public
        view
        returns (bool)
    {
        return minersByChallenge[_challenge][_miner];
    }

    /**
     * @dev Checks if an address voted in a given dispute
     * @param _disputeId to look up
     * @param _address to look up
     * @return bool of whether or not party voted
     */
    function didVote(uint256 _disputeId, address _address)
        external
        view
        returns (bool)
    {
        return disputesById[_disputeId].voted[_address];
    }

    /**
     * @dev allows Tellor to read data from the addressVars mapping
     * @param _data is the keccak256("variable_name") of the variable that is being accessed.
     * These are examples of how the variables are saved within other functions:
     * addressVars[keccak256("_owner")]
     * addressVars[keccak256("tellorContract")]
     * @return address of the requested variable
     */
    function getAddressVars(bytes32 _data) external view returns (address) {
        return addresses[_data];
    }

    /**
     * @dev Gets all dispute variables
     * @param _disputeId to look up
     * @return bytes32 hash of dispute
     * bool executed where true if it has been voted on
     * bool disputeVotePassed
     * bool isPropFork true if the dispute is a proposed fork
     * address of reportedMiner
     * address of reportingParty
     * address of proposedForkAddress
     * uint of requestId
     * uint of timestamp
     * uint of value
     * uint of minExecutionDate
     * uint of numberOfVotes
     * uint of blocknumber
     * uint of minerSlot
     * uint of quorum
     * uint of fee
     * int count of the current tally
     */
    function getAllDisputeVars(uint256 _disputeId)
        public
        view
        returns (
            bytes32,
            bool,
            bool,
            bool,
            address,
            address,
            address,
            uint256[9] memory,
            int256
        )
    {
        Dispute storage disp = disputesById[_disputeId];
        return (
            disp.hash,
            disp.executed,
            disp.disputeVotePassed,
            disp.isPropFork,
            disp.reportedMiner,
            disp.reportingParty,
            disp.proposedForkAddress,
            [
                disp.disputeUintVars[_REQUEST_ID],
                disp.disputeUintVars[_TIMESTAMP],
                disp.disputeUintVars[_VALUE],
                disp.disputeUintVars[_MIN_EXECUTION_DATE],
                disp.disputeUintVars[_NUM_OF_VOTES],
                disp.disputeUintVars[_BLOCK_NUMBER],
                disp.disputeUintVars[_MINER_SLOT],
                disp.disputeUintVars[keccak256("quorum")],
                disp.disputeUintVars[_FEE]
            ],
            disp.tally
        );
    }

    /**
     * @dev Checks if a given hash of miner,requestId has been disputed
     * @param _hash is the sha256(abi.encodePacked(_miners[2],_requestId,_timestamp));
     * @return uint disputeId
     */
    function getDisputeIdByDisputeHash(bytes32 _hash)
        external
        view
        returns (uint256)
    {
        return disputeIdByDisputeHash[_hash];
    }

    /**
     * @dev Checks for uint variables in the disputeUintVars mapping based on the disputeId
     * @param _disputeId is the dispute id;
     * @param _data the variable to pull from the mapping. _data = keccak256("variable_name") where variable_name is
     * the variables/strings used to save the data in the mapping. The variables names are
     * commented out under the disputeUintVars under the Dispute struct
     * @return uint value for the bytes32 data submitted
     */
    function getDisputeUintVars(uint256 _disputeId, bytes32 _data)
        external
        view
        returns (uint256)
    {
        return disputesById[_disputeId].disputeUintVars[_data];
    }

    /**
     * @dev Gets the a value for the latest timestamp available
     * @return value for timestamp of last proof of work submitted
     * @return true if the is a timestamp for the lastNewValue
     */
    function getLastNewValue() external view returns (uint256, bool) {
        return (
            retrieveData(
                requestIdByTimestamp[uints[_TIME_OF_LAST_NEW_VALUE]],
                uints[_TIME_OF_LAST_NEW_VALUE]
            ),
            true
        );
    }

    /**
     * @dev Gets the a value for the latest timestamp available
     * @param _requestId being requested
     * @return value for timestamp of last proof of work submitted and if true if it exist or 0 and false if it doesn't
     */
    function getLastNewValueById(uint256 _requestId)
        external
        view
        returns (uint256, bool)
    {
        Request storage _request = requestDetails[_requestId];
        if (_request.requestTimestamps.length != 0) {
            return (
                retrieveData(
                    _requestId,
                    _request.requestTimestamps[
                        _request.requestTimestamps.length - 1
                    ]
                ),
                true
            );
        } else {
            return (0, false);
        }
    }

    /**
     * @dev Gets blocknumber for mined timestamp
     * @param _requestId to look up
     * @param _timestamp is the timestamp to look up blocknumber
     * @return uint of the blocknumber which the dispute was mined
     */
    function getMinedBlockNum(uint256 _requestId, uint256 _timestamp)
        external
        view
        returns (uint256)
    {
        return requestDetails[_requestId].minedBlockNum[_timestamp];
    }

    /**
     * @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp
     * @param _requestId to look up
     * @param _timestamp is the timestamp to look up miners for
     * @return the 5 miners' addresses
     */
    function getMinersByRequestIdAndTimestamp(
        uint256 _requestId,
        uint256 _timestamp
    ) external view returns (address[5] memory) {
        return requestDetails[_requestId].minersByValue[_timestamp];
    }

    /**
     * @dev Counts the number of values that have been submitted for the request
     * if called for the currentRequest being mined it can tell you how many miners have submitted a value for that
     * request so far
     * @param _requestId the requestId to look up
     * @return uint count of the number of values received for the requestId
     */
    function getNewValueCountbyRequestId(uint256 _requestId)
        external
        view
        returns (uint256)
    {
        return requestDetails[_requestId].requestTimestamps.length;
    }

    /**
     * @dev Getter function for the specified requestQ index
     * @param _index to look up in the requestQ array
     * @return uint of requestId
     */
    function getRequestIdByRequestQIndex(uint256 _index)
        external
        view
        returns (uint256)
    {
        require(_index <= 50, "RequestQ index is above 50");
        return requestIdByRequestQIndex[_index];
    }

    /**
     * @dev Getter function for requestId based on timestamp
     * @param _timestamp to check requestId
     * @return uint of requestId
     */
    function getRequestIdByTimestamp(uint256 _timestamp)
        external
        view
        returns (uint256)
    {
        return requestIdByTimestamp[_timestamp];
    }

    /**
     * @dev Getter function for the requestQ array
     * @return the requestQ array
     */
    function getRequestQ() public view returns (uint256[51] memory) {
        return requestQ;
    }

    /**
     * @dev Allows access to the uint variables saved in the apiUintVars under the requestDetails struct
     * for the requestId specified
     * @param _requestId to look up
     * @param _data the variable to pull from the mapping. _data = keccak256("variable_name") where variable_name is
     * the variables/strings used to save the data in the mapping. The variables names are
     * commented out under the apiUintVars under the requestDetails struct
     * @return uint value of the apiUintVars specified in _data for the requestId specified
     */
    function getRequestUintVars(uint256 _requestId, bytes32 _data)
        external
        view
        returns (uint256)
    {
        return requestDetails[_requestId].apiUintVars[_data];
    }

    /**
     * @dev Gets the API struct variables that are not mappings
     * @param _requestId to look up
     * @return uint of index in requestQ array
     * @return uint of current payout/tip for this requestId
     */
    function getRequestVars(uint256 _requestId)
        external
        view
        returns (uint256, uint256)
    {
        Request storage _request = requestDetails[_requestId];
        return (
            _request.apiUintVars[_REQUEST_Q_POSITION],
            _request.apiUintVars[_TOTAL_TIP]
        );
    }

    /**
     * @dev This function allows users to retrieve all information about a staker
     * @param _staker address of staker inquiring about
     * @return uint current state of staker
     * @return uint startDate of staking
     */
    function getStakerInfo(address _staker)
        external
        view
        returns (uint256, uint256)
    {
        return (
            stakerDetails[_staker].currentStatus,
            stakerDetails[_staker].startDate
        );
    }

    /**
     * @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp
     * @param _requestId to look up
     * @param _timestamp is the timestamp to look up miners for
     * @return address[5] array of 5 addresses of miners that mined the requestId
     */
    function getSubmissionsByTimestamp(uint256 _requestId, uint256 _timestamp)
        external
        view
        returns (uint256[5] memory)
    {
        return requestDetails[_requestId].valuesByTimestamp[_timestamp];
    }

    /**
     * @dev Gets the timestamp for the value based on their index
     * @param _requestID is the requestId to look up
     * @param _index is the value index to look up
     * @return uint timestamp
     */
    function getTimestampbyRequestIDandIndex(uint256 _requestID, uint256 _index)
        external
        view
        returns (uint256)
    {
        return requestDetails[_requestID].requestTimestamps[_index];
    }

    /**
     * @dev Getter for the variables saved under the TellorStorageStruct uints variable
     * @param _data the variable to pull from the mapping. _data = keccak256("variable_name")
     * where variable_name is the variables/strings used to save the data in the mapping.
     * The variables names in the TellorVariables contract
     * @return uint of specified variable
     */
    function getUintVar(bytes32 _data) public view returns (uint256) {
        return uints[_data];
    }

    /**
     * @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp
     * @param _requestId to look up
     * @param _timestamp is the timestamp to look up miners for
     * @return bool true if requestId/timestamp is under dispute
     */
    function isInDispute(uint256 _requestId, uint256 _timestamp)
        external
        view
        returns (bool)
    {
        return requestDetails[_requestId].inDispute[_timestamp];
    }

    /**
     * @dev Retrieve value from oracle based on timestamp
     * @param _requestId being requested
     * @param _timestamp to retrieve data/value from
     * @return value for timestamp submitted
     */
    function retrieveData(uint256 _requestId, uint256 _timestamp)
        public
        view
        returns (uint256)
    {
        return requestDetails[_requestId].finalValues[_timestamp];
    }

    /**
     * @dev Getter for the total_supply of oracle tokens
     * @return uint total supply
     */
    function totalSupply() external view returns (uint256) {
        return uints[_TOTAL_SUPPLY];
    }

    /**
     * @dev Allows users to access the token's name
     */
    function name() external pure returns (string memory) {
        return "Tellor Tributes";
    }

    /**
     * @dev Allows users to access the token's symbol
     */
    function symbol() external pure returns (string memory) {
        return "TRB";
    }

    /**
     * @dev Allows users to access the number of decimals
     */
    function decimals() external pure returns (uint8) {
        return 18;
    }

    /**
     * @dev Getter function for the requestId being mined
     * returns the currentChallenge, array of requestIDs, difficulty, and the current Tip of the 5 IDs
     */
    function getNewCurrentVariables()
        external
        view
        returns (
            bytes32 _challenge,
            uint256[5] memory _requestIds,
            uint256 _diff,
            uint256 _tip
        )
    {
        for (uint256 i = 0; i < 5; i++) {
            _requestIds[i] = currentMiners[i].value;
        }
        return (
            bytesVars[_CURRENT_CHALLENGE],
            _requestIds,
            uints[_DIFFICULTY],
            uints[_CURRENT_TOTAL_TIPS]
        );
    }

    /**
     * @dev Getter function for next requestIds on queue/request with highest payouts at time the function is called
     */
    function getNewVariablesOnDeck()
        external
        view
        returns (uint256[5] memory idsOnDeck, uint256[5] memory tipsOnDeck)
    {
        idsOnDeck = getTopRequestIDs();
        for (uint256 i = 0; i < 5; i++) {
            tipsOnDeck[i] = requestDetails[idsOnDeck[i]].apiUintVars[
                _TOTAL_TIP
            ];
        }
    }

    /**
     * @dev Getter function for the top 5 requests with highest payouts. This function is used within the getNewVariablesOnDeck function
     */
    function getTopRequestIDs()
        public
        view
        returns (uint256[5] memory _requestIds)
    {
        uint256[5] memory _max;
        uint256[5] memory _index;
        (_max, _index) = getMax5(requestQ);
        for (uint256 i = 0; i < 5; i++) {
            if (_max[i] != 0) {
                _requestIds[i] = requestIdByRequestQIndex[_index[i]];
            } else {
                _requestIds[i] = currentMiners[4 - i].value;
            }
        }
    }
}

File 4 of 9 : Utilities.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;

//Functions for retrieving min and Max in 51 length array (requestQ)
//Taken partly from: https://github.com/modular-network/ethereum-libraries-array-utils/blob/master/contracts/Array256Lib.sol

contract Utilities {
    /**
     * @dev This is an internal function called by updateOnDeck that gets the top 5 values
     * @param data is an array [51] to determine the top 5 values from
     * @return max the top 5 values and their index values in the data array
     */
    function getMax5(uint256[51] memory data)
        public
        view
        returns (uint256[5] memory max, uint256[5] memory maxIndex)
    {
        uint256 min5 = data[1];
        uint256 minI = 0;
        for (uint256 j = 0; j < 5; j++) {
            max[j] = data[j + 1]; //max[0]=data[1]
            maxIndex[j] = j + 1; //maxIndex[0]= 1
            if (max[j] < min5) {
                min5 = max[j];
                minI = j;
            }
        }
        for (uint256 i = 6; i < data.length; i++) {
            if (data[i] > min5) {
                max[minI] = data[i];
                maxIndex[minI] = i;
                min5 = data[i];
                for (uint256 j = 0; j < 5; j++) {
                    if (max[j] < min5) {
                        min5 = max[j];
                        minI = j;
                    }
                }
            }
        }
    }
}

File 5 of 9 : ITellor.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;

abstract contract ITellor {
    event NewTellorAddress(address _newTellor);
    event NewDispute(
        uint256 indexed _disputeId,
        uint256 indexed _requestId,
        uint256 _timestamp,
        address _miner
    );
    event Voted(
        uint256 indexed _disputeID,
        bool _position,
        address indexed _voter,
        uint256 indexed _voteWeight
    );
    event DisputeVoteTallied(
        uint256 indexed _disputeID,
        int256 _result,
        address indexed _reportedMiner,
        address _reportingParty,
        bool _active
    );
    event TipAdded(
        address indexed _sender,
        uint256 indexed _requestId,
        uint256 _tip,
        uint256 _totalTips
    );
    event NewChallenge(
        bytes32 indexed _currentChallenge,
        uint256[5] _currentRequestId,
        uint256 _difficulty,
        uint256 _totalTips
    );
    event NewValue(
        uint256[5] _requestId,
        uint256 _time,
        uint256[5] _value,
        uint256 _totalTips,
        bytes32 indexed _currentChallenge
    );
    event NonceSubmitted(
        address indexed _miner,
        string _nonce,
        uint256[5] _requestId,
        uint256[5] _value,
        bytes32 indexed _currentChallenge
    );
    event OwnershipTransferred(
        address indexed _previousOwner,
        address indexed _newOwner
    );
    event OwnershipProposed(
        address indexed _previousOwner,
        address indexed _newOwner
    );
    event NewStake(address indexed _sender); //Emits upon new staker
    event StakeWithdrawn(address indexed _sender); //Emits when a staker is now no longer staked
    event StakeWithdrawRequested(address indexed _sender); //Emits when a staker begins the 7 day withdraw period
    event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _value
    ); //ERC20 Approval event
    event Transfer(address indexed _from, address indexed _to, uint256 _value); //ERC20 Transfer Event

    function changeDeity(address _newDeity) external virtual;

    function changeTellorContract(address _tellorContract) external virtual;

    function allowance(address _user, address _spender)
        external
        view
        virtual
        returns (uint256);

    function allowedToTrade(address _user, uint256 _amount)
        external
        view
        virtual
        returns (bool);

    function balanceOf(address _user) external view virtual returns (uint256);

    function balanceOfAt(address _user, uint256 _blockNumber)
        external
        view
        virtual
        returns (uint256);

    function didMine(bytes32 _challenge, address _miner)
        external
        view
        virtual
        returns (bool);

    function didVote(uint256 _disputeId, address _address)
        external
        view
        virtual
        returns (bool);

    function getAddressVars(bytes32 _data)
        external
        view
        virtual
        returns (address);

    function getAllDisputeVars(uint256 _disputeId)
        public
        view
        virtual
        returns (
            bytes32,
            bool,
            bool,
            bool,
            address,
            address,
            address,
            uint256[9] memory,
            int256
        );

    function getCurrentVariables()
        external
        view
        virtual
        returns (
            bytes32,
            uint256,
            uint256,
            string memory,
            uint256,
            uint256
        );

    function getDisputeIdByDisputeHash(bytes32 _hash)
        external
        view
        virtual
        returns (uint256);

    function getDisputeUintVars(uint256 _disputeId, bytes32 _data)
        external
        view
        virtual
        returns (uint256);

    function getLastNewValue() external view virtual returns (uint256, bool);

    function getLastNewValueById(uint256 _requestId)
        external
        view
        virtual
        returns (uint256, bool);

    function getMinedBlockNum(uint256 _requestId, uint256 _timestamp)
        external
        view
        virtual
        returns (uint256);

    function getMinersByRequestIdAndTimestamp(
        uint256 _requestId,
        uint256 _timestamp
    ) external view virtual returns (address[5] memory);

    function getNewValueCountbyRequestId(uint256 _requestId)
        external
        view
        virtual
        returns (uint256);

    function getRequestIdByRequestQIndex(uint256 _index)
        external
        view
        virtual
        returns (uint256);

    function getRequestIdByTimestamp(uint256 _timestamp)
        external
        view
        virtual
        returns (uint256);

    function getRequestIdByQueryHash(bytes32 _request)
        external
        view
        virtual
        returns (uint256);

    function getRequestQ() public view virtual returns (uint256[51] memory);

    function getRequestUintVars(uint256 _requestId, bytes32 _data)
        external
        view
        virtual
        returns (uint256);

    function getRequestVars(uint256 _requestId)
        external
        view
        virtual
        returns (uint256, uint256);

    function getStakerInfo(address _staker)
        external
        view
        virtual
        returns (uint256, uint256);

    function getSubmissionsByTimestamp(uint256 _requestId, uint256 _timestamp)
        external
        view
        virtual
        returns (uint256[5] memory);

    function getTimestampbyRequestIDandIndex(uint256 _requestID, uint256 _index)
        external
        view
        virtual
        returns (uint256);

    function getUintVar(bytes32 _data) public view virtual returns (uint256);

    function getVariablesOnDeck()
        external
        view
        virtual
        returns (
            uint256,
            uint256,
            string memory
        );

    function isInDispute(uint256 _requestId, uint256 _timestamp)
        external
        view
        virtual
        returns (bool);

    function retrieveData(uint256 _requestId, uint256 _timestamp)
        external
        view
        virtual
        returns (uint256);

    function totalSupply() external view virtual returns (uint256);

    function beginDispute(
        uint256 _requestId,
        uint256 _timestamp,
        uint256 _minerIndex
    ) external virtual;

    function vote(uint256 _disputeId, bool _supportsDispute) external virtual;

    function tallyVotes(uint256 _disputeId) external virtual;

    function proposeFork(address _propNewTellorAddress) external virtual;

    function addTip(uint256 _requestId, uint256 _tip) external virtual;

    function submitMiningSolution(
        string calldata _nonce,
        uint256[5] calldata _requestId,
        uint256[5] calldata _value
    ) external virtual;

    function proposeOwnership(address payable _pendingOwner) external virtual;

    function claimOwnership() external virtual;

    function depositStake() external virtual;

    function requestStakingWithdraw() external virtual;

    function withdrawStake() external virtual;

    function approve(address _spender, uint256 _amount)
        external
        virtual
        returns (bool);

    function transfer(address _to, uint256 _amount)
        external
        virtual
        returns (bool);

    function transferFrom(
        address _from,
        address _to,
        uint256 _amount
    ) external virtual returns (bool);

    function name() external pure virtual returns (string memory);

    function symbol() external pure virtual returns (string memory);

    function decimals() external pure virtual returns (uint8);

    function getNewCurrentVariables()
        external
        view
        virtual
        returns (
            bytes32 _challenge,
            uint256[5] memory _requestIds,
            uint256 _difficutly,
            uint256 _tip
        );

    function getTopRequestIDs()
        external
        view
        virtual
        returns (uint256[5] memory _requestIds);

    function getNewVariablesOnDeck()
        external
        view
        virtual
        returns (uint256[5] memory idsOnDeck, uint256[5] memory tipsOnDeck);

    function updateTellor(uint256 _disputeId) external virtual;

    function unlockDisputeFee(uint256 _disputeId) external virtual;

    //Test Functions
    function theLazyCoon(address _address, uint256 _amount) external virtual;

    function testSubmitMiningSolution(
        string calldata _nonce,
        uint256[5] calldata _requestId,
        uint256[5] calldata _value
    ) external virtual;

    function manuallySetDifficulty(uint256 _diff) external virtual {}

    function migrate() external {}

    function getMax(uint256[51] memory data)
        public
        view
        virtual
        returns (uint256 max, uint256 maxIndex);

    function getMin(uint256[51] memory data)
        public
        view
        virtual
        returns (uint256 min, uint256 minIndex);

    function getMax5(uint256[51] memory data)
        public
        view
        virtual
        returns (uint256[5] memory max, uint256[5] memory maxIndex);

    function changeTellorGetters(address _tGetters) external virtual;
}

File 6 of 9 : SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;

//Slightly modified SafeMath library - includes a min and max function, removes useless div function
library SafeMath {
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        assert(c >= a);
        return c;
    }

    function add(int256 a, int256 b) internal pure returns (int256 c) {
        if (b > 0) {
            c = a + b;
            assert(c >= a);
        } else {
            c = a + b;
            assert(c <= a);
        }
    }

    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    function max(int256 a, int256 b) internal pure returns (uint256) {
        return a > b ? uint256(a) : uint256(b);
    }

    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a * b;
        assert(a == 0 || c / a == b);
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
    }

    function sub(int256 a, int256 b) internal pure returns (int256 c) {
        if (b > 0) {
            c = a - b;
            assert(c <= a);
        } else {
            c = a - b;
            assert(c >= a);
        }
    }
}

File 7 of 9 : TellorTransfer.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;

import "./SafeMath.sol";
import "./TellorStorage.sol";
import "./TellorVariables.sol";

/**
 * @title Tellor Transfer
 * @dev Contains the methods related to transfers and ERC20, its storage and hashes of tellor variable
 * that are used to save gas on transactions.
 */
contract TellorTransfer is TellorStorage, TellorVariables {
    using SafeMath for uint256;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

    /*Functions*/

    /**
     * @dev Allows for a transfer of tokens to _to
     * @param _to The address to send tokens to
     * @param _amount The amount of tokens to send
     */
    function transfer(address _to, uint256 _amount)
        public
        returns (bool success)
    {
        _doTransfer(msg.sender, _to, _amount);
        return true;
    }

    /**
     * @notice Send _amount tokens to _to from _from on the condition it
     * is approved by _from
     * @param _from The address holding the tokens being transferred
     * @param _to The address of the recipient
     * @param _amount The amount of tokens to be transferred
     */
    function transferFrom(
        address _from,
        address _to,
        uint256 _amount
    ) public returns (bool success) {
        require(
            _allowances[_from][msg.sender] >= _amount,
            "Allowance is wrong"
        );
        _allowances[_from][msg.sender] -= _amount;
        _doTransfer(_from, _to, _amount);
        return true;
    }

    /**
     * @dev This function approves a _spender an _amount of tokens to use
     * @param _spender address
     * @param _amount amount the spender is being approved for
     * @return true if spender approved successfully
     */
    function approve(address _spender, uint256 _amount) public returns (bool) {
        require(
            msg.sender != address(0),
            "ERC20: approve from the zero address"
        );
        require(_spender != address(0), "ERC20: approve to the zero address");

        _allowances[msg.sender][_spender] = _amount;
        emit Approval(msg.sender, _spender, _amount);
        return true;
    }

    /**
     * @dev Getter function for remaining spender balance
     * @param _user address of party with the balance
     * @param _spender address of spender of parties said balance
     * @return Returns the remaining allowance of tokens granted to the _spender from the _user
     */
    function allowance(address _user, address _spender)
        public
        view
        returns (uint256)
    {
        return _allowances[_user][_spender];
    }

    /**
     * @dev Completes transfers by updating the balances on the current block number
     * and ensuring the amount does not contain tokens staked for mining
     * @param _from address to transfer from
     * @param _to address to transfer to
     * @param _amount to transfer
     */
    function _doTransfer(
        address _from,
        address _to,
        uint256 _amount
    ) internal {
        require(_amount != 0, "Tried to send non-positive amount");
        require(_to != address(0), "Receiver is 0 address");
        require(
            allowedToTrade(_from, _amount),
            "Should have sufficient balance to trade"
        );
        uint256 previousBalance = balanceOf(_from);
        updateBalanceAtNow(_from, previousBalance - _amount);
        previousBalance = balanceOf(_to);
        require(
            previousBalance + _amount >= previousBalance,
            "Overflow happened"
        ); // Check for overflow
        updateBalanceAtNow(_to, previousBalance + _amount);
        emit Transfer(_from, _to, _amount);
    }

    /**
     * @dev Helps swap the old Tellor contract Tokens to the new one
     * @param _to is the adress to send minted amount to
     * @param _amount is the amount of TRB to send
     */
    function _doMint(address _to, uint256 _amount) internal {
        require(_amount != 0, "Tried to mint non-positive amount");
        require(_to != address(0), "Receiver is 0 address");
        uint256 previousBalance = balanceOf(_to);
        require(
            previousBalance + _amount >= previousBalance,
            "Overflow happened"
        ); // Check for overflow
        uint256 previousSupply = uints[_TOTAL_SUPPLY];
        require(
            previousSupply + _amount >= previousSupply,
            "Overflow happened"
        );
        uints[_TOTAL_SUPPLY] += _amount;
        updateBalanceAtNow(_to, previousBalance + _amount);
        emit Transfer(address(0), _to, _amount);
    }

    /**
     * @dev Helps burn TRB Tokens
     * @param _from is the adress to burn or remove TRB amount
     * @param _amount is the amount of TRB to burn
     */
    function _doBurn(address _from, uint256 _amount) internal {
        if (_amount == 0) return;
        uint256 previousBalance = balanceOf(_from);
        require(
            previousBalance - _amount <= previousBalance,
            "Overflow happened"
        ); // Check for overflow
        uint256 previousSupply = uints[_TOTAL_SUPPLY];
        require(
            previousSupply - _amount <= previousSupply,
            "Overflow happened"
        );
        updateBalanceAtNow(_from, previousBalance - _amount);
        uints[_TOTAL_SUPPLY] -= _amount;
    }

    /**
     * @dev Gets balance of owner specified
     * @param _user is the owner address used to look up the balance
     * @return Returns the balance associated with the passed in _user
     */
    function balanceOf(address _user) public view returns (uint256) {
        return balanceOfAt(_user, block.number);
    }

    /**
     * @dev Queries the balance of _user at a specific _blockNumber
     * @param _user The address from which the balance will be retrieved
     * @param _blockNumber The block number when the balance is queried
     * @return The balance at _blockNumber specified
     */
    function balanceOfAt(address _user, uint256 _blockNumber)
        public
        view
        returns (uint256)
    {
        TellorStorage.Checkpoint[] storage checkpoints = balances[_user];
        if (
            checkpoints.length == 0 || checkpoints[0].fromBlock > _blockNumber
        ) {
            return 0;
        } else {
            if (_blockNumber >= checkpoints[checkpoints.length - 1].fromBlock)
                return checkpoints[checkpoints.length - 1].value;
            // Binary search of the value in the array
            uint256 min = 0;
            uint256 max = checkpoints.length - 2;
            while (max > min) {
                uint256 mid = (max + min + 1) / 2;
                if (checkpoints[mid].fromBlock == _blockNumber) {
                    return checkpoints[mid].value;
                } else if (checkpoints[mid].fromBlock < _blockNumber) {
                    min = mid;
                } else {
                    max = mid - 1;
                }
            }
            return checkpoints[min].value;
        }
    }

    /**
     * @dev This function returns whether or not a given user is allowed to trade a given amount
     * and removing the staked amount from their balance if they are staked
     * @param _user address of user
     * @param _amount to check if the user can spend
     * @return true if they are allowed to spend the amount being checked
     */
    function allowedToTrade(address _user, uint256 _amount)
        public
        view
        returns (bool)
    {
        if (
            stakerDetails[_user].currentStatus != 0 &&
            stakerDetails[_user].currentStatus < 5
        ) {
            //Subtracts the stakeAmount from balance if the _user is staked
            if (balanceOf(_user) - uints[_STAKE_AMOUNT] >= _amount) {
                return true;
            }
            return false;
        }
        return (balanceOf(_user) >= _amount);
    }

    /**
     * @dev Updates balance for from and to on the current block number via doTransfer
     * @param _value is the new balance
     */
    function updateBalanceAtNow(address _user, uint256 _value) public {
        Checkpoint[] storage checkpoints = balances[_user];
        if (
            checkpoints.length == 0 ||
            checkpoints[checkpoints.length - 1].fromBlock != block.number
        ) {
            checkpoints.push(
                TellorStorage.Checkpoint({
                    fromBlock: uint128(block.number),
                    value: uint128(_value)
                })
            );
        } else {
            TellorStorage.Checkpoint storage oldCheckPoint =
                checkpoints[checkpoints.length - 1];
            oldCheckPoint.value = uint128(_value);
        }
    }
}

File 8 of 9 : TellorStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;

/**
 * @title Tellor Oracle Storage Library
 * @dev Contains all the variables/structs used by Tellor
 */

contract TellorStorage {
    //Internal struct for use in proof-of-work submission
    struct Details {
        uint256 value;
        address miner;
    }

    struct Dispute {
        bytes32 hash; //unique hash of dispute: keccak256(_miner,_requestId,_timestamp)
        int256 tally; //current tally of votes for - against measure
        bool executed; //is the dispute settled
        bool disputeVotePassed; //did the vote pass?
        bool isPropFork; //true for fork proposal NEW
        address reportedMiner; //miner who submitted the 'bad value' will get disputeFee if dispute vote fails
        address reportingParty; //miner reporting the 'bad value'-pay disputeFee will get reportedMiner's stake if dispute vote passes
        address proposedForkAddress; //new fork address (if fork proposal)
        mapping(bytes32 => uint256) disputeUintVars;
        //Each of the variables below is saved in the mapping disputeUintVars for each disputeID
        //e.g. TellorStorageStruct.DisputeById[disputeID].disputeUintVars[keccak256("requestId")]
        //These are the variables saved in this mapping:
        // uint keccak256("requestId");//apiID of disputed value
        // uint keccak256("timestamp");//timestamp of disputed value
        // uint keccak256("value"); //the value being disputed
        // uint keccak256("minExecutionDate");//7 days from when dispute initialized
        // uint keccak256("numberOfVotes");//the number of parties who have voted on the measure
        // uint keccak256("blockNumber");// the blocknumber for which votes will be calculated from
        // uint keccak256("minerSlot"); //index in dispute array
        // uint keccak256("fee"); //fee paid corresponding to dispute
        mapping(address => bool) voted; //mapping of address to whether or not they voted
    }

    struct StakeInfo {
        uint256 currentStatus; //0-not Staked, 1=Staked, 2=LockedForWithdraw 3= OnDispute 4=ReadyForUnlocking 5=Unlocked
        uint256 startDate; //stake start date
    }

    //Internal struct to allow balances to be queried by blocknumber for voting purposes
    struct Checkpoint {
        uint128 fromBlock; // fromBlock is the block number that the value was generated from
        uint128 value; // value is the amount of tokens at a specific block number
    }

    struct Request {
        uint256[] requestTimestamps; //array of all newValueTimestamps requested
        mapping(bytes32 => uint256) apiUintVars;
        //Each of the variables below is saved in the mapping apiUintVars for each api request
        //e.g. requestDetails[_requestId].apiUintVars[keccak256("totalTip")]
        //These are the variables saved in this mapping:
        // uint keccak256("requestQPosition"); //index in requestQ
        // uint keccak256("totalTip");//bonus portion of payout
        mapping(uint256 => uint256) minedBlockNum; //[apiId][minedTimestamp]=>block.number
        //This the time series of finalValues stored by the contract where uint UNIX timestamp is mapped to value
        mapping(uint256 => uint256) finalValues;
        mapping(uint256 => bool) inDispute; //checks if API id is in dispute or finalized.
        mapping(uint256 => address[5]) minersByValue;
        mapping(uint256 => uint256[5]) valuesByTimestamp;
    }

    uint256[51] requestQ; //uint50 array of the top50 requests by payment amount
    uint256[] public newValueTimestamps; //array of all timestamps requested
    //Address fields in the Tellor contract are saved the addressVars mapping
    //e.g. addressVars[keccak256("tellorContract")] = address
    //These are the variables saved in this mapping:
    // address keccak256("tellorContract");//Tellor address
    // address  keccak256("_owner");//Tellor Owner address
    // address  keccak256("_deity");//Tellor Owner that can do things at will
    // address  keccak256("pending_owner"); // The proposed new owner
    //uint fields in the Tellor contract are saved the uintVars mapping
    //e.g. uintVars[keccak256("decimals")] = uint
    //These are the variables saved in this mapping:
    // keccak256("decimals");    //18 decimal standard ERC20
    // keccak256("disputeFee");//cost to dispute a mined value
    // keccak256("disputeCount");//totalHistoricalDisputes
    // keccak256("total_supply"); //total_supply of the token in circulation
    // keccak256("stakeAmount");//stakeAmount for miners (we can cut gas if we just hardcoded it in...or should it be variable?)
    // keccak256("stakerCount"); //number of parties currently staked
    // keccak256("timeOfLastNewValue"); // time of last challenge solved
    // keccak256("difficulty"); // Difficulty of current block
    // keccak256("currentTotalTips"); //value of highest api/timestamp PayoutPool
    // keccak256("currentRequestId"); //API being mined--updates with the ApiOnQ Id
    // keccak256("requestCount"); // total number of requests through the system
    // keccak256("slotProgress");//Number of miners who have mined this value so far
    // keccak256("miningReward");//Mining Reward in PoWo tokens given to all miners per value
    // keccak256("timeTarget"); //The time between blocks (mined Oracle values)
    // keccak256("_tblock"); //
    // keccak256("runningTips"); // VAriable to track running tips
    // keccak256("currentReward"); // The current reward
    // keccak256("devShare"); // The amount directed towards th devShare
    // keccak256("currentTotalTips"); //

    //This is a boolean that tells you if a given challenge has been completed by a given miner
    mapping(uint256 => uint256) requestIdByTimestamp; //minedTimestamp to apiId
    mapping(uint256 => uint256) requestIdByRequestQIndex; //link from payoutPoolIndex (position in payout pool array) to apiId
    mapping(uint256 => Dispute) public disputesById; //disputeId=> Dispute details
    mapping(bytes32 => uint256) public requestIdByQueryHash; // api bytes32 gets an id = to count of requests array
    mapping(bytes32 => uint256) public disputeIdByDisputeHash; //maps a hash to an ID for each dispute
    mapping(bytes32 => mapping(address => bool)) public minersByChallenge;
    Details[5] public currentMiners; //This struct is for organizing the five mined values to find the median
    mapping(address => StakeInfo) stakerDetails; //mapping from a persons address to their staking info
    mapping(uint256 => Request) requestDetails;

    mapping(bytes32 => uint256) public uints;
    mapping(bytes32 => address) public addresses;
    mapping(bytes32 => bytes32) public bytesVars;

    //ERC20 storage
    mapping(address => Checkpoint[]) public balances;
    mapping(address => mapping(address => uint256)) public _allowances;

    //Migration storage
    mapping(address => bool) public migrated;
}

File 9 of 9 : TellorVariables.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;

// Helper contract to store hashes of variables
contract TellorVariables {
    bytes32 constant _BLOCK_NUMBER =
        0x4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c; //keccak256("_BLOCK_NUMBER");
    bytes32 constant _CURRENT_CHALLENGE =
        0xd54702836c9d21d0727ffacc3e39f57c92b5ae0f50177e593bfb5ec66e3de280; //keccak256("_CURRENT_CHALLENGE");
    bytes32 constant _CURRENT_REQUESTID =
        0xf5126bb0ac211fbeeac2c0e89d4c02ac8cadb2da1cfb27b53c6c1f4587b48020; //keccak256("_CURRENT_REQUESTID");
    bytes32 constant _CURRENT_REWARD =
        0xd415862fd27fb74541e0f6f725b0c0d5b5fa1f22367d9b78ec6f61d97d05d5f8; //keccak256("_CURRENT_REWARD");
    bytes32 constant _CURRENT_TOTAL_TIPS =
        0x09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a; //keccak256("_CURRENT_TOTAL_TIPS");
    bytes32 constant _DEITY =
        0x5fc094d10c65bc33cc842217b2eccca0191ff24148319da094e540a559898961; //keccak256("_DEITY");
    bytes32 constant _DIFFICULTY =
        0xf758978fc1647996a3d9992f611883adc442931dc49488312360acc90601759b; //keccak256("_DIFFICULTY");
    bytes32 constant _DISPUTE_COUNT =
        0x310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d7; //keccak256("_DISPUTE_COUNT");
    bytes32 constant _DISPUTE_FEE =
        0x675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc; //keccak256("_DISPUTE_FEE");
    bytes32 constant _DISPUTE_ROUNDS =
        0x6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a923; //keccak256("_DISPUTE_ROUNDS");
    bytes32 constant _FEE =
        0x1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc409; //keccak256("FEE");
    bytes32 constant _MIN_EXECUTION_DATE =
        0x46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d28; //keccak256("_MIN_EXECUTION_DATE");
    bytes32 constant _MINER_SLOT =
        0x6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d; //keccak256("_MINER_SLOT");
    bytes32 constant _NUM_OF_VOTES =
        0x1da378694063870452ce03b189f48e04c1aa026348e74e6c86e10738514ad2c4; //keccak256("_NUM_OF_VOTES");
    bytes32 constant _OLD_TELLOR =
        0x56e0987db9eaec01ed9e0af003a0fd5c062371f9d23722eb4a3ebc74f16ea371; //keccak256("_OLD_TELLOR");
    bytes32 constant _ORIGINAL_ID =
        0xed92b4c1e0a9e559a31171d487ecbec963526662038ecfa3a71160bd62fb8733; //keccak256("_ORIGINAL_ID");
    bytes32 constant _OWNER =
        0x7a39905194de50bde334d18b76bbb36dddd11641d4d50b470cb837cf3bae5def; //keccak256("_OWNER");
    bytes32 constant _PAID =
        0x29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc; //keccak256("_PAID");
    bytes32 constant _PENDING_OWNER =
        0x7ec081f029b8ac7e2321f6ae8c6a6a517fda8fcbf63cabd63dfffaeaafa56cc0; //keccak256("_PENDING_OWNER");
    bytes32 constant _REQUEST_COUNT =
        0x3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c865; //keccak256("_REQUEST_COUNT");
    bytes32 constant _REQUEST_ID =
        0x9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f; //keccak256("_REQUEST_ID");
    bytes32 constant _REQUEST_Q_POSITION =
        0xf68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa1; //keccak256("_REQUEST_Q_POSITION");
    bytes32 constant _SLOT_PROGRESS =
        0xdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b082; //keccak256("_SLOT_PROGRESS");
    bytes32 constant _STAKE_AMOUNT =
        0x5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc97; //keccak256("_STAKE_AMOUNT");
    bytes32 constant _STAKE_COUNT =
        0x10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b; //keccak256("_STAKE_COUNT");
    bytes32 constant _T_BLOCK =
        0xf3b93531fa65b3a18680d9ea49df06d96fbd883c4889dc7db866f8b131602dfb; //keccak256("_T_BLOCK");
    bytes32 constant _TALLY_DATE =
        0xf9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a6; //keccak256("_TALLY_DATE");
    bytes32 constant _TARGET_MINERS =
        0x0b8561044b4253c8df1d9ad9f9ce2e0f78e4bd42b2ed8dd2e909e85f750f3bc1; //keccak256("_TARGET_MINERS");
    bytes32 constant _TELLOR_CONTRACT =
        0x0f1293c916694ac6af4daa2f866f0448d0c2ce8847074a7896d397c961914a08; //keccak256("_TELLOR_CONTRACT");
    bytes32 constant _TELLOR_GETTERS =
        0xabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a; //keccak256("_TELLOR_GETTERS");
    bytes32 constant _TIME_OF_LAST_NEW_VALUE =
        0x2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f1; //keccak256("_TIME_OF_LAST_NEW_VALUE");
    bytes32 constant _TIME_TARGET =
        0xd4f87b8d0f3d3b7e665df74631f6100b2695daa0e30e40eeac02172e15a999e1; //keccak256("_TIME_TARGET");
    bytes32 constant _TIMESTAMP =
        0x2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5; //keccak256("_TIMESTAMP");
    bytes32 constant _TOTAL_SUPPLY =
        0xe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb7380160; //keccak256("_TOTAL_SUPPLY");
    bytes32 constant _TOTAL_TIP =
        0x1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d; //keccak256("_TOTAL_TIP");
    bytes32 constant _VALUE =
        0x9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f47; //keccak256("_VALUE");
    bytes32 constant _EIP_SLOT =
        0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3;
}

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

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_disputeID","type":"uint256"},{"indexed":false,"internalType":"int256","name":"_result","type":"int256"},{"indexed":true,"internalType":"address","name":"_reportedMiner","type":"address"},{"indexed":false,"internalType":"address","name":"_reportingParty","type":"address"},{"indexed":false,"internalType":"bool","name":"_active","type":"bool"}],"name":"DisputeVoteTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_currentChallenge","type":"bytes32"},{"indexed":false,"internalType":"uint256[5]","name":"_currentRequestId","type":"uint256[5]"},{"indexed":false,"internalType":"uint256","name":"_difficulty","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalTips","type":"uint256"}],"name":"NewChallenge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_disputeId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"_miner","type":"address"}],"name":"NewDispute","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"}],"name":"NewStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[5]","name":"_requestId","type":"uint256[5]"},{"indexed":false,"internalType":"uint256","name":"_time","type":"uint256"},{"indexed":false,"internalType":"uint256[5]","name":"_value","type":"uint256[5]"},{"indexed":false,"internalType":"uint256","name":"_totalTips","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"_currentChallenge","type":"bytes32"}],"name":"NewValue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_miner","type":"address"},{"indexed":false,"internalType":"string","name":"_nonce","type":"string"},{"indexed":false,"internalType":"uint256[5]","name":"_requestId","type":"uint256[5]"},{"indexed":false,"internalType":"uint256[5]","name":"_value","type":"uint256[5]"},{"indexed":true,"internalType":"bytes32","name":"_currentChallenge","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_slot","type":"uint256"}],"name":"NonceSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"}],"name":"StakeWithdrawRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"}],"name":"StakeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"_requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tip","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalTips","type":"uint256"}],"name":"TipAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_disputeID","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_position","type":"bool"},{"indexed":true,"internalType":"address","name":"_voter","type":"address"},{"indexed":true,"internalType":"uint256","name":"_voteWeight","type":"uint256"}],"name":"Voted","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"_allowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint256","name":"_tip","type":"uint256"}],"name":"addTip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"addresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"allowedToTrade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_blockNumber","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balances","outputs":[{"internalType":"uint128","name":"fromBlock","type":"uint128"},{"internalType":"uint128","name":"value","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"uint256","name":"_minerIndex","type":"uint256"}],"name":"beginDispute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"bytesVars","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tGetters","type":"address"}],"name":"changeTellorGetters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"currentMiners","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"miner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"disputeIdByDisputeHash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"disputesById","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"int256","name":"tally","type":"int256"},{"internalType":"bool","name":"executed","type":"bool"},{"internalType":"bool","name":"disputeVotePassed","type":"bool"},{"internalType":"bool","name":"isPropFork","type":"bool"},{"internalType":"address","name":"reportedMiner","type":"address"},{"internalType":"address","name":"reportingParty","type":"address"},{"internalType":"address","name":"proposedForkAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"migrated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"minersByChallenge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"newValueTimestamps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestIdByQueryHash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestStakingWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_nonce","type":"string"},{"internalType":"uint256[5]","name":"_requestIds","type":"uint256[5]"},{"internalType":"uint256[5]","name":"_values","type":"uint256[5]"}],"name":"submitMiningSolution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"}],"name":"tallyVotes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"uints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"}],"name":"unlockDisputeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"updateBalanceAtNow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateMinDisputeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"},{"internalType":"bool","name":"_supportsDispute","type":"bool"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawStake","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50615f5e80620000216000396000f3fe6080604052600436106101e35760003560e01c806370a0823111610102578063b59e14d411610095578063d01f4d9e11610064578063d01f4d9e146108f7578063d67dcbc514610921578063db085beb14610967578063dd62ed3e146109ee576101e3565b8063b59e14d4146107ff578063bed9d86114610829578063c9d27afe1461083e578063cbf1304d14610870576101e3565b806390e5b235116100d157806390e5b23514610734578063999cf26c146107495780639a01ca131461078f578063a9059cbb146107b9576101e3565b806370a0823114610679578063752d49a1146106b95780638581af19146106e95780638fd3ab801461071f576101e3565b8063453990161161017a5780634ee2cd7e116101495780634ee2cd7e1461058c5780635700242c146105d257806362dd1d2a146105fc578063699f200f14610626576101e3565b8063453990161461049c57806348b18e54146104dc5780634ba0a5ee146105225780634d318b0e14610562576101e3565b806323b872dd116101b657806323b872dd1461038c57806328449c3a146103dc5780634350283e146103f1578063438c0aa314610472576101e3565b8063024c2ddd14610269578063095ea7b3146102c35780630d2d76a21461031d5780631fd2236414610334575b7fabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a600090815260476020527f9a17b40120dc8667cacbaf2c16d2d82572643f21bfde07d6cf294bd1927356dc5473ffffffffffffffffffffffffffffffffffffffff169061025082610a36565b5090503d6000803e808015610264573d6000f35b3d6000fd5b34801561027557600080fd5b506102b16004803603604081101561028c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610ab3565b60408051918252519081900360200190f35b3480156102cf57600080fd5b50610309600480360360408110156102e657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610ad0565b604080519115158252519081900360200190f35b34801561032957600080fd5b50610332610c09565b005b34801561034057600080fd5b5061035e6004803603602081101561035757600080fd5b5035610c1c565b6040805192835273ffffffffffffffffffffffffffffffffffffffff90911660208301528051918290030190f35b34801561039857600080fd5b50610309600480360360608110156103af57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610c54565b3480156103e857600080fd5b50610332610d3f565b3480156103fd57600080fd5b50610332600480360361016081101561041557600080fd5b81019060208101813564010000000081111561043057600080fd5b82018360208201111561044257600080fd5b8035906020019184600183028401116401000000008311171561046457600080fd5b919350915060a08101610e75565b34801561047e57600080fd5b506102b16004803603602081101561049557600080fd5b503561104e565b3480156104a857600080fd5b50610332600480360360208110156104bf57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661106f565b3480156104e857600080fd5b50610309600480360360408110156104ff57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff1661116a565b34801561052e57600080fd5b506103096004803603602081101561054557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661118a565b34801561056e57600080fd5b506103326004803603602081101561058557600080fd5b503561119f565b34801561059857600080fd5b506102b1600480360360408110156105af57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356114a0565b3480156105de57600080fd5b506102b1600480360360208110156105f557600080fd5b5035611711565b34801561060857600080fd5b506102b16004803603602081101561061f57600080fd5b5035611723565b34801561063257600080fd5b506106506004803603602081101561064957600080fd5b5035611735565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561068557600080fd5b506102b16004803603602081101561069c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661175d565b3480156106c557600080fd5b50610332600480360360408110156106dc57600080fd5b5080359060200135611769565b3480156106f557600080fd5b506103326004803603606081101561070c57600080fd5b50803590602081013590604001356119e8565b34801561072b57600080fd5b50610332612386565b34801561074057600080fd5b5061033261238f565b34801561075557600080fd5b506103096004803603604081101561076c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356124a9565b34801561079b57600080fd5b50610332600480360360208110156107b257600080fd5b5035612586565b3480156107c557600080fd5b50610309600480360360408110156107dc57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612d27565b34801561080b57600080fd5b506102b16004803603602081101561082257600080fd5b5035612d3d565b34801561083557600080fd5b50610332612d4f565b34801561084a57600080fd5b506103326004803603604081101561086157600080fd5b50803590602001351515612e68565b34801561087c57600080fd5b506108b66004803603604081101561089357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135613112565b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b34801561090357600080fd5b506102b16004803603602081101561091a57600080fd5b503561316b565b34801561092d57600080fd5b506103326004803603604081101561094457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561317d565b34801561097357600080fd5b506109916004803603602081101561098a57600080fd5b5035613307565b604080519889526020890197909752941515878701529215156060870152901515608086015273ffffffffffffffffffffffffffffffffffffffff90811660a086015290811660c08501521660e083015251908190036101000190f35b3480156109fa57600080fd5b506102b160048036036040811015610a1157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516613370565b600060608273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610aa3576040519150601f19603f3d011682016040523d82523d6000602084013e610aa8565b606091505b509094909350915050565b604a60209081526000928352604080842090915290825290205481565b600033610b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615ee06024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316610b94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615df16022913960400191505060405180910390fd5b336000818152604a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b610c12336133a8565b610c1a61238f565b565b603a8160058110610c2c57600080fd5b60020201805460019091015490915073ffffffffffffffffffffffffffffffffffffffff1682565b73ffffffffffffffffffffffffffffffffffffffff83166000908152604a60209081526040808320338452909152812054821115610cf357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f416c6c6f77616e63652069732077726f6e670000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152604a60209081526040808320338452909152902080548390039055610d358484846135ba565b5060019392505050565b3360009081526044602052604090208054600114610dbe57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4d696e6572206973206e6f74207374616b656400000000000000000000000000604482015290519081900360640190fd5b60028155620151804206420360018201557f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b60005260466020527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055610e4761238f565b60405133907f453865710d0cb4b14ad25de371c860da196368895daa9662e5087711d14daecf90600090a250565b6040805133602080830191909152825180830382018152918301835281519181019190912060008181526046909252919020541580610ec857506000818152604660205260409020546103844291909103115b610f1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615da4602a913960400191505060405180910390fd5b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b08260005260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed249254600414610fae57610fae85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137fd92505050565b6000818152604660209081526040918290204290558151601f870182900482028101820190925285825261104791908790879081908401838280828437600092019190915250506040805160a081810190925292508791506005908390839080828437600092019190915250506040805160a0818101909252915086906005908390839080828437600092019190915250613b96915050565b5050505050565b6033818154811061105e57600080fd5b600091825260209091200154905081565b7f5fc094d10c65bc33cc842217b2eccca0191ff24148319da094e540a55989896160005260476020527f437dd27c2043efdfef03344e9331c924985f7bd1752abef5ea93bdbfed6851005473ffffffffffffffffffffffffffffffffffffffff1633146110db57600080fd5b7fabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a60005260476020527f9a17b40120dc8667cacbaf2c16d2d82572643f21bfde07d6cf294bd1927356dc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b603960209081526000928352604080842090915290825290205460ff1681565b604b6020526000908152604090205460ff1681565b6000818152603660205260409020600281015460ff161561120b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e9e6021913960400191505060405180910390fd5b7f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2860009081526005820160205260409020544210156112ab57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b600381015473ffffffffffffffffffffffffffffffffffffffff1661133157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706f7274696e672050617274792069732061646472657373203000000000604482015290519081900360640190fd5b6001810154600081131561136e576002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600282015462010000900460ff166113c15760028201546301000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526044602052604090208054600314156113bf57600481555b505b7ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a660009081526005830160209081526040918290204290556002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117908190556003850154835185815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352610100820460ff1615158385015292516301000000909104929092169185917f21459c2f5447ebcf83a7f0a238c32c71076faef0d12295e771c0cb1e10434739919081900360600190a3505050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152604960205260408120805415806114fc575082816000815481106114dc57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff16115b1561150b576000915050610c03565b805481907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061153b57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1683106115ca57805481907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061158f57fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169150610c039050565b80546000907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe015b818111156116c857600060026001838501010490508584828154811061161457fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1614156116825783818154811061164457fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169450610c039350505050565b8584828154811061168f57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1610156116bb578092506116c2565b6001810391505b506115f2565b8282815481106116d457fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169350610c0392505050565b60376020526000908152604090205481565b60486020526000908152604090205481565b60476020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6000610c0382436114a0565b816117d557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f5265717565737449642069732030000000000000000000000000000000000000604482015290519081900360640190fd5b8061184157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f5469702073686f756c642062652067726561746572207468616e203000000000604482015290519081900360640190fd5b7f3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c86560005260466020527f7119b9afaa3bda0901ffe121c1535f50cd6d0d09df5d29eb1cb16c8ab47a55d654600101828114156118e9577f3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c86560005260466020527f7119b9afaa3bda0901ffe121c1535f50cd6d0d09df5d29eb1cb16c8ab47a55d6819055611957565b80831061195757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f526571756573744964206973206e6f74206c657373207468616e20636f756e74604482015290519081900360640190fd5b6119613383614433565b61196b83836145db565b60008381526045602090815260408083207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d8452600101825291829020548251858152918201528151859233927fd32134405b68f6f7220f9c38ae310df1b648d16188006768d45be2f7c24e8820929081900390910190a3505050565b60008381526045602090815260408083208584526002810190925290912054611a7257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d696e656420626c6f636b206973203000000000000000000000000000000000604482015290519081900360640190fd5b60058210611ae157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4d696e657220696e6465782069732077726f6e67000000000000000000000000604482015290519081900360640190fd5b60008381526005808301602052604082209084908110611afd57fe5b0154604080517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084901b1660208083019190915260348201899052605480830189905283518084039091018152607490920183528151918101919091207f1ce2382bc92689b00ba121fa5a411aa976168affdd8ac143a69035dd984b3b6a80546001019081905560008281526038909352929091205473ffffffffffffffffffffffffffffffffffffffff9093169350918015611bfa5760008281526036602090815260408083207fed92b4c1e0a9e559a31171d487ecbec963526662038ecfa3a71160bd62fb873384526005019091529020819055611c0e565b506000828152603860205260409020819055805b60008181526036602081815260408084207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a92385526005018083528185208054600101908190558686529383528151808401859052825180820385018152908301835280519084012085529091529091208390558190838214611e5657600082815260366020818152604080842081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8701818501528251808203850181529083018352805190840120855260059081018352818520548086529383528185207f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2886520190915290912054421015611d8757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4469737075746520697320616c7265616479206f70656e000000000000000000604482015290519081900360640190fd5b60008181526036602052604090206002015460ff1615611e545760008181526036602090815260408083207ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a684526005019091529020546201518042919091031115611e5457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b505b60008860021415611ef9575060008a81526045602090815260408083207f310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d78452600190810183529083208054909101908190557f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc97909252604690527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be5402611f48565b507f675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc60005260466020527f3e5522f19747f0f285b96ded572ac4128c3a764aea9f44058dc0afc9dda449865481025b85603660008781526020019081526020016000206000018190555060006036600087815260200190815260200160002060020160026101000a81548160ff021916908315150217905550866036600087815260200190815260200160002060020160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550336036600087815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006036600087815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006036600087815260200190815260200160002060020160006101000a81548160ff02191690831515021790555060006036600087815260200190815260200160002060020160016101000a81548160ff021916908315150217905550600060366000878152602001908152602001600020600101819055508a6036600087815260200190815260200160002060050160007f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60001b815260200190815260200160002081905550896036600087815260200190815260200160002060050160007f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e560001b8152602001908152602001600020819055508760060160008b815260200190815260200160002089600581106121ca57fe5b015460008681526036602090815260408083207f9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f478452600501909152808220929092557f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2881528181206202a3008502420190557f4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c81528181204390557f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d81528181208b90557f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098152208190556122c13330836135ba565b88600214156123115760008a8152600489016020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560038b019091528120555b73ffffffffffffffffffffffffffffffffffffffff87166000818152604460209081526040918290206003905581518d81529081019290925280518d9288927feceec1aebf67772b2440120c4b4dc913a1fe1b865509219f9456785c23b9da6492918290030190a35050505050505050505050565b610c1a3361488b565b60466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be547f2e2f0a18eb55ef91e37921b3810d7feeef7a855ddc7f4f4249ef03d7b887ae31547f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b6000527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd35461245a9067d02ab486cedc0000906103e890849061243d908290614a5f565b6103e80286028161244a57fe5b048161245257fe5b048403614a77565b7f675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc60005260466020527f3e5522f19747f0f285b96ded572ac4128c3a764aea9f44058dc0afc9dda44986555050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526044602052604081205415801590612502575073ffffffffffffffffffffffffffffffffffffffff83166000908152604460205260409020546005115b15612573577f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be54829061255d8561175d565b031061256b57506001610c03565b506000610c03565b8161257d8461175d565b10159392505050565b600081815260366020818152604080842054845260388252808420548085529282528084207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a9238552600501808352818520548251808501919091528251808203850181529083018352805190840120855290915290912054806126065750805b60008281526036602090815260408083208484528184207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a92385526005820190935292205480612653575060015b7f29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc6000908152600584016020526040812054156126f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f616c72656164792070616964206f757400000000000000000000000000000000604482015290519081900360640190fd5b7ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a660009081526005840160205260409020546201518042919091031161279857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b6002848101546301000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526044602090815260408083207f29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc84526005890190925290912060019081905591850154909161010090910460ff16151514156129ef57620151804206420360018201557f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b60005260466020527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01905561289b61238f565b80546004141561292e5760058155600285015460038601547f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be546129299273ffffffffffffffffffffffffffffffffffffffff630100000090910481169216906135ba565b600081555b60005b838110156129e9576040805182860360208083019190915282518083038201815291830183528151918101919091206000908152600589019091522054925082612979578792505b600083815260366020908152604080832060038101547f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098552600582019093529220546129e091309173ffffffffffffffffffffffffffffffffffffffff909116906135ba565b50600101612931565b50612c53565b600181557f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60009081526005860160208181526040808420548452604582528084207f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d8552929091529091205460021415612ace577f9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f4760009081526005870160209081526040808320547f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5845281842054845260038501909252909120555b7f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5600090815260058701602090815260408083205483526004840190915290205460ff16151560011415612b83577f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e56000908152600587016020908152604080832054835260048401909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b60005b84811015612c5057604080518287036020808301919091528251808303820181529183018352815191810191909120600090815260058a01909152205493508315612bdc57600084815260366020526040902095505b600286015460008581526036602090815260408083207f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098452600501909152902054612c48913091630100000090910473ffffffffffffffffffffffffffffffffffffffff16906135ba565b600101612b86565b50505b7f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d600090815260058601602052604090205460021415612d1d577f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60009081526005860160209081526040808320548352604582528083207f310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d78452600101909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b5050505050505050565b6000612d343384846135ba565b50600192915050565b60466020526000908152604090205481565b336000908152604460205260409020600181015462093a80906201518042064203031015612dde57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f372064617973206469646e277420706173730000000000000000000000000000604482015290519081900360640190fd5b8054600214612e38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615dce6023913960400191505060405180910390fd5b600080825560405133917f4a7934670bd8304e7da22378be1368f7c4fef17c5aee81804beda8638fe428ec91a250565b60008281526036602090815260408083207f4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c845260058101909252822054909190612eb49033906114a0565b33600090815260068401602052604090205490915060ff16151560011415612f3d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f53656e6465722068617320616c726561647920766f7465640000000000000000604482015290519081900360640190fd5b80612fa957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f557365722062616c616e63652069732030000000000000000000000000000000604482015290519081900360640190fd5b336000908152604460205260409020546003141561302857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d696e657220697320756e646572206469737075746500000000000000000000604482015290519081900360640190fd5b336000908152600683016020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091557f1da378694063870452ce03b189f48e04c1aa026348e74e6c86e10738514ad2c48452600586019092529091208054909101905582156130bb5760018201546130b19082614a86565b60018301556130d0565b60018201546130ca9082614ab1565b60018301555b60408051841515815290518291339187917f911ef2e98570b1d96c0e8ef81107a33d5b8e844aeb8f9710f9bc76c3b3fef40e919081900360200190a450505050565b6049602052816000526040600020818154811061312e57600080fd5b6000918252602090912001546fffffffffffffffffffffffffffffffff808216935070010000000000000000000000000000000090910416905082565b60386020526000908152604090205481565b73ffffffffffffffffffffffffffffffffffffffff82166000908152604960205260409020805415806131fe57508054439082907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106131dd57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1614155b156132945760408051808201909152436fffffffffffffffffffffffffffffffff90811682528381166020808401918252845460018101865560008681529190912093519301805491517fffffffffffffffffffffffffffffffff000000000000000000000000000000009092169383169390931782167001000000000000000000000000000000009190921602179055613302565b805460009082907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106132c757fe5b600091825260209091200180546fffffffffffffffffffffffffffffffff808616700100000000000000000000000000000000029116179055505b505050565b603660205260009081526040902080546001820154600283015460038401546004909401549293919260ff8083169361010084048216936201000081049092169273ffffffffffffffffffffffffffffffffffffffff6301000000909304831692918216911688565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152604a6020908152604080832093909416825291909152205490565b7f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be546133fc8261175d565b1015613453576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615e7c6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526044602052604090205415806134aa575073ffffffffffffffffffffffffffffffffffffffff81166000908152604460205260409020546002145b61351557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d696e657220697320696e207468652077726f6e672073746174650000000000604482015290519081900360640190fd5b7fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd38054600190810190915560408051808201825282815262015180429081069003602082810191825273ffffffffffffffffffffffffffffffffffffffff8616600081815260449092528482209351845591519290940191909155905190917f46d8ab1385f70e5a3673e97c23c764f7600f7ed7a09b6687deae7131d51752e291a250565b80613610576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e5b6021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661369257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5265636569766572206973203020616464726573730000000000000000000000604482015290519081900360640190fd5b61369c83826124a9565b6136f1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180615e346027913960400191505060405180910390fd5b60006136fc8461175d565b905061370a8483830361317d565b6137138361175d565b905080828201101561378657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b6137928383830161317d565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b7f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547fd54702836c9d21d0727ffacc3e39f57c92b5ae0f50177e593bfb5ec66e3de280600052604860209081527f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d546040805180840183815233606081901b93830193909352865160029560039594938993926054909101918401908083835b602083106138da57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161389d565b6001836020036101000a038019825116818451168082178552505050505050905001935050505060405160208183030381529060405280519060200120604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061398357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613946565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156139e0573d6000803e3d6000fd5b5050506040515160601b60405160200180826bffffffffffffffffffffffff191681526014019150506040516020818303038152906040526040518082805190602001908083835b60208310613a6557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613a28565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015613ac2573d6000803e3d6000fd5b5050506040513d6020811015613ad757600080fd5b505181613ae057fe5b061580613b3e57507f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f160005260466020527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e0311854610384429190910310155b613b93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615f046025913960400191505060405180910390fd5b50565b604080513360208083018290528351808403820181529284018452825192810192909220600091825260449092529190912054600114613c3757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e657220737461747573206973206e6f74207374616b6572000000000000604482015290519081900360640190fd5b603a54835114613ca857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b603c54602084015114613d1c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b603e54604084015114613d9057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b604054606084015114613e0457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b604254608084015114613e7857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b60008181526046602090815260408083204290557f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d547f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed2492548185526039845282852033865290935292205460ff1615613f3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615ebf6021913960400191505060405180910390fd5b6000828152603960209081526040808320338452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c5483526045825280832087518480526006820190935292208360058110613fc257fe5b0155602080860151600160009081526006840190925260409091208360058110613fe857fe5b0155604080860151600260009081526006840160205291909120836005811061400d57fe5b01556060850151600360009081526006830160205260409020836005811061403157fe5b01556080850151600460009081526006830160205260409020836005811061405557fe5b015560008080526005808301602052604090912033918490811061407557fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905560016000908152600582810160205260409091203391849081106140d957fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600260009081526005828101602052604090912033918490811061413d57fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905560036000908152600582810160205260409091203391849081106141a157fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600460009081526005828101602052604090912033918490811061420557fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600182016004141561425d5761425d614ad7565b81600101600514156142c5576142738787614c15565b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b082600090815260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed249255614317565b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b08260005260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed2492805460010190555b823373ffffffffffffffffffffffffffffffffffffffff167f9d2e5f03fc65aff196e0f3a8dd924b24099de487e8cffc888921d420ab196e3989898987604051808060200185600560200280838360005b83811015614380578181015183820152602001614368565b5050505090500184600560200280838360005b838110156143ab578181015183820152602001614393565b50505050905001838152602001828103825286818151815260200191508051906020019080838360005b838110156143ed5781810151838201526020016143d5565b50505050905090810190601f16801561441a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a350505050505050565b8061443d576145d7565b60006144488361175d565b90508082820311156144bb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e5482810381101561457757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b6145838484840361317d565b50507fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e805482900390555b5050565b60008281526045602090815260408083207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d845260018101909252909120546146249083615605565b7f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d6000908152600183016020526040902055603a548314806146675750603c5483145b806146735750603e5483145b8061467f575060405483145b8061468b575060425483145b156146e5577f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60005260466020527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b72805483019055613302565b7ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa1600090815260018201602052604090205461483f5760408051610660810191829052600091829161475691839060339082845b815481526020019060010190808311614739575050505050615614565b7f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d60009081526001860160205260409020549193509150821080614798575081155b15614838577f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d60009081526001840160205260408120549082603381106147db57fe5b0155600081815260356020908152604080832080548452604583528184207ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa185526001908101845282852085905590899055860190915290208190555b5050613302565b7ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa160009081526001820160205260408120548391906033811061487e57fe5b0180549091019055505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152604b602052604090205460ff161561492057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f616c72656479206d696772617465640000000000000000000000000000000000604482015290519081900360640190fd5b7f56e0987db9eaec01ed9e0af003a0fd5c062371f9d23722eb4a3ebc74f16ea371600052604760209081527fc930326aab6c1874fc004d856083a6ed34e057e064970b7effb48e8e6e8ca12754604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301529151614a1094869493909316926370a082319260248082019391829003018186803b1580156149df57600080fd5b505afa1580156149f3573d6000803e3d6000fd5b505050506040513d6020811015614a0957600080fd5b5051615681565b73ffffffffffffffffffffffffffffffffffffffff166000908152604b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000818310614a6e5781614a70565b825b9392505050565b6000818311614a6e5781614a70565b600080821315614aa3575081810182811215614a9e57fe5b610c03565b5081810182811315610c0357fe5b600080821315614ac9575080820382811315614a9e57fe5b5080820382811215610c0357fe5b7f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f1600090815260466020527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e0311854420390614b336104b083614a5f565b60466020527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547fd4f87b8d0f3d3b7e665df74631f6100b2695daa0e30e40eeac02172e15a999e16000527f8156e704072c396780f8253d0562de28216b73a1503daa96e259b9cdd951d71c54610fa0929003810291909105915081614bb857600191505b614bc58282016001615943565b7ff758978fc1647996a3d9992f611883adc442931dc49488312360acc90601759b60005260466020527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d15002555505050565b7fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c54600090815260456020908152604082207f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d547f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f190935260469091527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e031188054429182905591929190614cc6615d12565b614cce615d12565b60005b600581101561510d5760015b6005811015614f6857600082815260068901602052604081208260058110614d0157fe5b0154905060008960050160008581526020019081526020016000208360058110614d2757fe5b015473ffffffffffffffffffffffffffffffffffffffff169050825b600081118015614d905750600085815260068c01602052604090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820160058110614d8b57fe5b015483105b15614ed357600085815260068c01602052604090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820160058110614dd257fe5b0154600086815260068d01602052604090208260058110614def57fe5b015560008581526005808d016020526040909120907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301908110614e3057fe5b015460008681526005808e01602052604090912073ffffffffffffffffffffffffffffffffffffffff909216919083908110614e6857fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01614d43565b83811015614f5d57600085815260068c016020526040902083908260058110614ef857fe5b015560008581526005808d016020526040909120839183908110614f1857fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b505050600101614cdd565b506000604560008a8460058110614f7b57fe5b602002015181526020019081526020016000209050876006016000838152602001908152602001600020600580602002604051908101604052809291908260058015614fdc576020028201915b815481526020019060010190808311614fc8575b5050505050935083600260058110614ff057fe5b602090810291909101516000878152600384019092526040918290205584015183836005811061501c57fe5b6020908102919091019190915260008381526005808b0183526040808320898452858301909452909120615051929091615d30565b5060008281526006808a016020908152604080842089855292850190915290912061507d916005615d30565b506000828152600589016020526040812061509791615d6b565b600082815260068901602052604081206150b091615d6b565b8054600181810183556000838152602080822090930188905587815260028401835260408082204390557f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d82529382019092529181205501614cd1565b50847fbeb3b9f46c8d7bb00c873fca10d307538df350866d25f891ffb395147ddbdc45888584604660007f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60001b8152602001908152602001600020546040518085600560200280838360005b8381101561519257818101518382015260200161517a565b5050505090500184815260200183600560200280838360005b838110156151c35781810151838201526020016151ab565b5050505090500182815260200194505050505060405180910390a2603380546001810182556000919091527f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a820183905561521b615d12565b87516000908152604560209081526040808320878452600590810190925291829020825160a08101938490529290919082845b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161524e57505050505090506152898186615952565b7ff3b93531fa65b3a18680d9ea49df06d96fbd883c4889dc7db866f8b131602dfb60005260466020527fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c805460010190556152e2615d12565b6152ea615ad9565b905060005b60058110156154375781816005811061530457fe5b6020020151603a826005811061531657fe5b600202015560008060458185856005811061532d57fe5b6020020151815260200190815260200160002060010160007ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa160001b8152602001908152602001600020546033811061538257fe5b01556045600083836005811061539457fe5b60209081029190910151825281810192909252604090810160009081207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d825260019081018452918120547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a90915260469092527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b728054909201909155016152ef565b50898760014303406040516020018080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b8381101561548b578181015183820152602001615473565b50505050905090810190601f1680156154b85780820380516001836020036101000a031916815260200191505b50604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d81905560469091527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60009081527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b7254929f508f98507f1d85ce10456e29b67de37887496d3f1fcf1b64c79c4d07484038703a9f5c140897508996509094509092508190859060a0908190849084905b838110156155db5781810151838201526020016155c3565b5050505091909101938452505060208201526040805191829003019150a250505050505050505050565b600082820183811015614a7057fe5b610640810151603260315b801561567b578284826033811061563257fe5b602002015110156156545783816033811061564957fe5b602002015192508091505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161561f565b50915091565b806156d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e136021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661575957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5265636569766572206973203020616464726573730000000000000000000000604482015290519081900360640190fd5b60006157648361175d565b90508082820110156157d757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e5482810181111561589357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e8054840190556158ef8483850161317d565b60408051848152905173ffffffffffffffffffffffffffffffffffffffff8616916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350505050565b6000818313614a6e5781614a70565b60466020527fc2c579d641b643400780d5c7ce967b420034b9f66962a5ee405cf70e4cbed6bb547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60009081527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b7254428490039261012c9084020491600a9091049060028304906159ed9087905b6020020151838501615681565b6159f88660016159e0565b615a038660026159e0565b615a0e8660036159e0565b615a198660046159e0565b7f7a39905194de50bde334d18b76bbb36dddd11641d4d50b470cb837cf3bae5def60005260476020527fb5f7e7387e8e977cc9c4c9513388b0d7224264b9a0159cd8e8bdd84a9ed504c354615a849073ffffffffffffffffffffffffffffffffffffffff1682615681565b50507f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a600090815260466020527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b725550505050565b615ae1615d12565b615ae9615d12565b615af1615d12565b60408051610660810191829052615b289160009060339082845b815481526020019060010190808311615b0b575050505050615bbe565b909250905060005b6005811015615bb857828160058110615b4557fe5b602002015115615b895760356000838360058110615b5f57fe5b6020020151815260200190815260200160002054848260058110615b7f57fe5b6020020152615bb0565b603a8160040360058110615b9957fe5b6002020154848260058110615baa57fe5b60200201525b600101615b30565b50505090565b615bc6615d12565b615bce615d12565b60208301516000805b6005811015615c5157858160010160338110615bef57fe5b6020020151858260058110615c0057fe5b602002015260018101848260058110615c1557fe5b602002015282858260058110615c2757fe5b60200201511015615c4957848160058110615c3e57fe5b602002015192508091505b600101615bd7565b5060065b6033811015615d0a5782868260338110615c6b57fe5b60200201511115615d0257858160338110615c8257fe5b6020020151858360058110615c9357fe5b602002015280848360058110615ca557fe5b6020020152858160338110615cb657fe5b6020020151925060005b6005811015615d005783868260058110615cd657fe5b60200201511015615cf857858160058110615ced57fe5b602002015193508092505b600101615cc0565b505b600101615c55565b505050915091565b6040518060a001604052806005906020820280368337509192915050565b8260058101928215615d5b579182015b82811115615d5b578254825591600101919060010190615d40565b50615d67929150615d8e565b5090565b506000815560010160008155600101600081556001016000815560010160009055565b5b80821115615d675760008155600101615d8f56fe4d696e65722063616e206f6e6c792077696e2072657761726473206f6e636520706572203135206d696e4d696e657220776173206e6f74206c6f636b656420666f72207769746864726177616c45524332303a20617070726f766520746f20746865207a65726f2061646472657373547269656420746f206d696e74206e6f6e2d706f73697469766520616d6f756e7453686f756c6420686176652073756666696369656e742062616c616e636520746f207472616465547269656420746f2073656e64206e6f6e2d706f73697469766520616d6f756e7442616c616e6365206973206c6f776572207468616e207374616b6520616d6f756e744469737075746520686173206265656e20616c72656164792065786563757465644d696e657220616c7265616479207375626d6974746564207468652076616c756545524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373496e636f7272656374206e6f6e636520666f722063757272656e74206368616c6c656e6765a2646970667358221220283d77407206ff6c4cc0f6e78ee639e4e194574cc796cf2b7dbf2fa45ca9e7dc64736f6c63430007040033

Deployed Bytecode

0x6080604052600436106101e35760003560e01c806370a0823111610102578063b59e14d411610095578063d01f4d9e11610064578063d01f4d9e146108f7578063d67dcbc514610921578063db085beb14610967578063dd62ed3e146109ee576101e3565b8063b59e14d4146107ff578063bed9d86114610829578063c9d27afe1461083e578063cbf1304d14610870576101e3565b806390e5b235116100d157806390e5b23514610734578063999cf26c146107495780639a01ca131461078f578063a9059cbb146107b9576101e3565b806370a0823114610679578063752d49a1146106b95780638581af19146106e95780638fd3ab801461071f576101e3565b8063453990161161017a5780634ee2cd7e116101495780634ee2cd7e1461058c5780635700242c146105d257806362dd1d2a146105fc578063699f200f14610626576101e3565b8063453990161461049c57806348b18e54146104dc5780634ba0a5ee146105225780634d318b0e14610562576101e3565b806323b872dd116101b657806323b872dd1461038c57806328449c3a146103dc5780634350283e146103f1578063438c0aa314610472576101e3565b8063024c2ddd14610269578063095ea7b3146102c35780630d2d76a21461031d5780631fd2236414610334575b7fabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a600090815260476020527f9a17b40120dc8667cacbaf2c16d2d82572643f21bfde07d6cf294bd1927356dc5473ffffffffffffffffffffffffffffffffffffffff169061025082610a36565b5090503d6000803e808015610264573d6000f35b3d6000fd5b34801561027557600080fd5b506102b16004803603604081101561028c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610ab3565b60408051918252519081900360200190f35b3480156102cf57600080fd5b50610309600480360360408110156102e657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610ad0565b604080519115158252519081900360200190f35b34801561032957600080fd5b50610332610c09565b005b34801561034057600080fd5b5061035e6004803603602081101561035757600080fd5b5035610c1c565b6040805192835273ffffffffffffffffffffffffffffffffffffffff90911660208301528051918290030190f35b34801561039857600080fd5b50610309600480360360608110156103af57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610c54565b3480156103e857600080fd5b50610332610d3f565b3480156103fd57600080fd5b50610332600480360361016081101561041557600080fd5b81019060208101813564010000000081111561043057600080fd5b82018360208201111561044257600080fd5b8035906020019184600183028401116401000000008311171561046457600080fd5b919350915060a08101610e75565b34801561047e57600080fd5b506102b16004803603602081101561049557600080fd5b503561104e565b3480156104a857600080fd5b50610332600480360360208110156104bf57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661106f565b3480156104e857600080fd5b50610309600480360360408110156104ff57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff1661116a565b34801561052e57600080fd5b506103096004803603602081101561054557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661118a565b34801561056e57600080fd5b506103326004803603602081101561058557600080fd5b503561119f565b34801561059857600080fd5b506102b1600480360360408110156105af57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356114a0565b3480156105de57600080fd5b506102b1600480360360208110156105f557600080fd5b5035611711565b34801561060857600080fd5b506102b16004803603602081101561061f57600080fd5b5035611723565b34801561063257600080fd5b506106506004803603602081101561064957600080fd5b5035611735565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561068557600080fd5b506102b16004803603602081101561069c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661175d565b3480156106c557600080fd5b50610332600480360360408110156106dc57600080fd5b5080359060200135611769565b3480156106f557600080fd5b506103326004803603606081101561070c57600080fd5b50803590602081013590604001356119e8565b34801561072b57600080fd5b50610332612386565b34801561074057600080fd5b5061033261238f565b34801561075557600080fd5b506103096004803603604081101561076c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356124a9565b34801561079b57600080fd5b50610332600480360360208110156107b257600080fd5b5035612586565b3480156107c557600080fd5b50610309600480360360408110156107dc57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612d27565b34801561080b57600080fd5b506102b16004803603602081101561082257600080fd5b5035612d3d565b34801561083557600080fd5b50610332612d4f565b34801561084a57600080fd5b506103326004803603604081101561086157600080fd5b50803590602001351515612e68565b34801561087c57600080fd5b506108b66004803603604081101561089357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135613112565b60405180836fffffffffffffffffffffffffffffffff168152602001826fffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b34801561090357600080fd5b506102b16004803603602081101561091a57600080fd5b503561316b565b34801561092d57600080fd5b506103326004803603604081101561094457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561317d565b34801561097357600080fd5b506109916004803603602081101561098a57600080fd5b5035613307565b604080519889526020890197909752941515878701529215156060870152901515608086015273ffffffffffffffffffffffffffffffffffffffff90811660a086015290811660c08501521660e083015251908190036101000190f35b3480156109fa57600080fd5b506102b160048036036040811015610a1157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516613370565b600060608273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610aa3576040519150601f19603f3d011682016040523d82523d6000602084013e610aa8565b606091505b509094909350915050565b604a60209081526000928352604080842090915290825290205481565b600033610b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615ee06024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316610b94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615df16022913960400191505060405180910390fd5b336000818152604a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b610c12336133a8565b610c1a61238f565b565b603a8160058110610c2c57600080fd5b60020201805460019091015490915073ffffffffffffffffffffffffffffffffffffffff1682565b73ffffffffffffffffffffffffffffffffffffffff83166000908152604a60209081526040808320338452909152812054821115610cf357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f416c6c6f77616e63652069732077726f6e670000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152604a60209081526040808320338452909152902080548390039055610d358484846135ba565b5060019392505050565b3360009081526044602052604090208054600114610dbe57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4d696e6572206973206e6f74207374616b656400000000000000000000000000604482015290519081900360640190fd5b60028155620151804206420360018201557f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b60005260466020527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055610e4761238f565b60405133907f453865710d0cb4b14ad25de371c860da196368895daa9662e5087711d14daecf90600090a250565b6040805133602080830191909152825180830382018152918301835281519181019190912060008181526046909252919020541580610ec857506000818152604660205260409020546103844291909103115b610f1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615da4602a913960400191505060405180910390fd5b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b08260005260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed249254600414610fae57610fae85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506137fd92505050565b6000818152604660209081526040918290204290558151601f870182900482028101820190925285825261104791908790879081908401838280828437600092019190915250506040805160a081810190925292508791506005908390839080828437600092019190915250506040805160a0818101909252915086906005908390839080828437600092019190915250613b96915050565b5050505050565b6033818154811061105e57600080fd5b600091825260209091200154905081565b7f5fc094d10c65bc33cc842217b2eccca0191ff24148319da094e540a55989896160005260476020527f437dd27c2043efdfef03344e9331c924985f7bd1752abef5ea93bdbfed6851005473ffffffffffffffffffffffffffffffffffffffff1633146110db57600080fd5b7fabd9bea65759494fe86471c8386762f989e1f2e778949e94efa4a9d1c4b3545a60005260476020527f9a17b40120dc8667cacbaf2c16d2d82572643f21bfde07d6cf294bd1927356dc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b603960209081526000928352604080842090915290825290205460ff1681565b604b6020526000908152604090205460ff1681565b6000818152603660205260409020600281015460ff161561120b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e9e6021913960400191505060405180910390fd5b7f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2860009081526005820160205260409020544210156112ab57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b600381015473ffffffffffffffffffffffffffffffffffffffff1661133157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706f7274696e672050617274792069732061646472657373203000000000604482015290519081900360640190fd5b6001810154600081131561136e576002820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600282015462010000900460ff166113c15760028201546301000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526044602052604090208054600314156113bf57600481555b505b7ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a660009081526005830160209081526040918290204290556002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117908190556003850154835185815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352610100820460ff1615158385015292516301000000909104929092169185917f21459c2f5447ebcf83a7f0a238c32c71076faef0d12295e771c0cb1e10434739919081900360600190a3505050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152604960205260408120805415806114fc575082816000815481106114dc57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff16115b1561150b576000915050610c03565b805481907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061153b57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1683106115ca57805481907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061158f57fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169150610c039050565b80546000907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe015b818111156116c857600060026001838501010490508584828154811061161457fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1614156116825783818154811061164457fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169450610c039350505050565b8584828154811061168f57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1610156116bb578092506116c2565b6001810391505b506115f2565b8282815481106116d457fe5b60009182526020909120015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169350610c0392505050565b60376020526000908152604090205481565b60486020526000908152604090205481565b60476020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6000610c0382436114a0565b816117d557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f5265717565737449642069732030000000000000000000000000000000000000604482015290519081900360640190fd5b8061184157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f5469702073686f756c642062652067726561746572207468616e203000000000604482015290519081900360640190fd5b7f3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c86560005260466020527f7119b9afaa3bda0901ffe121c1535f50cd6d0d09df5d29eb1cb16c8ab47a55d654600101828114156118e9577f3f8b5616fa9e7f2ce4a868fde15c58b92e77bc1acd6769bf1567629a3dc4c86560005260466020527f7119b9afaa3bda0901ffe121c1535f50cd6d0d09df5d29eb1cb16c8ab47a55d6819055611957565b80831061195757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f526571756573744964206973206e6f74206c657373207468616e20636f756e74604482015290519081900360640190fd5b6119613383614433565b61196b83836145db565b60008381526045602090815260408083207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d8452600101825291829020548251858152918201528151859233927fd32134405b68f6f7220f9c38ae310df1b648d16188006768d45be2f7c24e8820929081900390910190a3505050565b60008381526045602090815260408083208584526002810190925290912054611a7257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4d696e656420626c6f636b206973203000000000000000000000000000000000604482015290519081900360640190fd5b60058210611ae157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4d696e657220696e6465782069732077726f6e67000000000000000000000000604482015290519081900360640190fd5b60008381526005808301602052604082209084908110611afd57fe5b0154604080517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084901b1660208083019190915260348201899052605480830189905283518084039091018152607490920183528151918101919091207f1ce2382bc92689b00ba121fa5a411aa976168affdd8ac143a69035dd984b3b6a80546001019081905560008281526038909352929091205473ffffffffffffffffffffffffffffffffffffffff9093169350918015611bfa5760008281526036602090815260408083207fed92b4c1e0a9e559a31171d487ecbec963526662038ecfa3a71160bd62fb873384526005019091529020819055611c0e565b506000828152603860205260409020819055805b60008181526036602081815260408084207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a92385526005018083528185208054600101908190558686529383528151808401859052825180820385018152908301835280519084012085529091529091208390558190838214611e5657600082815260366020818152604080842081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8701818501528251808203850181529083018352805190840120855260059081018352818520548086529383528185207f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2886520190915290912054421015611d8757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4469737075746520697320616c7265616479206f70656e000000000000000000604482015290519081900360640190fd5b60008181526036602052604090206002015460ff1615611e545760008181526036602090815260408083207ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a684526005019091529020546201518042919091031115611e5457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b505b60008860021415611ef9575060008a81526045602090815260408083207f310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d78452600190810183529083208054909101908190557f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc97909252604690527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be5402611f48565b507f675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc60005260466020527f3e5522f19747f0f285b96ded572ac4128c3a764aea9f44058dc0afc9dda449865481025b85603660008781526020019081526020016000206000018190555060006036600087815260200190815260200160002060020160026101000a81548160ff021916908315150217905550866036600087815260200190815260200160002060020160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550336036600087815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006036600087815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006036600087815260200190815260200160002060020160006101000a81548160ff02191690831515021790555060006036600087815260200190815260200160002060020160016101000a81548160ff021916908315150217905550600060366000878152602001908152602001600020600101819055508a6036600087815260200190815260200160002060050160007f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60001b815260200190815260200160002081905550896036600087815260200190815260200160002060050160007f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e560001b8152602001908152602001600020819055508760060160008b815260200190815260200160002089600581106121ca57fe5b015460008681526036602090815260408083207f9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f478452600501909152808220929092557f46f7d53798d31923f6952572c6a19ad2d1a8238d26649c2f3493a6d69e425d2881528181206202a3008502420190557f4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c81528181204390557f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d81528181208b90557f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098152208190556122c13330836135ba565b88600214156123115760008a8152600489016020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560038b019091528120555b73ffffffffffffffffffffffffffffffffffffffff87166000818152604460209081526040918290206003905581518d81529081019290925280518d9288927feceec1aebf67772b2440120c4b4dc913a1fe1b865509219f9456785c23b9da6492918290030190a35050505050505050505050565b610c1a3361488b565b60466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be547f2e2f0a18eb55ef91e37921b3810d7feeef7a855ddc7f4f4249ef03d7b887ae31547f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b6000527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd35461245a9067d02ab486cedc0000906103e890849061243d908290614a5f565b6103e80286028161244a57fe5b048161245257fe5b048403614a77565b7f675d2171f68d6f5545d54fb9b1fb61a0e6897e6188ca1cd664e7c9530d91ecfc60005260466020527f3e5522f19747f0f285b96ded572ac4128c3a764aea9f44058dc0afc9dda44986555050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526044602052604081205415801590612502575073ffffffffffffffffffffffffffffffffffffffff83166000908152604460205260409020546005115b15612573577f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be54829061255d8561175d565b031061256b57506001610c03565b506000610c03565b8161257d8461175d565b10159392505050565b600081815260366020818152604080842054845260388252808420548085529282528084207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a9238552600501808352818520548251808501919091528251808203850181529083018352805190840120855290915290912054806126065750805b60008281526036602090815260408083208484528184207f6ab2b18aafe78fd59c6a4092015bddd9fcacb8170f72b299074f74d76a91a92385526005820190935292205480612653575060015b7f29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc6000908152600584016020526040812054156126f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f616c72656164792070616964206f757400000000000000000000000000000000604482015290519081900360640190fd5b7ff9e1ae10923bfc79f52e309baf8c7699edb821f91ef5b5bd07be29545917b3a660009081526005840160205260409020546201518042919091031161279857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686176656e277420656c617073656400604482015290519081900360640190fd5b6002848101546301000000900473ffffffffffffffffffffffffffffffffffffffff1660009081526044602090815260408083207f29169706298d2b6df50a532e958b56426de1465348b93650fca42d456eaec5fc84526005890190925290912060019081905591850154909161010090910460ff16151514156129ef57620151804206420360018201557f10c168823622203e4057b65015ff4d95b4c650b308918e8c92dc32ab5a0a034b60005260466020527fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01905561289b61238f565b80546004141561292e5760058155600285015460038601547f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be546129299273ffffffffffffffffffffffffffffffffffffffff630100000090910481169216906135ba565b600081555b60005b838110156129e9576040805182860360208083019190915282518083038201815291830183528151918101919091206000908152600589019091522054925082612979578792505b600083815260366020908152604080832060038101547f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098552600582019093529220546129e091309173ffffffffffffffffffffffffffffffffffffffff909116906135ba565b50600101612931565b50612c53565b600181557f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60009081526005860160208181526040808420548452604582528084207f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d8552929091529091205460021415612ace577f9147231ab14efb72c38117f68521ddef8de64f092c18c69dbfb602ffc4de7f4760009081526005870160209081526040808320547f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5845281842054845260038501909252909120555b7f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e5600090815260058701602090815260408083205483526004840190915290205460ff16151560011415612b83577f2f9328a9c75282bec25bb04befad06926366736e0030c985108445fa728335e56000908152600587016020908152604080832054835260048401909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b60005b84811015612c5057604080518287036020808301919091528251808303820181529183018352815191810191909120600090815260058a01909152205493508315612bdc57600084815260366020526040902095505b600286015460008581526036602090815260408083207f1da95f11543c9b03927178e07951795dfc95c7501a9d1cf00e13414ca33bc4098452600501909152902054612c48913091630100000090910473ffffffffffffffffffffffffffffffffffffffff16906135ba565b600101612b86565b50505b7f6de96ee4d33a0617f40a846309c8759048857f51b9d59a12d3c3786d4778883d600090815260058601602052604090205460021415612d1d577f9f47a2659c3d32b749ae717d975e7962959890862423c4318cf86e4ec220291f60009081526005860160209081526040808320548352604582528083207f310199159a20c50879ffb440b45802138b5b162ec9426720e9dd3ee8bbcdb9d78452600101909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b5050505050505050565b6000612d343384846135ba565b50600192915050565b60466020526000908152604090205481565b336000908152604460205260409020600181015462093a80906201518042064203031015612dde57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f372064617973206469646e277420706173730000000000000000000000000000604482015290519081900360640190fd5b8054600214612e38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615dce6023913960400191505060405180910390fd5b600080825560405133917f4a7934670bd8304e7da22378be1368f7c4fef17c5aee81804beda8638fe428ec91a250565b60008281526036602090815260408083207f4b4cefd5ced7569ef0d091282b4bca9c52a034c56471a6061afd1bf307a2de7c845260058101909252822054909190612eb49033906114a0565b33600090815260068401602052604090205490915060ff16151560011415612f3d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f53656e6465722068617320616c726561647920766f7465640000000000000000604482015290519081900360640190fd5b80612fa957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f557365722062616c616e63652069732030000000000000000000000000000000604482015290519081900360640190fd5b336000908152604460205260409020546003141561302857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d696e657220697320756e646572206469737075746500000000000000000000604482015290519081900360640190fd5b336000908152600683016020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091557f1da378694063870452ce03b189f48e04c1aa026348e74e6c86e10738514ad2c48452600586019092529091208054909101905582156130bb5760018201546130b19082614a86565b60018301556130d0565b60018201546130ca9082614ab1565b60018301555b60408051841515815290518291339187917f911ef2e98570b1d96c0e8ef81107a33d5b8e844aeb8f9710f9bc76c3b3fef40e919081900360200190a450505050565b6049602052816000526040600020818154811061312e57600080fd5b6000918252602090912001546fffffffffffffffffffffffffffffffff808216935070010000000000000000000000000000000090910416905082565b60386020526000908152604090205481565b73ffffffffffffffffffffffffffffffffffffffff82166000908152604960205260409020805415806131fe57508054439082907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106131dd57fe5b6000918252602090912001546fffffffffffffffffffffffffffffffff1614155b156132945760408051808201909152436fffffffffffffffffffffffffffffffff90811682528381166020808401918252845460018101865560008681529190912093519301805491517fffffffffffffffffffffffffffffffff000000000000000000000000000000009092169383169390931782167001000000000000000000000000000000009190921602179055613302565b805460009082907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081106132c757fe5b600091825260209091200180546fffffffffffffffffffffffffffffffff808616700100000000000000000000000000000000029116179055505b505050565b603660205260009081526040902080546001820154600283015460038401546004909401549293919260ff8083169361010084048216936201000081049092169273ffffffffffffffffffffffffffffffffffffffff6301000000909304831692918216911688565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152604a6020908152604080832093909416825291909152205490565b7f5d9fadfc729fd027e395e5157ef1b53ef9fa4a8f053043c5f159307543e7cc9760005260466020527f167af83a0768d27540775cfef6d996eb63f8a61fcdfb26e654c18fb50960e3be546133fc8261175d565b1015613453576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615e7c6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526044602052604090205415806134aa575073ffffffffffffffffffffffffffffffffffffffff81166000908152604460205260409020546002145b61351557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d696e657220697320696e207468652077726f6e672073746174650000000000604482015290519081900360640190fd5b7fa5ae3e2b97d73fb849ea855d27f073b72815b38452d976bd57e4a157827dadd38054600190810190915560408051808201825282815262015180429081069003602082810191825273ffffffffffffffffffffffffffffffffffffffff8616600081815260449092528482209351845591519290940191909155905190917f46d8ab1385f70e5a3673e97c23c764f7600f7ed7a09b6687deae7131d51752e291a250565b80613610576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e5b6021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661369257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5265636569766572206973203020616464726573730000000000000000000000604482015290519081900360640190fd5b61369c83826124a9565b6136f1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180615e346027913960400191505060405180910390fd5b60006136fc8461175d565b905061370a8483830361317d565b6137138361175d565b905080828201101561378657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b6137928383830161317d565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b7f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547fd54702836c9d21d0727ffacc3e39f57c92b5ae0f50177e593bfb5ec66e3de280600052604860209081527f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d546040805180840183815233606081901b93830193909352865160029560039594938993926054909101918401908083835b602083106138da57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161389d565b6001836020036101000a038019825116818451168082178552505050505050905001935050505060405160208183030381529060405280519060200120604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061398357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613946565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156139e0573d6000803e3d6000fd5b5050506040515160601b60405160200180826bffffffffffffffffffffffff191681526014019150506040516020818303038152906040526040518082805190602001908083835b60208310613a6557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613a28565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015613ac2573d6000803e3d6000fd5b5050506040513d6020811015613ad757600080fd5b505181613ae057fe5b061580613b3e57507f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f160005260466020527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e0311854610384429190910310155b613b93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615f046025913960400191505060405180910390fd5b50565b604080513360208083018290528351808403820181529284018452825192810192909220600091825260449092529190912054600114613c3757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e657220737461747573206973206e6f74207374616b6572000000000000604482015290519081900360640190fd5b603a54835114613ca857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b603c54602084015114613d1c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b603e54604084015114613d9057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b604054606084015114613e0457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b604254608084015114613e7857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f526571756573742049442069732077726f6e6700000000000000000000000000604482015290519081900360640190fd5b60008181526046602090815260408083204290557f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d547f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed2492548185526039845282852033865290935292205460ff1615613f3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615ebf6021913960400191505060405180910390fd5b6000828152603960209081526040808320338452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c5483526045825280832087518480526006820190935292208360058110613fc257fe5b0155602080860151600160009081526006840190925260409091208360058110613fe857fe5b0155604080860151600260009081526006840160205291909120836005811061400d57fe5b01556060850151600360009081526006830160205260409020836005811061403157fe5b01556080850151600460009081526006830160205260409020836005811061405557fe5b015560008080526005808301602052604090912033918490811061407557fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905560016000908152600582810160205260409091203391849081106140d957fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600260009081526005828101602052604090912033918490811061413d57fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905560036000908152600582810160205260409091203391849081106141a157fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600460009081526005828101602052604090912033918490811061420557fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600182016004141561425d5761425d614ad7565b81600101600514156142c5576142738787614c15565b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b082600090815260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed249255614317565b7fdfbec46864bc123768f0d134913175d9577a55bb71b9b2595fda21e21f36b08260005260466020527f7df1eb1754bc067736ff3d89af41d339bf906d31b0f5978e3c78f402d4ed2492805460010190555b823373ffffffffffffffffffffffffffffffffffffffff167f9d2e5f03fc65aff196e0f3a8dd924b24099de487e8cffc888921d420ab196e3989898987604051808060200185600560200280838360005b83811015614380578181015183820152602001614368565b5050505090500184600560200280838360005b838110156143ab578181015183820152602001614393565b50505050905001838152602001828103825286818151815260200191508051906020019080838360005b838110156143ed5781810151838201526020016143d5565b50505050905090810190601f16801561441a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a350505050505050565b8061443d576145d7565b60006144488361175d565b90508082820311156144bb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e5482810381101561457757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b6145838484840361317d565b50507fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e805482900390555b5050565b60008281526045602090815260408083207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d845260018101909252909120546146249083615605565b7f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d6000908152600183016020526040902055603a548314806146675750603c5483145b806146735750603e5483145b8061467f575060405483145b8061468b575060425483145b156146e5577f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60005260466020527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b72805483019055613302565b7ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa1600090815260018201602052604090205461483f5760408051610660810191829052600091829161475691839060339082845b815481526020019060010190808311614739575050505050615614565b7f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d60009081526001860160205260409020549193509150821080614798575081155b15614838577f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d60009081526001840160205260408120549082603381106147db57fe5b0155600081815260356020908152604080832080548452604583528184207ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa185526001908101845282852085905590899055860190915290208190555b5050613302565b7ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa160009081526001820160205260408120548391906033811061487e57fe5b0180549091019055505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152604b602052604090205460ff161561492057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f616c72656479206d696772617465640000000000000000000000000000000000604482015290519081900360640190fd5b7f56e0987db9eaec01ed9e0af003a0fd5c062371f9d23722eb4a3ebc74f16ea371600052604760209081527fc930326aab6c1874fc004d856083a6ed34e057e064970b7effb48e8e6e8ca12754604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301529151614a1094869493909316926370a082319260248082019391829003018186803b1580156149df57600080fd5b505afa1580156149f3573d6000803e3d6000fd5b505050506040513d6020811015614a0957600080fd5b5051615681565b73ffffffffffffffffffffffffffffffffffffffff166000908152604b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000818310614a6e5781614a70565b825b9392505050565b6000818311614a6e5781614a70565b600080821315614aa3575081810182811215614a9e57fe5b610c03565b5081810182811315610c0357fe5b600080821315614ac9575080820382811315614a9e57fe5b5080820382811215610c0357fe5b7f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f1600090815260466020527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e0311854420390614b336104b083614a5f565b60466020527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547fd4f87b8d0f3d3b7e665df74631f6100b2695daa0e30e40eeac02172e15a999e16000527f8156e704072c396780f8253d0562de28216b73a1503daa96e259b9cdd951d71c54610fa0929003810291909105915081614bb857600191505b614bc58282016001615943565b7ff758978fc1647996a3d9992f611883adc442931dc49488312360acc90601759b60005260466020527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d15002555505050565b7fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c54600090815260456020908152604082207f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d547f2c8b528fbaf48aaf13162a5a0519a7ad5a612da8ff8783465c17e076660a59f190935260469091527f231bb0dc207f13dd4e565ebc32496c470e35391bd8d3b6649269ee2328e031188054429182905591929190614cc6615d12565b614cce615d12565b60005b600581101561510d5760015b6005811015614f6857600082815260068901602052604081208260058110614d0157fe5b0154905060008960050160008581526020019081526020016000208360058110614d2757fe5b015473ffffffffffffffffffffffffffffffffffffffff169050825b600081118015614d905750600085815260068c01602052604090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820160058110614d8b57fe5b015483105b15614ed357600085815260068c01602052604090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820160058110614dd257fe5b0154600086815260068d01602052604090208260058110614def57fe5b015560008581526005808d016020526040909120907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301908110614e3057fe5b015460008681526005808e01602052604090912073ffffffffffffffffffffffffffffffffffffffff909216919083908110614e6857fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01614d43565b83811015614f5d57600085815260068c016020526040902083908260058110614ef857fe5b015560008581526005808d016020526040909120839183908110614f1857fe5b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555b505050600101614cdd565b506000604560008a8460058110614f7b57fe5b602002015181526020019081526020016000209050876006016000838152602001908152602001600020600580602002604051908101604052809291908260058015614fdc576020028201915b815481526020019060010190808311614fc8575b5050505050935083600260058110614ff057fe5b602090810291909101516000878152600384019092526040918290205584015183836005811061501c57fe5b6020908102919091019190915260008381526005808b0183526040808320898452858301909452909120615051929091615d30565b5060008281526006808a016020908152604080842089855292850190915290912061507d916005615d30565b506000828152600589016020526040812061509791615d6b565b600082815260068901602052604081206150b091615d6b565b8054600181810183556000838152602080822090930188905587815260028401835260408082204390557f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d82529382019092529181205501614cd1565b50847fbeb3b9f46c8d7bb00c873fca10d307538df350866d25f891ffb395147ddbdc45888584604660007f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60001b8152602001908152602001600020546040518085600560200280838360005b8381101561519257818101518382015260200161517a565b5050505090500184815260200183600560200280838360005b838110156151c35781810151838201526020016151ab565b5050505090500182815260200194505050505060405180910390a2603380546001810182556000919091527f82a75bdeeae8604d839476ae9efd8b0e15aa447e21bfd7f41283bb54e22c9a820183905561521b615d12565b87516000908152604560209081526040808320878452600590810190925291829020825160a08101938490529290919082845b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161524e57505050505090506152898186615952565b7ff3b93531fa65b3a18680d9ea49df06d96fbd883c4889dc7db866f8b131602dfb60005260466020527fe97d205f7d20bf394e3813033d2203b4733acb28b351c8d2a771647ab0d41c3c805460010190556152e2615d12565b6152ea615ad9565b905060005b60058110156154375781816005811061530457fe5b6020020151603a826005811061531657fe5b600202015560008060458185856005811061532d57fe5b6020020151815260200190815260200160002060010160007ff68d680ab3160f1aa5d9c3a1383c49e3e60bf3c0c031245cbb036f5ce99afaa160001b8152602001908152602001600020546033811061538257fe5b01556045600083836005811061539457fe5b60209081029190910151825281810192909252604090810160009081207f1590276b7f31dd8e2a06f9a92867333eeb3eddbc91e73b9833e3e55d8e34f77d825260019081018452918120547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a90915260469092527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b728054909201909155016152ef565b50898760014303406040516020018080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b8381101561548b578181015183820152602001615473565b50505050905090810190601f1680156154b85780820380516001836020036101000a031916815260200191505b50604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f52cb9007c7c6068f8ef37039d4f232cbf5a28ff8d93a5983c4c0c27cd2f9bc0d81905560469091527f5bccd7373734898281f858d7562320d2cdfc0b17bd72f779686937174d150025547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60009081527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b7254929f508f98507f1d85ce10456e29b67de37887496d3f1fcf1b64c79c4d07484038703a9f5c140897508996509094509092508190859060a0908190849084905b838110156155db5781810151838201526020016155c3565b5050505091909101938452505060208201526040805191829003019150a250505050505050505050565b600082820183811015614a7057fe5b610640810151603260315b801561567b578284826033811061563257fe5b602002015110156156545783816033811061564957fe5b602002015192508091505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161561f565b50915091565b806156d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615e136021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661575957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f5265636569766572206973203020616464726573730000000000000000000000604482015290519081900360640190fd5b60006157648361175d565b90508082820110156157d757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e5482810181111561589357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f766572666c6f772068617070656e6564000000000000000000000000000000604482015290519081900360640190fd5b7fe6148e7230ca038d456350e69a91b66968b222bfac9ebfbea6ff0a1fb738016060005260466020527ffffeead1ec15181fd57b4590d95e0c076bccb59e311315e8b38f23c710aa7c3e8054840190556158ef8483850161317d565b60408051848152905173ffffffffffffffffffffffffffffffffffffffff8616916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350505050565b6000818313614a6e5781614a70565b60466020527fc2c579d641b643400780d5c7ce967b420034b9f66962a5ee405cf70e4cbed6bb547f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a60009081527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b7254428490039261012c9084020491600a9091049060028304906159ed9087905b6020020151838501615681565b6159f88660016159e0565b615a038660026159e0565b615a0e8660036159e0565b615a198660046159e0565b7f7a39905194de50bde334d18b76bbb36dddd11641d4d50b470cb837cf3bae5def60005260476020527fb5f7e7387e8e977cc9c4c9513388b0d7224264b9a0159cd8e8bdd84a9ed504c354615a849073ffffffffffffffffffffffffffffffffffffffff1682615681565b50507f09659d32f99e50ac728058418d38174fe83a137c455ff1847e6fb8e15f78f77a600090815260466020527f38b16d06a20ab673b01c748aff938df6a38f81640035f4ce8bd9abb03aae5b725550505050565b615ae1615d12565b615ae9615d12565b615af1615d12565b60408051610660810191829052615b289160009060339082845b815481526020019060010190808311615b0b575050505050615bbe565b909250905060005b6005811015615bb857828160058110615b4557fe5b602002015115615b895760356000838360058110615b5f57fe5b6020020151815260200190815260200160002054848260058110615b7f57fe5b6020020152615bb0565b603a8160040360058110615b9957fe5b6002020154848260058110615baa57fe5b60200201525b600101615b30565b50505090565b615bc6615d12565b615bce615d12565b60208301516000805b6005811015615c5157858160010160338110615bef57fe5b6020020151858260058110615c0057fe5b602002015260018101848260058110615c1557fe5b602002015282858260058110615c2757fe5b60200201511015615c4957848160058110615c3e57fe5b602002015192508091505b600101615bd7565b5060065b6033811015615d0a5782868260338110615c6b57fe5b60200201511115615d0257858160338110615c8257fe5b6020020151858360058110615c9357fe5b602002015280848360058110615ca557fe5b6020020152858160338110615cb657fe5b6020020151925060005b6005811015615d005783868260058110615cd657fe5b60200201511015615cf857858160058110615ced57fe5b602002015193508092505b600101615cc0565b505b600101615c55565b505050915091565b6040518060a001604052806005906020820280368337509192915050565b8260058101928215615d5b579182015b82811115615d5b578254825591600101919060010190615d40565b50615d67929150615d8e565b5090565b506000815560010160008155600101600081556001016000815560010160009055565b5b80821115615d675760008155600101615d8f56fe4d696e65722063616e206f6e6c792077696e2072657761726473206f6e636520706572203135206d696e4d696e657220776173206e6f74206c6f636b656420666f72207769746864726177616c45524332303a20617070726f766520746f20746865207a65726f2061646472657373547269656420746f206d696e74206e6f6e2d706f73697469766520616d6f756e7453686f756c6420686176652073756666696369656e742062616c616e636520746f207472616465547269656420746f2073656e64206e6f6e2d706f73697469766520616d6f756e7442616c616e6365206973206c6f776572207468616e207374616b6520616d6f756e744469737075746520686173206265656e20616c72656164792065786563757465644d696e657220616c7265616479207375626d6974746564207468652076616c756545524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373496e636f7272656374206e6f6e636520666f722063757272656e74206368616c6c656e6765a2646970667358221220283d77407206ff6c4cc0f6e78ee639e4e194574cc796cf2b7dbf2fa45ca9e7dc64736f6c63430007040033

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.