Mumbai Testnet

Contract

0x8A868711e3cE97429faAA6be476F93907BCBc2bc

Overview

MATIC Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 MATIC

Token Holdings

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Value
Begin Dispute245565582022-02-03 16:34:18783 days ago1643906058IN
0x8A868711...07BCBc2bc
0 MATIC0.001019631.99999999
0x60806040244601312022-01-31 19:21:23786 days ago1643656883IN
 Create: Governance
0 MATIC0.007327172.5

Parent Txn Hash Block From To Value
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Governance

Compiler Version
v0.8.3+commit.8d00100c

Optimization Enabled:
Yes with 300 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 3 : Governance.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.3;

import "./TellorFlex.sol";

contract Governance {
    // Storage
    TellorFlex public tellor;
    IERC20 public token;
    address public teamMultisig;
    uint256 public voteCount; // total number of votes initiated
    uint256 public disputeFee; // dispute fee for a vote
    mapping(uint256 => Dispute) private disputeInfo; // mapping of dispute IDs to the details of the dispute
    mapping(bytes32 => uint256) private openDisputesOnId; // mapping of a query ID to the number of disputes on that query ID
    mapping(address => bool) private users; // mapping of users with voting power, determined by governance proposal votes
    mapping(uint256 => Vote) private voteInfo; // mapping of vote IDs to the details of the vote
    mapping(bytes32 => uint256[]) private voteRounds; // mapping of vote identifier hashes to an array of dispute IDs

    enum VoteResult {
        FAILED,
        PASSED,
        INVALID
    } // status of a potential vote

    struct Dispute {
        bytes32 queryId; // query ID of disputed value
        uint256 timestamp; // timestamp of disputed value
        bytes value; // disputed value
        address disputedReporter; // reporter who submitted the disputed value
        uint256 slashedAmount; // amount of tokens slashed from reporter
    }

    // Structs
    struct Tally {
        uint256 doesSupport; // number of votes in favor
        uint256 against; // number of votes against
        uint256 invalidQuery; // number of votes for invalid
    }

    struct Vote {
        bytes32 identifierHash; // identifier hash of the vote
        uint256 voteRound; // the round of voting on a given dispute or proposal
        uint256 startDate; // timestamp of when vote was initiated
        uint256 blockNumber; // block number of when vote was initiated
        uint256 fee; // fee associated with the vote
        uint256 tallyDate; // timestamp of when the votes were tallied
        Tally tokenholders;
        Tally users;
        Tally reporters;
        Tally teamMultisig;
        bool executed; // boolean of is the dispute settled
        VoteResult result; // VoteResult of did the vote pass?
        bool isDispute; // boolean of is the vote a dispute as opposed to a proposal
        bytes data; // arguments used to execute a proposal
        bytes4 voteFunction; // hash of the function associated with a proposal vote
        address voteAddress; // address of contract to execute function on
        address initiator; // address which initiated dispute/proposal
        mapping(address => bool) voted; // mapping of address to whether or not they voted
    }

    // Events
    event NewDispute(
        uint256 _disputeId,
        bytes32 _queryId,
        uint256 _timestamp,
        address _reporter
    ); // Emitted when a new dispute is opened
    event NewVote(
        address _contract,
        bytes4 _function,
        bytes _data,
        uint256 _disputeId
    ); // Emitted when a new proposal vote is initiated
    event Voted(
        uint256 _disputeId,
        bool _supports,
        address _voter,
        bool _invalidQuery
    ); // Emitted when an address casts their vote
    event VoteExecuted(uint256 _disputeId, VoteResult _result); // Emitted when a vote is executed
    event VoteTallied(
        uint256 _disputeId,
        VoteResult _result,
        address _initiator,
        address _reporter
    ); // Emitted when all casting for a vote is tallied

    /**
     * @dev Initializes contract parameters
     * @param _tellor address of tellor oracle contract to be governed
     * @param _disputeFee base dispute fee
     * @param _teamMultisig address of tellor team multisig, one of four voting
     * stakeholder groups
     */
    constructor(
        address _tellor,
        uint256 _disputeFee,
        address _teamMultisig
    ) {
        tellor = TellorFlex(_tellor);
        token = tellor.token();
        disputeFee = _disputeFee;
        teamMultisig = _teamMultisig;
    }

    /**
     * @dev Helps initialize a dispute by assigning it a disputeId
     * @param _queryId being disputed
     * @param _timestamp being disputed
     */
    function beginDispute(bytes32 _queryId, uint256 _timestamp) external {
        // Ensure value actually exists
        require(
            tellor.getBlockNumberByTimestamp(_queryId, _timestamp) != 0,
            "no value exists at given timestamp"
        );
        bytes32 _hash = keccak256(abi.encodePacked(_queryId, _timestamp));
        // Increment vote count and push new vote round
        voteCount++;
        uint256 _disputeId = voteCount;
        voteRounds[_hash].push(_disputeId);
        // Check if dispute is started within correct time frame
        if (voteRounds[_hash].length > 1) {
            uint256 _prevId = voteRounds[_hash][voteRounds[_hash].length - 2];
            require(
                block.timestamp - voteInfo[_prevId].tallyDate < 1 days,
                "New dispute round must be started within a day"
            ); // Within a day for new round
        } else {
            require(
                block.timestamp - _timestamp < tellor.reportingLock(),
                "Dispute must be started within reporting lock time"
            ); // New dispute within reporting lock
            openDisputesOnId[_queryId]++;
        }
        // Create new vote and dispute
        Vote storage _thisVote = voteInfo[_disputeId];
        Dispute storage _thisDispute = disputeInfo[_disputeId];
        // Initialize dispute information - query ID, timestamp, value, etc.
        _thisDispute.queryId = _queryId;
        _thisDispute.timestamp = _timestamp;
        _thisDispute.value = tellor.retrieveData(_queryId, _timestamp);
        _thisDispute.disputedReporter = tellor.getReporterByTimestamp(
            _queryId,
            _timestamp
        );
        // Initialize vote information - hash, initiator, block number, etc.
        _thisVote.identifierHash = _hash;
        _thisVote.initiator = msg.sender;
        _thisVote.blockNumber = block.number;
        _thisVote.startDate = block.timestamp;
        _thisVote.voteRound = voteRounds[_hash].length;
        _thisVote.isDispute = true;
        // Calculate dispute fee based on number of current vote rounds
        uint256 _fee;
        if (voteRounds[_hash].length == 1) {
            _fee = disputeFee * 2**(openDisputesOnId[_queryId] - 1);
        } else {
            _fee = disputeFee * 2**(voteRounds[_hash].length - 1);
        }
        _thisVote.fee = _fee;
        require(
            token.transferFrom(msg.sender, address(this), _fee),
            "Fee must be paid"
        ); // This is the fork fee. Returned if dispute passes
        if (voteRounds[_hash].length == 1) {
            _thisDispute.slashedAmount = tellor.slashReporter(
                _thisDispute.disputedReporter,
                address(this)
            );
            tellor.removeValue(_queryId, _timestamp);
        } else {
            _thisDispute.slashedAmount = disputeInfo[voteRounds[_hash][0]]
                .slashedAmount;
        }
        emit NewDispute(
            _disputeId,
            _queryId,
            _timestamp,
            _thisDispute.disputedReporter
        );
    }

    /**
     * @dev Executes vote by using result and transferring balance to either
     * initiator or disputed reporter
     * @param _disputeId is the ID of the vote being executed
     */
    function executeVote(uint256 _disputeId) external {
        // Ensure validity of vote ID, vote has been executed, and vote must be tallied
        Vote storage _thisVote = voteInfo[_disputeId];
        require(_disputeId <= voteCount, "Vote ID must be valid");
        require(!_thisVote.executed, "Vote has been executed");
        require(_thisVote.tallyDate > 0, "Vote must be tallied");
        // Ensure vote must be final vote and that time has to be pass (86400 = 24 * 60 * 60 for seconds in a day)
        require(
            voteRounds[_thisVote.identifierHash].length == _thisVote.voteRound,
            "Must be the final vote"
        );
        require(
            block.timestamp - _thisVote.tallyDate >=
                86400 * _thisVote.voteRound,
            "Vote needs to be tallied and time must pass"
        );
        _thisVote.executed = true;
        if (!_thisVote.isDispute) {
            // If vote is not in dispute and passed, execute proper vote function with vote data
            if (_thisVote.result == VoteResult.PASSED) {
                address _destination = _thisVote.voteAddress;
                bool _succ;
                bytes memory _res;
                (_succ, _res) = _destination.call(
                    abi.encodePacked(_thisVote.voteFunction, _thisVote.data)
                ); // Be sure to send enough gas!
            }
            emit VoteExecuted(_disputeId, _thisVote.result);
        } else {
            Dispute storage _thisDispute = disputeInfo[_disputeId];
            if (
                voteRounds[_thisVote.identifierHash].length ==
                _thisVote.voteRound
            ) {
                openDisputesOnId[_thisDispute.queryId]--;
            }
            uint256 _i;
            uint256 _voteID;
            if (_thisVote.result == VoteResult.PASSED) {
                // If vote is in dispute and passed, iterate through each vote round and transfer the dispute to initiator
                for (
                    _i = voteRounds[_thisVote.identifierHash].length;
                    _i > 0;
                    _i--
                ) {
                    _voteID = voteRounds[_thisVote.identifierHash][_i - 1];
                    _thisVote = voteInfo[_voteID];
                    // If the first vote round, also make sure to transfer the reporter's slashed stake to the initiator
                    if (_i == 1) {
                        token.transfer(
                            _thisVote.initiator,
                            _thisDispute.slashedAmount
                        );
                    }
                    token.transfer(_thisVote.initiator, _thisVote.fee);
                }
            } else if (_thisVote.result == VoteResult.INVALID) {
                // If vote is in dispute and is invalid, iterate through each vote round and transfer the dispute fee to initiator
                for (
                    _i = voteRounds[_thisVote.identifierHash].length;
                    _i > 0;
                    _i--
                ) {
                    _voteID = voteRounds[_thisVote.identifierHash][_i - 1];
                    _thisVote = voteInfo[_voteID];
                    token.transfer(_thisVote.initiator, _thisVote.fee);
                }
                // Transfer slashed tokens back to disputed reporter
                token.transfer(
                    _thisDispute.disputedReporter,
                    _thisDispute.slashedAmount
                );
            } else if (_thisVote.result == VoteResult.FAILED) {
                // If vote is in dispute and fails, iterate through each vote round and transfer the dispute fee to disputed reporter
                uint256 _reporterReward = 0;
                for (
                    _i = voteRounds[_thisVote.identifierHash].length;
                    _i > 0;
                    _i--
                ) {
                    _voteID = voteRounds[_thisVote.identifierHash][_i - 1];
                    _thisVote = voteInfo[_voteID];
                    _reporterReward += _thisVote.fee;
                }
                _reporterReward += _thisDispute.slashedAmount;
                token.transfer(_thisDispute.disputedReporter, _reporterReward);
            }
            emit VoteExecuted(_disputeId, voteInfo[_disputeId].result);
        }
    }

    /**
     * @dev Initializes proposal to change oracle governance address
     * @param _newGovernanceAddress proposed new governance address
     * @param _timestamp used to differentiate proposals. If set to zero, timestamp
     * will automatically be reset to block timestamp
     */
    function proposeChangeGovernanceAddress(
        address _newGovernanceAddress,
        uint256 _timestamp
    ) external {
        _proposeVote(
            address(tellor),
            bytes4(keccak256(bytes("changeGovernanceAddress(address)"))),
            abi.encode(_newGovernanceAddress),
            _timestamp
        );
    }

    /**
     * @dev Initializes proposal to change reporting lock time
     * @param _newReportingLock proposed new reporting lock time
     * @param _timestamp used to differentiate proposals. If set to zero, timestamp
     * will automatically be reset to block timestamp
     */
    function proposeChangeReportingLock(
        uint256 _newReportingLock,
        uint256 _timestamp
    ) external {
        _proposeVote(
            address(tellor),
            bytes4(keccak256(bytes("changeReportingLock(uint256)"))),
            abi.encode(_newReportingLock),
            _timestamp
        );
    }

    /**
     * @dev Initializes proposal to change stake amount
     * @param _newStakeAmount proposed new stake amount
     * @param _timestamp used to differentiate proposals. If set to zero, timestamp
     * will automatically be reset to block timestamp
     */
    function proposeChangeStakeAmount(
        uint256 _newStakeAmount,
        uint256 _timestamp
    ) external {
        _proposeVote(
            address(tellor),
            bytes4(keccak256(bytes("changeStakeAmount(uint256)"))),
            abi.encode(_newStakeAmount),
            _timestamp
        );
    }

    /**
     * @dev Initializes proposal to update user stakeholder list
     * @param _address address whose user status to update
     * @param _isUser true to set address as user, false to remove address from user list
     * @param _timestamp used to differentiate proposals. If set to zero, timestamp
     * will automatically be reset to block timestamp
     */
    function proposeUpdateUserList(
        address _address,
        bool _isUser,
        uint256 _timestamp
    ) external {
        _proposeVote(
            address(this),
            bytes4(keccak256(bytes("updateUserList(address,bool)"))),
            abi.encode(_address, _isUser),
            _timestamp
        );
    }

    /**
     * @dev Tallies the votes and begins the 1 day challenge period
     * @param _disputeId is the dispute id
     */
    function tallyVotes(uint256 _disputeId) external {
        // Ensure vote has not been executed and that vote has not been tallied
        Vote storage _thisVote = voteInfo[_disputeId];
        require(!_thisVote.executed, "Dispute has already been executed");
        require(_thisVote.tallyDate == 0, "Vote has already been tallied");
        require(_disputeId <= voteCount, "Vote does not exist");
        // Determine appropriate vote duration and quorum based on dispute status
        uint256 _duration = 2 days;
        if (!_thisVote.isDispute) {
            _duration = 7 days;
        }
        // Ensure voting is not still open
        require(
            block.timestamp - _thisVote.startDate > _duration,
            "Time for voting has not elapsed"
        );

        uint256 tokenVoteSum = _thisVote.tokenholders.doesSupport +
            _thisVote.tokenholders.against +
            _thisVote.tokenholders.invalidQuery;
        uint256 reportersVoteSum = _thisVote.reporters.doesSupport +
            _thisVote.reporters.against +
            _thisVote.reporters.invalidQuery;
        uint256 multisigVoteSum = _thisVote.teamMultisig.doesSupport +
            _thisVote.teamMultisig.against +
            _thisVote.teamMultisig.invalidQuery;
        uint256 usersVoteSum = _thisVote.users.doesSupport +
            _thisVote.users.against +
            _thisVote.users.invalidQuery;
        if (
            tokenVoteSum * reportersVoteSum * multisigVoteSum * usersVoteSum ==
            0
        ) {
            if (tokenVoteSum == 0) {
                tokenVoteSum++;
            }
            if (reportersVoteSum == 0) {
                reportersVoteSum++;
            }
            if (multisigVoteSum == 0) {
                multisigVoteSum++;
            }
            if (usersVoteSum == 0) {
                usersVoteSum++;
            }
        }
        uint256 scaledDoesSupport = ((_thisVote.tokenholders.doesSupport *
            10000) / tokenVoteSum) +
            ((_thisVote.reporters.doesSupport * 10000) / reportersVoteSum) +
            ((_thisVote.teamMultisig.doesSupport * 10000) / multisigVoteSum) +
            ((_thisVote.users.doesSupport * 10000) / multisigVoteSum);
        uint256 scaledAgainst = ((_thisVote.tokenholders.against * 10000) /
            tokenVoteSum) +
            ((_thisVote.reporters.against * 10000) / reportersVoteSum) +
            ((_thisVote.teamMultisig.against * 10000) / multisigVoteSum) +
            ((_thisVote.users.against * 10000) / multisigVoteSum);
        uint256 scaledInvalid = ((_thisVote.tokenholders.invalidQuery * 10000) /
            tokenVoteSum) +
            ((_thisVote.reporters.invalidQuery * 10000) / reportersVoteSum) +
            ((_thisVote.teamMultisig.invalidQuery * 10000) / multisigVoteSum) +
            ((_thisVote.users.invalidQuery * 10000) / multisigVoteSum);

        // If there are more invalid votes than for and against, result is invalid
        if (
            scaledInvalid >= scaledDoesSupport &&
            scaledInvalid >= scaledAgainst &&
            _thisVote.isDispute
        ) {
            _thisVote.result = VoteResult.INVALID;
        } else if (scaledDoesSupport > scaledAgainst) {
            // If there are more support votes than against votes, allow the vote to pass
            _thisVote.result = VoteResult.PASSED;
        }
        // If there are more against votes than support votes, the result failed
        else {
            _thisVote.result = VoteResult.FAILED;
        }
        _thisVote.tallyDate = block.timestamp; // Update time vote was tallied
        emit VoteTallied(
            _disputeId,
            _thisVote.result,
            _thisVote.initiator,
            disputeInfo[_disputeId].disputedReporter
        );
    }

    /**
     * @dev Changes address's status as user. Can only be called by this contract
     * through a proposeUpdateUserList proposal
     * @param _address address whose user status to update
     * @param _isUser true to set address as user, false to remove address from user list
     */
    function updateUserList(address _address, bool _isUser) public {
        require(
            msg.sender == address(this),
            "Only governance can update user list"
        );
        users[_address] = _isUser;
    }

    /**
     * @dev Enables the sender address to cast a vote
     * @param _disputeId is the ID of the vote
     * @param _supports is the address's vote: whether or not they support or are against
     * @param _invalidQuery is whether or not the dispute is valid
     */
    function vote(
        uint256 _disputeId,
        bool _supports,
        bool _invalidQuery
    ) external {
        // Ensure that dispute has not been executed and that vote does not exist and is not tallied
        require(_disputeId <= voteCount, "Vote does not exist");
        Vote storage _thisVote = voteInfo[_disputeId];
        require(_thisVote.tallyDate == 0, "Vote has already been tallied");
        require(!_thisVote.voted[msg.sender], "Sender has already voted");
        // Update voting status and increment total queries for support, invalid, or against based on vote
        _thisVote.voted[msg.sender] = true;
        uint256 voteWeight = token.balanceOf(msg.sender);
        (, uint256 stakedBalance, uint256 lockedBalance, , ) = tellor
            .getStakerInfo(msg.sender);
        voteWeight += stakedBalance + lockedBalance;
        if (_thisVote.isDispute && _invalidQuery) {
            if (voteWeight > 0) {
                _thisVote.tokenholders.invalidQuery += voteWeight;
            }
            voteWeight = tellor.getReportsSubmittedByAddress(msg.sender);
            if (voteWeight > 0) {
                _thisVote.reporters.invalidQuery += voteWeight;
            }
            if (users[msg.sender]) {
                _thisVote.users.invalidQuery += 1;
            }
            if (msg.sender == teamMultisig) {
                _thisVote.teamMultisig.invalidQuery += 1;
            }
        } else if (_supports) {
            if (voteWeight > 0) {
                _thisVote.tokenholders.doesSupport += voteWeight;
            }
            voteWeight = tellor.getReportsSubmittedByAddress(msg.sender);
            if (voteWeight > 0) {
                _thisVote.reporters.doesSupport += voteWeight;
            }
            if (users[msg.sender]) {
                _thisVote.users.doesSupport += 1;
            }
            if (msg.sender == teamMultisig) {
                _thisVote.teamMultisig.doesSupport += 1;
            }
        } else {
            if (voteWeight > 0) {
                _thisVote.tokenholders.against += voteWeight;
            }
            voteWeight = tellor.getReportsSubmittedByAddress(msg.sender);
            if (voteWeight > 0) {
                _thisVote.reporters.against += voteWeight;
            }
            if (users[msg.sender]) {
                _thisVote.users.against += 1;
            }
            if (msg.sender == teamMultisig) {
                _thisVote.teamMultisig.against += 1;
            }
        }
        emit Voted(_disputeId, _supports, msg.sender, _invalidQuery);
    }

    // Getters
    /**
     * @dev Determines if an address voted for a specific vote
     * @param _disputeId is the ID of the vote
     * @param _voter is the address of the voter to check for
     * @return bool of whether or note the address voted for the specific vote
     */
    function didVote(uint256 _disputeId, address _voter)
        external
        view
        returns (bool)
    {
        return voteInfo[_disputeId].voted[_voter];
    }

    /**
     * @dev Returns info on a dispute for a given ID
     * @param _disputeId is the ID of a specific dispute
     * @return bytes32 of the data ID of the dispute
     * @return uint256 of the timestamp of the dispute
     * @return bytes memory of the value being disputed
     * @return address of the reporter being disputed
     */
    function getDisputeInfo(uint256 _disputeId)
        external
        view
        returns (
            bytes32,
            uint256,
            bytes memory,
            address
        )
    {
        Dispute storage _d = disputeInfo[_disputeId];
        return (_d.queryId, _d.timestamp, _d.value, _d.disputedReporter);
    }

    /**
     * @dev Returns the number of open disputes for a specific query ID
     * @param _queryId is the ID of a specific data feed
     * @return uint256 of the number of open disputes for the query ID
     */
    function getOpenDisputesOnId(bytes32 _queryId)
        external
        view
        returns (uint256)
    {
        return openDisputesOnId[_queryId];
    }

    /**
     * @dev Returns the total number of votes
     * @return uint256 of the total number of votes
     */
    function getVoteCount() external view returns (uint256) {
        return voteCount;
    }

    /**
     * @dev Returns info on a vote for a given vote ID
     * @param _disputeId is the ID of a specific vote
     * @return bytes32 identifier hash of the vote
     * @return uint256[8] memory of the pertinent round info (vote rounds, start date, fee, etc.)
     * @return bool[2] memory of both whether or not the vote was executed and is dispute
     * @return VoteResult result of the vote
     * @return bytes memory of the argument data of a proposal vote
     * @return bytes4 of the function selector proposed to be called
     * @return address[2] memory of the Tellor system contract address and vote initiator
     */
    function getVoteInfo(uint256 _disputeId)
        external
        view
        returns (
            bytes32,
            uint256[17] memory,
            bool[2] memory,
            VoteResult,
            bytes memory,
            bytes4,
            address[2] memory
        )
    {
        Vote storage _v = voteInfo[_disputeId];
        return (
            _v.identifierHash,
            [
                _v.voteRound,
                _v.startDate,
                _v.blockNumber,
                _v.fee,
                _v.tallyDate,
                _v.tokenholders.doesSupport,
                _v.tokenholders.against,
                _v.tokenholders.invalidQuery,
                _v.users.doesSupport,
                _v.users.against,
                _v.users.invalidQuery,
                _v.reporters.doesSupport,
                _v.reporters.against,
                _v.reporters.invalidQuery,
                _v.teamMultisig.doesSupport,
                _v.teamMultisig.against,
                _v.teamMultisig.invalidQuery
            ],
            [_v.executed, _v.isDispute],
            _v.result,
            _v.data,
            _v.voteFunction,
            [_v.voteAddress, _v.initiator]
        );
    }

    /**
     * @dev Returns an array of voting rounds for a given vote
     * @param _hash is the identifier hash for a vote
     * @return uint256[] memory dispute IDs of the vote rounds
     */
    function getVoteRounds(bytes32 _hash)
        external
        view
        returns (uint256[] memory)
    {
        return voteRounds[_hash];
    }

    /**
     * @dev Returns boolean value for whether a given address is set as a user with
     * voting rights
     * @param _address address of potential user
     * @return bool whether or not the address is set as a user
     */
    function isUser(address _address) external view returns (bool) {
        return users[_address];
    }

    // Internal
    /**
     * @dev Proposes a vote for an associated Tellor contract and function, and defines the properties of the vote
     * @param _contract is the Tellor contract to propose a vote for -> used to calculate identifier hash
     * @param _function is the Tellor function to propose a vote for -> used to calculate identifier hash
     * @param _data is the function argument data associated with the vote proposal -> used to calculate identifier hash
     * @param _timestamp is the timestamp associated with the vote -> used to calculate identifier hash
     */
    function _proposeVote(
        address _contract,
        bytes4 _function,
        bytes memory _data,
        uint256 _timestamp
    ) internal {
        // Update vote count, vote ID, current vote, and timestamp
        voteCount++;
        uint256 _disputeId = voteCount;
        Vote storage _thisVote = voteInfo[_disputeId];
        if (_timestamp == 0) {
            _timestamp = block.timestamp;
        }
        // Calculate vote identifier hash and push to vote rounds
        bytes32 _hash = keccak256(
            abi.encodePacked(_contract, _function, _data, _timestamp)
        );
        voteRounds[_hash].push(_disputeId);
        // Ensure new dispute round started within a day
        if (voteRounds[_hash].length > 1) {
            uint256 _prevId = voteRounds[_hash][voteRounds[_hash].length - 2];
            require(
                block.timestamp - voteInfo[_prevId].tallyDate < 1 days,
                "New dispute round must be started within a day"
            ); // 1 day for new disputes
        }
        // Calculate fee to propose vote. Starts as just 10 tokens flat, doubles with each round
        uint256 _fee = 10e18 * 2**(voteRounds[_hash].length - 1);
        require(
            token.transferFrom(msg.sender, address(this), _fee),
            "Fee must be paid"
        );
        // Update information on vote -- hash, vote round, start date, block number, fee, etc.
        _thisVote.identifierHash = _hash;
        _thisVote.voteRound = voteRounds[_hash].length;
        _thisVote.startDate = block.timestamp;
        _thisVote.blockNumber = block.number;
        _thisVote.fee = _fee;
        _thisVote.data = _data;
        _thisVote.voteFunction = _function;
        _thisVote.voteAddress = _contract;
        _thisVote.initiator = msg.sender;
        emit NewVote(_contract, _function, _data, _disputeId);
    }
}

File 2 of 3 : TellorFlex.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.3;

import "./interfaces/IERC20.sol";

/**
 @author Tellor Inc.
 @title TellorFlex
 @dev This is a streamlined Tellor oracle system which handles staking, reporting,
 * slashing, and user data getters in one contract. This contract is controlled
 * by a single address known as 'governance', which could be an externally owned
 * account or a contract, allowing for a flexible, modular design.
*/
contract TellorFlex {
    IERC20 public token;
    address public governance;
    uint256 public stakeAmount; //amount required to be a staker
    uint256 public totalStakeAmount; //total amount of tokens locked in contract (via stake)
    uint256 public reportingLock; // base amount of time before a reporter is able to submit a value again
    uint256 public timeOfLastNewValue = block.timestamp; // time of the last new submitted value, originally set to the block timestamp
    mapping(bytes32 => Report) private reports; // mapping of query IDs to a report
    mapping(address => StakeInfo) stakerDetails; //mapping from a persons address to their staking info

    // Structs
    struct Report {
        uint256[] timestamps; // array of all newValueTimestamps reported
        mapping(uint256 => uint256) timestampIndex; // mapping of timestamps to respective indices
        mapping(uint256 => uint256) timestampToBlockNum; // mapping of timestamp to block number
        mapping(uint256 => bytes) valueByTimestamp; // mapping of timestamps to values
        mapping(uint256 => address) reporterByTimestamp; // mapping of timestamps to reporters
    }

    struct StakeInfo {
        uint256 startDate; //stake start date
        uint256 stakedBalance; // staked balance
        uint256 lockedBalance; // amount locked for withdrawal
        uint256 reporterLastTimestamp; // timestamp of reporter's last reported value
        uint256 reportsSubmitted; // total number of reports submitted by reporter
        mapping(bytes32 => uint256) reportsSubmittedByQueryId;
    }

    // Events
    event NewGovernanceAddress(address _newGovernanceAddress);
    event NewReport(
        bytes32 _queryId,
        uint256 _time,
        bytes _value,
        uint256 _nonce,
        bytes _queryData,
        address _reporter
    );
    event NewReportingLock(uint256 _newReportingLock);
    event NewStakeAmount(uint256 _newStakeAmount);
    event NewStaker(address _staker, uint256 _amount);
    event ReporterSlashed(
        address _reporter,
        address _recipient,
        uint256 _slashAmount
    );
    event StakeWithdrawRequested(address _staker, uint256 _amount);
    event StakeWithdrawn(address _staker);
    event ValueRemoved(bytes32 _queryId, uint256 _timestamp);

    /**
     * @dev Initializes system parameters
     * @param _token address of token used for staking
     * @param _governance address which controls system
     * @param _stakeAmount amount of token needed to report oracle values
     * @param _reportingLock base amount of time (seconds) before reporter is able to report again
     */
    constructor(
        address _token,
        address _governance,
        uint256 _stakeAmount,
        uint256 _reportingLock
    ) {
        require(_token != address(0), "must set token address");
        require(_governance != address(0), "must set governance address");
        token = IERC20(_token);
        governance = _governance;
        stakeAmount = _stakeAmount;
        reportingLock = _reportingLock;
    }

    /**
     * @dev Changes governance address
     * @param _newGovernanceAddress new governance address
     */
    function changeGovernanceAddress(address _newGovernanceAddress) external {
        require(msg.sender == governance, "caller must be governance address");
        require(
            _newGovernanceAddress != address(0),
            "must set governance address"
        );
        governance = _newGovernanceAddress;
        emit NewGovernanceAddress(_newGovernanceAddress);
    }

    /**
     * @dev Changes base amount of time (seconds) before reporter is allowed to report again
     * @param _newReportingLock new reporter lock time in seconds
     */
    function changeReportingLock(uint256 _newReportingLock) external {
        require(msg.sender == governance, "caller must be governance address");
        require(
            _newReportingLock > 0,
            "reporting lock must be greater than zero"
        );
        reportingLock = _newReportingLock;
        emit NewReportingLock(_newReportingLock);
    }

    /**
     * @dev Changes amount of token stake required to report values
     * @param _newStakeAmount new reporter stake amount
     */
    function changeStakeAmount(uint256 _newStakeAmount) external {
        require(msg.sender == governance, "caller must be governance address");
        require(_newStakeAmount > 0, "stake amount must be greater than zero");
        stakeAmount = _newStakeAmount;
        emit NewStakeAmount(_newStakeAmount);
    }

    /**
     * @dev Allows a reporter to submit stake
     * @param _amount amount of tokens to stake
     */
    function depositStake(uint256 _amount) external {
        StakeInfo storage _staker = stakerDetails[msg.sender];
        if (_staker.lockedBalance > 0) {
            if (_staker.lockedBalance >= _amount) {
                _staker.lockedBalance -= _amount;
            } else {
                require(
                    token.transferFrom(
                        msg.sender,
                        address(this),
                        _amount - _staker.lockedBalance
                    )
                );
                _staker.lockedBalance = 0;
            }
        } else {
            require(token.transferFrom(msg.sender, address(this), _amount));
        }
        _staker.startDate = block.timestamp; // This resets their stake start date to now
        _staker.stakedBalance += _amount;
        totalStakeAmount += _amount;
        emit NewStaker(msg.sender, _amount);
    }

    /**
     * @dev Removes a value from the oracle.
     * Note: this function is only callable by the Governance contract.
     * @param _queryId is ID of the specific data feed
     * @param _timestamp is the timestamp of the data value to remove
     */
    function removeValue(bytes32 _queryId, uint256 _timestamp) external {
        require(msg.sender == governance, "caller must be governance address");
        Report storage rep = reports[_queryId];
        uint256 _index = rep.timestampIndex[_timestamp];
        require(_timestamp == rep.timestamps[_index], "invalid timestamp");
        // Shift all timestamps back to reflect deletion of value
        for (uint256 _i = _index; _i < rep.timestamps.length - 1; _i++) {
            rep.timestamps[_i] = rep.timestamps[_i + 1];
            rep.timestampIndex[rep.timestamps[_i]] -= 1;
        }
        // Delete and reset timestamp and value
        delete rep.timestamps[rep.timestamps.length - 1];
        rep.timestamps.pop();
        rep.valueByTimestamp[_timestamp] = "";
        rep.timestampIndex[_timestamp] = 0;
        emit ValueRemoved(_queryId, _timestamp);
    }

    /**
     * @dev Allows a reporter to request to withdraw their stake
     * @param _amount amount of staked tokens requesting to withdraw
     */
    function requestStakingWithdraw(uint256 _amount) external {
        StakeInfo storage _staker = stakerDetails[msg.sender];
        require(
            _staker.stakedBalance >= _amount,
            "insufficient staked balance"
        );
        _staker.startDate = block.timestamp;
        _staker.lockedBalance += _amount;
        _staker.stakedBalance -= _amount;
        totalStakeAmount -= _amount;
        emit StakeWithdrawRequested(msg.sender, _amount);
    }

    /**
     * @dev Slashes a reporter and transfers their stake amount to the given recipient
     * Note: this function is only callable by the governance address.
     * @param _reporter is the address of the reporter being slashed
     * @param _recipient is the address receiving the reporter's stake
     * @return uint256 amount of token slashed and sent to recipient address
     */
    function slashReporter(address _reporter, address _recipient)
        external
        returns (uint256)
    {
        require(msg.sender == governance, "only governance can slash reporter");
        StakeInfo storage _staker = stakerDetails[_reporter];
        require(
            _staker.stakedBalance + _staker.lockedBalance > 0,
            "zero staker balance"
        );
        uint256 _slashAmount;
        if (_staker.lockedBalance >= stakeAmount) {
            _slashAmount = stakeAmount;
            _staker.lockedBalance -= stakeAmount;
        } else if (
            _staker.lockedBalance + _staker.stakedBalance >= stakeAmount
        ) {
            _slashAmount = stakeAmount;
            _staker.stakedBalance -= stakeAmount - _staker.lockedBalance;
            totalStakeAmount -= stakeAmount - _staker.lockedBalance;
            _staker.lockedBalance = 0;
        } else {
            _slashAmount = _staker.stakedBalance + _staker.lockedBalance;
            totalStakeAmount -= _staker.stakedBalance;
            _staker.stakedBalance = 0;
            _staker.lockedBalance = 0;
        }
        token.transfer(_recipient, _slashAmount);
        emit ReporterSlashed(_reporter, _recipient, _slashAmount);
        return (_slashAmount);
    }

    /**
     * @dev Allows a reporter to submit a value to the oracle
     * @param _queryId is ID of the specific data feed. Equals keccak256(_queryData) for non-legacy IDs
     * @param _value is the value the user submits to the oracle
     * @param _nonce is the current value count for the query id
     * @param _queryData is the data used to fulfill the data query
     */
    function submitValue(
        bytes32 _queryId,
        bytes calldata _value,
        uint256 _nonce,
        bytes memory _queryData
    ) external {
        Report storage rep = reports[_queryId];
        require(
            _nonce == rep.timestamps.length || _nonce == 0,
            "nonce must match timestamp index"
        );
        StakeInfo storage _staker = stakerDetails[msg.sender];
        require(
            _staker.stakedBalance >= stakeAmount,
            "balance must be greater than stake amount"
        );
        // Require reporter to abide by given reporting lock
        require(
            (block.timestamp - _staker.reporterLastTimestamp) * 1000 >
                (reportingLock * 1000) / (_staker.stakedBalance / stakeAmount),
            "still in reporter time lock, please wait!"
        );
        require(
            _queryId == keccak256(_queryData) || uint256(_queryId) <= 100,
            "id must be hash of bytes data"
        );
        _staker.reporterLastTimestamp = block.timestamp;
        // Checks for no double reporting of timestamps
        require(
            rep.reporterByTimestamp[block.timestamp] == address(0),
            "timestamp already reported for"
        );
        // Update number of timestamps, value for given timestamp, and reporter for timestamp
        rep.timestampIndex[block.timestamp] = rep.timestamps.length;
        rep.timestamps.push(block.timestamp);
        rep.timestampToBlockNum[block.timestamp] = block.number;
        rep.valueByTimestamp[block.timestamp] = _value;
        rep.reporterByTimestamp[block.timestamp] = msg.sender;
        // Update last oracle value and number of values submitted by a reporter
        timeOfLastNewValue = block.timestamp;
        _staker.reportsSubmitted++;
        _staker.reportsSubmittedByQueryId[_queryId]++;
        emit NewReport(
            _queryId,
            block.timestamp,
            _value,
            _nonce,
            _queryData,
            msg.sender
        );
    }

    /**
     * @dev Withdraws a reporter's stake
     */
    function withdrawStake() external {
        StakeInfo storage _s = stakerDetails[msg.sender];
        // Ensure reporter is locked and that enough time has passed
        require(block.timestamp - _s.startDate >= 7 days, "7 days didn't pass");
        require(_s.lockedBalance > 0, "reporter not locked for withdrawal");
        token.transfer(msg.sender, _s.lockedBalance);
        _s.lockedBalance = 0;
        emit StakeWithdrawn(msg.sender);
    }

    //Getters
    /**
     * @dev Returns the block number at a given timestamp
     * @param _queryId is ID of the specific data feed
     * @param _timestamp is the timestamp to find the corresponding block number for
     * @return uint256 block number of the timestamp for the given data ID
     */
    function getBlockNumberByTimestamp(bytes32 _queryId, uint256 _timestamp)
        external
        view
        returns (uint256)
    {
        return reports[_queryId].timestampToBlockNum[_timestamp];
    }

    /**
     * @dev Returns the current value of a data feed given a specific ID
     * @param _queryId is the ID of the specific data feed
     * @return bytes memory of the current value of data
     */
    function getCurrentValue(bytes32 _queryId)
        external
        view
        returns (bytes memory)
    {
        return
            reports[_queryId].valueByTimestamp[
                reports[_queryId].timestamps[
                    reports[_queryId].timestamps.length - 1
                ]
            ];
    }

    /**
     * @dev Returns governance address
     * @return address governance
     */
    function getGovernanceAddress() external view returns (address) {
        return governance;
    }

    /**
     * @dev Counts the number of values that have been submitted for the request.
     * @param _queryId the id to look up
     * @return uint256 count of the number of values received for the id
     */
    function getNewValueCountbyQueryId(bytes32 _queryId)
        external
        view
        returns (uint256)
    {
        return reports[_queryId].timestamps.length;
    }

    /**
     * @dev Returns reporter address and whether a value was removed for a given queryId and timestamp
     * @param _queryId the id to look up
     * @param _timestamp is the timestamp of the value to look up
     * @return address reporter who submitted the value
     * @return bool true if the value was removed
     */
    function getReportDetails(bytes32 _queryId, uint256 _timestamp)
        external
        view
        returns (address, bool)
    {
        bool _wasRemoved = reports[_queryId].timestampIndex[_timestamp] == 0 &&
            keccak256(reports[_queryId].valueByTimestamp[_timestamp]) ==
            keccak256(bytes("")) &&
            reports[_queryId].reporterByTimestamp[_timestamp] != address(0);
        return (reports[_queryId].reporterByTimestamp[_timestamp], _wasRemoved);
    }

    /**
     * @dev Returns the address of the reporter who submitted a value for a data ID at a specific time
     * @param _queryId is ID of the specific data feed
     * @param _timestamp is the timestamp to find a corresponding reporter for
     * @return address of the reporter who reported the value for the data ID at the given timestamp
     */
    function getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp)
        external
        view
        returns (address)
    {
        return reports[_queryId].reporterByTimestamp[_timestamp];
    }

    /**
     * @dev Returns the timestamp of the reporter's last submission
     * @param _reporter is address of the reporter
     * @return uint256 timestamp of the reporter's last submission
     */
    function getReporterLastTimestamp(address _reporter)
        external
        view
        returns (uint256)
    {
        return stakerDetails[_reporter].reporterLastTimestamp;
    }

    /**
     * @dev Returns the reporting lock time, the amount of time a reporter must wait to submit again
     * @return uint256 reporting lock time
     */
    function getReportingLock() external view returns (uint256) {
        return reportingLock;
    }

    /**
     * @dev Returns the number of values submitted by a specific reporter address
     * @param _reporter is the address of a reporter
     * @return uint256 of the number of values submitted by the given reporter
     */
    function getReportsSubmittedByAddress(address _reporter)
        external
        view
        returns (uint256)
    {
        return stakerDetails[_reporter].reportsSubmitted;
    }

    /**
     * @dev Returns the number of values submitted to a specific queryId by a specific reporter address
     * @param _reporter is the address of a reporter
     * @param _queryId is the ID of the specific data feed
     * @return uint256 of the number of values submitted by the given reporter to the given queryId
     */
    function getReportsSubmittedByAddressAndQueryId(
        address _reporter,
        bytes32 _queryId
    ) external view returns (uint256) {
        return stakerDetails[_reporter].reportsSubmittedByQueryId[_queryId];
    }

    /**
     * @dev Returns amount required to report oracle values
     * @return uint256 stake amount
     */
    function getStakeAmount() external view returns (uint256) {
        return stakeAmount;
    }

    /**
     * @dev Allows users to retrieve all information about a staker
     * @param _staker address of staker inquiring about
     * @return uint startDate of staking
     * @return uint current amount staked
     * @return uint current amount locked for withdrawal
     * @return uint reporter's last reported timestamp
     * @return uint total number of reports submitted by reporter
     */
    function getStakerInfo(address _staker)
        external
        view
        returns (
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        return (
            stakerDetails[_staker].startDate,
            stakerDetails[_staker].stakedBalance,
            stakerDetails[_staker].lockedBalance,
            stakerDetails[_staker].reporterLastTimestamp,
            stakerDetails[_staker].reportsSubmitted
        );
    }

    /**
     * @dev Returns the timestamp for the last value of any ID from the oracle
     * @return uint256 of timestamp of the last oracle value
     */
    function getTimeOfLastNewValue() external view returns (uint256) {
        return timeOfLastNewValue;
    }

    /**
     * @dev Gets the timestamp for the value based on their index
     * @param _queryId is the id to look up
     * @param _index is the value index to look up
     * @return uint256 timestamp
     */
    function getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index)
        external
        view
        returns (uint256)
    {
        return reports[_queryId].timestamps[_index];
    }

    /**
     * @dev Returns the index of a reporter timestamp in the timestamp array for a specific data ID
     * @param _queryId is ID of the specific data feed
     * @param _timestamp is the timestamp to find in the timestamps array
     * @return uint256 of the index of the reporter timestamp in the array for specific ID
     */
    function getTimestampIndexByTimestamp(bytes32 _queryId, uint256 _timestamp)
        external
        view
        returns (uint256)
    {
        return reports[_queryId].timestampIndex[_timestamp];
    }

    /**
     * @dev Returns the address of the token used for staking
     * @return address of the token used for staking
     */
    function getTokenAddress() external view returns (address) {
        return address(token);
    }

    /**
     * @dev Returns total amount of token staked for reporting
     * @return uint256 total amount of token staked
     */
    function getTotalStakeAmount() external view returns (uint256) {
        return totalStakeAmount;
    }

    /**
     * @dev Retrieve value from oracle based on timestamp
     * @param _queryId being requested
     * @param _timestamp to retrieve data/value from
     * @return bytes value for timestamp submitted
     */
    function retrieveData(bytes32 _queryId, uint256 _timestamp)
        external
        view
        returns (bytes memory)
    {
        return reports[_queryId].valueByTimestamp[_timestamp];
    }
}

File 3 of 3 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.3;

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);

    function transfer(address recipient, uint256 amount)
        external
        returns (bool);

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_tellor","type":"address"},{"internalType":"uint256","name":"_disputeFee","type":"uint256"},{"internalType":"address","name":"_teamMultisig","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_disputeId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"_reporter","type":"address"}],"name":"NewDispute","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_contract","type":"address"},{"indexed":false,"internalType":"bytes4","name":"_function","type":"bytes4"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"_disputeId","type":"uint256"}],"name":"NewVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_disputeId","type":"uint256"},{"indexed":false,"internalType":"enum Governance.VoteResult","name":"_result","type":"uint8"}],"name":"VoteExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_disputeId","type":"uint256"},{"indexed":false,"internalType":"enum Governance.VoteResult","name":"_result","type":"uint8"},{"indexed":false,"internalType":"address","name":"_initiator","type":"address"},{"indexed":false,"internalType":"address","name":"_reporter","type":"address"}],"name":"VoteTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_disputeId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_supports","type":"bool"},{"indexed":false,"internalType":"address","name":"_voter","type":"address"},{"indexed":false,"internalType":"bool","name":"_invalidQuery","type":"bool"}],"name":"Voted","type":"event"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"beginDispute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"},{"internalType":"address","name":"_voter","type":"address"}],"name":"didVote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disputeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"}],"name":"executeVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"}],"name":"getDisputeInfo","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_queryId","type":"bytes32"}],"name":"getOpenDisputesOnId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVoteCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"}],"name":"getVoteInfo","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256[17]","name":"","type":"uint256[17]"},{"internalType":"bool[2]","name":"","type":"bool[2]"},{"internalType":"enum Governance.VoteResult","name":"","type":"uint8"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"address[2]","name":"","type":"address[2]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"getVoteRounds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isUser","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernanceAddress","type":"address"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"proposeChangeGovernanceAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newReportingLock","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"proposeChangeReportingLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newStakeAmount","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"proposeChangeStakeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"_isUser","type":"bool"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"proposeUpdateUserList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"}],"name":"tallyVotes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"teamMultisig","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tellor","outputs":[{"internalType":"contract TellorFlex","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"_isUser","type":"bool"}],"name":"updateUserList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeId","type":"uint256"},{"internalType":"bool","name":"_supports","type":"bool"},{"internalType":"bool","name":"_invalidQuery","type":"bool"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"voteCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b50604051620033d1380380620033d18339810160408190526200003491620000fc565b600080546001600160a01b0319166001600160a01b03851690811790915560408051637e062a3560e11b8152905163fc0c546a91600480820192602092909190829003018186803b1580156200008957600080fd5b505afa1580156200009e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000c4919062000143565b600180546001600160a01b03199081166001600160a01b03938416179091556004939093556002805490931691161790555062000182565b60008060006060848603121562000111578283fd5b83516200011e8162000169565b602085015160408601519194509250620001388162000169565b809150509250925092565b60006020828403121562000155578081fd5b8151620001628162000169565b9392505050565b6001600160a01b03811681146200017f57600080fd5b50565b61323f80620001926000396000f3fe608060405234801561001057600080fd5b50600436106101475760003560e01c8063a3cb1604116100c8578063dbc0c0851161008c578063ec36902511610066578063ec36902514610340578063f98a4eca14610353578063fc0c546a1461036657610147565b8063dbc0c08514610312578063df133bca14610325578063e7b3387c1461033857610147565b8063a3cb16041461029d578063a7c438bc146102b0578063b9ce896b146102ed578063c6384071146102f6578063d3b5e361146102ff57610147565b80634209fff11161010f5780634209fff1146101f25780634ac6eb7c1461022e5780634d318b0e146102415780636169c308146102545780638d8242731461027757610147565b80630e1596ef1461014c5780631959ad5b1461017f5780631f379acc146101aa57806321440a77146101bf578063248638e5146101d2575b600080fd5b61016c61015a366004612a55565b60009081526006602052604090205490565b6040519081526020015b60405180910390f35b600054610192906001600160a01b031681565b6040516001600160a01b039091168152602001610176565b6101bd6101b8366004612a6d565b610379565b005b6101bd6101cd366004612a6d565b610b2c565b6101e56101e0366004612a55565b610bb6565b6040516101769190612dd7565b61021e610200366004612957565b6001600160a01b031660009081526007602052604090205460ff1690565b6040519015158152602001610176565b6101bd61023c366004612a0e565b610c18565b6101bd61024f366004612a55565b610c9e565b610267610262366004612a55565b6111fa565b6040516101769493929190612ecb565b61028a610285366004612a55565b6112ce565b6040516101769796959493929190612e1b565b6101bd6102ab366004612996565b6114d0565b61021e6102be366004612b4f565b60008281526008602090815260408083206001600160a01b038516845260160190915290205460ff1692915050565b61016c60045481565b61016c60035481565b6101bd61030d3660046129ce565b611556565b600254610192906001600160a01b031681565b6101bd610333366004612b73565b6115dd565b60035461016c565b6101bd61034e366004612a6d565b611c0c565b6101bd610361366004612a55565b611c81565b600154610192906001600160a01b031681565b600054604051630935408d60e41b815260048101849052602481018390526001600160a01b039091169063935408d09060440160206040518083038186803b1580156103c457600080fd5b505afa1580156103d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fc9190612b37565b6104585760405162461bcd60e51b815260206004820152602260248201527f6e6f2076616c75652065786973747320617420676976656e2074696d6573746160448201526106d760f41b60648201526084015b60405180910390fd5b60408051602080820185905281830184905282518083038401815260609092019092528051910120600380549060006104908361319c565b90915550506003546000828152600960209081526040822080546001818101835582855292842001849055918490529054111561055757600082815260096020526040812080546104e390600290613107565b8154811061050157634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050620151806008600083815260200190815260200160002060050154426105349190613107565b106105515760405162461bcd60e51b815260040161044f90612f04565b5061066d565b60008054906101000a90046001600160a01b03166001600160a01b0316633321fc416040518163ffffffff1660e01b815260040160206040518083038186803b1580156105a357600080fd5b505afa1580156105b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105db9190612b37565b6105e58442613107565b1061064d5760405162461bcd60e51b815260206004820152603260248201527f44697370757465206d75737420626520737461727465642077697468696e207260448201527165706f7274696e67206c6f636b2074696d6560701b606482015260840161044f565b60008481526006602052604081208054916106678361319c565b91905055505b60008181526008602090815260408083206005909252808320878155600181018790559254905163c5958af960e01b815260048101889052602481018790529192916001600160a01b039091169063c5958af99060440160006040518083038186803b1580156106dc57600080fd5b505afa1580156106f0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107189190810190612a8e565b805161072e916002840191602090910190612881565b5060005460405163703e2a4360e11b815260048101889052602481018790526001600160a01b039091169063e07c54869060440160206040518083038186803b15801561077a57600080fd5b505afa15801561078e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b2919061297a565b600380830180546001600160a01b03939093166001600160a01b0319938416179055858455601584018054909216331790915543908301554260028301556000848152600960205260408120805460018581019190915560128501805462ff00001916620100001790559054141561085e5760008781526006602052604090205461083f90600190613107565b61084a90600261301a565b60045461085791906130e8565b9050610894565b60008581526009602052604090205461087990600190613107565b61088490600261301a565b60045461089191906130e8565b90505b60048381018290556001546040516323b872dd60e01b81523392810192909252306024830152604482018390526001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156108ee57600080fd5b505af1158015610902573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109269190612a39565b6109655760405162461bcd60e51b815260206004820152601060248201526f119959481b5d5cdd081899481c185a5960821b604482015260640161044f565b60008581526009602052604090205460011415610a7557600054600383015460405163137f0a8d60e21b81526001600160a01b039182166004820152306024820152911690634dfc2a3490604401602060405180830381600087803b1580156109cd57600080fd5b505af11580156109e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a059190612b37565b6004838101919091556000546040516316d7b73f60e21b8152918201899052602482018890526001600160a01b031690635b5edcfc90604401600060405180830381600087803b158015610a5857600080fd5b505af1158015610a6c573d6000803e3d6000fd5b50505050610acc565b6000858152600960205260408120805460059291908290610aa657634e487b7160e01b600052603260045260246000fd5b906000526020600020015481526020019081526020016000206004015482600401819055505b600382015460408051868152602081018a90529081018890526001600160a01b0390911660608201527f12b7317353cd7caa8eae8057464e3de356c1429d814fb3421797eccb19043044906080015b60405180910390a150505050505050565b600054604080518082018252601a81527f6368616e67655374616b65416d6f756e742875696e74323536290000000000006020918201528151908101859052610bb2926001600160a01b0316917fca79b5a978ea700f37e874524ca56caf88471abdb2cff892cab3e91ff005e0a191015b6040516020818303038152906040528461258a565b5050565b600081815260096020908152604091829020805483518184028101840190945280845260609392830182828015610c0c57602002820191906000526020600020905b815481526020019060010190808311610bf8575b50505050509050919050565b60005460408051808201825260208082527f6368616e6765476f7665726e616e636541646472657373286164647265737329918101919091529051610bb2926001600160a01b0316917f0636769e56486090c573831c9de80fac4458ca89aa37a2afff688bfcbc1ad71191610b9d918791016001600160a01b0391909116815260200190565b6000818152600860205260409020601281015460ff1615610d0b5760405162461bcd60e51b815260206004820152602160248201527f446973707574652068617320616c7265616479206265656e20657865637574656044820152601960fa1b606482015260840161044f565b600581015415610d5d5760405162461bcd60e51b815260206004820152601d60248201527f566f74652068617320616c7265616479206265656e2074616c6c696564000000604482015260640161044f565b600354821115610da55760405162461bcd60e51b8152602060048201526013602482015272159bdd1948191bd95cc81b9bdd08195e1a5cdd606a1b604482015260640161044f565b60128101546202a3009062010000900460ff16610dc2575062093a805b80826002015442610dd39190613107565b11610e205760405162461bcd60e51b815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686173206e6f7420656c617073656400604482015260640161044f565b60088201546007830154600684015460009291610e3c91612f9c565b610e469190612f9c565b600e840154600d850154600c860154929350600092610e659190612f9c565b610e6f9190612f9c565b60118501546010860154600f870154929350600092610e8e9190612f9c565b610e989190612f9c565b600b860154600a8701546009880154929350600092610eb79190612f9c565b610ec19190612f9c565b90508082610ecf85876130e8565b610ed991906130e8565b610ee391906130e8565b610f335783610efa5783610ef68161319c565b9450505b82610f0d5782610f098161319c565b9350505b81610f205781610f1c8161319c565b9250505b80610f335780610f2f8161319c565b9150505b60098601546000908390610f49906127106130e8565b610f539190612fb4565b600f8801548490610f66906127106130e8565b610f709190612fb4565b600c8901548690610f83906127106130e8565b610f8d9190612fb4565b60068a01548890610fa0906127106130e8565b610faa9190612fb4565b610fb49190612f9c565b610fbe9190612f9c565b610fc89190612f9c565b90506000838860090160010154612710610fe291906130e8565b610fec9190612fb4565b60108901548590610fff906127106130e8565b6110099190612fb4565b600d8a0154879061101c906127106130e8565b6110269190612fb4565b60078b01548990611039906127106130e8565b6110439190612fb4565b61104d9190612f9c565b6110579190612f9c565b6110619190612f9c565b9050600084896009016002015461271061107b91906130e8565b6110859190612fb4565b60118a01548690611098906127106130e8565b6110a29190612fb4565b600e8b015488906110b5906127106130e8565b6110bf9190612fb4565b60088c01548a906110d2906127106130e8565b6110dc9190612fb4565b6110e69190612f9c565b6110f09190612f9c565b6110fa9190612f9c565b905082811015801561110c5750818110155b80156111225750601289015462010000900460ff165b15611145576012890180546002919061ff001916610100835b0217905550611173565b81831115611165576012890180546001919061ff0019166101008361113b565b60128901805461ff00191690555b4260058a81019190915560128a015460158b015460008d81526020939093526040928390206003015492517fa2d4e500801849d40ad00f0f12ba92a5263f83ec68946e647be95cfbe581c7b6936111e6938f9361010090910460ff16926001600160a01b03918216929190911690612f66565b60405180910390a150505050505050505050565b6000818152600560205260408120805460018201546003830154600284018054869560609587959194909391926001600160a01b0390911690829061123e90613161565b80601f016020809104026020016040519081016040528092919081815260200182805461126a90613161565b80156112b75780601f1061128c576101008083540402835291602001916112b7565b820191906000526020600020905b81548152906001019060200180831161129a57829003601f168201915b505050505091509450945094509450509193509193565b60006112d8612905565b6112e0612924565b6000606060006112ee612924565b6000888152600860208181526040928390208054845161022081018652600183015481526002830154818501526003830154818701526004830154606082015260058301546080820152600683015460a0820152600783015460c08201529382015460e080860191909152600983015461010080870191909152600a840154610120870152600b840154610140870152600c840154610160870152600d840154610180870152600e8401546101a0870152600f8401546101c087015260108401546101e0870152601184015461020087015286518088018852601285015460ff80821615158352620100008204811615158389015260148701548a51808c01909b526001600160a01b03640100000000820481168c52601589015416988b0198909852601387018054979a969998939794909204169490939190911b91839061143690613161565b80601f016020809104026020016040519081016040528092919081815260200182805461146290613161565b80156114af5780601f10611484576101008083540402835291602001916114af565b820191906000526020600020905b81548152906001019060200180831161149257829003601f168201915b50505050509250975097509750975097509750975050919395979092949650565b33301461152b5760405162461bcd60e51b8152602060048201526024808201527f4f6e6c7920676f7665726e616e63652063616e207570646174652075736572206044820152631b1a5cdd60e21b606482015260840161044f565b6001600160a01b03919091166000908152600760205260409020805460ff1916911515919091179055565b604080518082018252601c81527f757064617465557365724c69737428616464726573732c626f6f6c290000000060209182015290516115d89130917fa3cb1604d428d5b2db415cab07e750952a0559e3ea14fc2ad01393fcccac6aee91610b9d9188918891016001600160a01b039290921682521515602082015260400190565b505050565b6003548311156116255760405162461bcd60e51b8152602060048201526013602482015272159bdd1948191bd95cc81b9bdd08195e1a5cdd606a1b604482015260640161044f565b60008381526008602052604090206005810154156116855760405162461bcd60e51b815260206004820152601d60248201527f566f74652068617320616c7265616479206265656e2074616c6c696564000000604482015260640161044f565b33600090815260168201602052604090205460ff16156116e75760405162461bcd60e51b815260206004820152601860248201527f53656e6465722068617320616c726561647920766f7465640000000000000000604482015260640161044f565b336000818152601683016020526040808220805460ff191660019081179091555490516370a0823160e01b8152600481019390935290916001600160a01b03909116906370a082319060240160206040518083038186803b15801561174b57600080fd5b505afa15801561175f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117839190612b37565b60008054604051630733bdef60e41b8152336004820152929350909182916001600160a01b03169063733bdef09060240160a06040518083038186803b1580156117cc57600080fd5b505afa1580156117e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118049190612bb4565b5050925092505080826118179190612f9c565b6118219084612f9c565b601285015490935062010000900460ff16801561183b5750845b1561196f578215611863578284600601600201600082825461185d9190612f9c565b90915550505b600054604051631c3c149f60e11b81523360048201526001600160a01b0390911690633878293e9060240160206040518083038186803b1580156118a657600080fd5b505afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190612b37565b92508215611903578284600c0160020160008282546118fd9190612f9c565b90915550505b3360009081526007602052604090205460ff16156119395760018460090160020160008282546119339190612f9c565b90915550505b6002546001600160a01b031633141561196a57600184600f0160020160008282546119649190612f9c565b90915550505b611bc3565b8515611a9957821561199857828460060160000160008282546119929190612f9c565b90915550505b600054604051631c3c149f60e11b81523360048201526001600160a01b0390911690633878293e9060240160206040518083038186803b1580156119db57600080fd5b505afa1580156119ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a139190612b37565b92508215611a38578284600c016000016000828254611a329190612f9c565b90915550505b3360009081526007602052604090205460ff1615611a6e576001846009016000016000828254611a689190612f9c565b90915550505b6002546001600160a01b031633141561196a57600184600f0160000160008282546119649190612f9c565b8215611abc5782846006016001016000828254611ab69190612f9c565b90915550505b600054604051631c3c149f60e11b81523360048201526001600160a01b0390911690633878293e9060240160206040518083038186803b158015611aff57600080fd5b505afa158015611b13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b379190612b37565b92508215611b5c578284600c016001016000828254611b569190612f9c565b90915550505b3360009081526007602052604090205460ff1615611b92576001846009016001016000828254611b8c9190612f9c565b90915550505b6002546001600160a01b0316331415611bc357600184600f016001016000828254611bbd9190612f9c565b90915550505b604080518881528715156020820152339181019190915285151560608201527fbe6f1c58cc15c8e86d6f0ef23c5a30eb33319af3b57f6b7d9b56ccfa87696b8490608001610b1b565b600054604080518082018252601c81527f6368616e67655265706f7274696e674c6f636b2875696e7432353629000000006020918201528151908101859052610bb2926001600160a01b0316917f5d183cfa1084f72f49f0f81fe5d34bf9533a659ae85960ce554cbcf02302ca309101610b9d565b6000818152600860205260409020600354821115611ce15760405162461bcd60e51b815260206004820152601560248201527f566f7465204944206d7573742062652076616c69640000000000000000000000604482015260640161044f565b601281015460ff1615611d365760405162461bcd60e51b815260206004820152601660248201527f566f746520686173206265656e20657865637574656400000000000000000000604482015260640161044f565b6000816005015411611d8a5760405162461bcd60e51b815260206004820152601460248201527f566f7465206d7573742062652074616c6c696564000000000000000000000000604482015260640161044f565b6001810154815460009081526009602052604090205414611ded5760405162461bcd60e51b815260206004820152601660248201527f4d757374206265207468652066696e616c20766f746500000000000000000000604482015260640161044f565b6001810154611dff90620151806130e8565b6005820154611e0e9042613107565b1015611e705760405162461bcd60e51b815260206004820152602b60248201527f566f7465206e6565647320746f2062652074616c6c69656420616e642074696d60448201526a65206d757374207061737360a81b606482015260840161044f565b60128101805460ff19166001179081905562010000900460ff16611fa75760016012820154610100900460ff166002811115611ebc57634e487b7160e01b600052602160045260246000fd5b1415611f5c5760148101546040516001600160a01b03640100000000830416916000916060918491611ef99160e01b906013880190602001612cc5565b60408051601f1981840301815290829052611f1391612d79565b6000604051808303816000865af19150503d8060008114611f50576040519150601f19603f3d011682016040523d82523d6000602084013e611f55565b606091505b5050505050505b60128101546040517f40d231bf91823121de9e1c012d95f835ea5684dc1d93360d9510a30543345da491611f9a918591610100900460ff1690612f52565b60405180910390a1610bb2565b600082815260056020908152604080832060018501548554855260099093529220541415611ff15780546000908152600660205260408120805491611feb8361314a565b91905055505b60008060016012850154610100900460ff16600281111561202257634e487b7160e01b600052602160045260246000fd5b14156121e057835460009081526009602052604090205491505b81156121db578354600090815260096020526040902061205d600184613107565b8154811061207b57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050600860008281526020019081526020016000209350816001141561213857600154601585015460048581015460405163a9059cbb60e01b81526001600160a01b0393841692810192909252602482015291169063a9059cbb90604401602060405180830381600087803b1580156120fe57600080fd5b505af1158015612112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121369190612a39565b505b600154601585015460048087015460405163a9059cbb60e01b81526001600160a01b0393841692810192909252602482015291169063a9059cbb90604401602060405180830381600087803b15801561219057600080fd5b505af11580156121a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121c89190612a39565b50816121d38161314a565b92505061203c565b61252f565b60026012850154610100900460ff16600281111561220e57634e487b7160e01b600052602160045260246000fd5b14156123c457835460009081526009602052604090205491505b811561232e5783546000908152600960205260409020612249600184613107565b8154811061226757634e487b7160e01b600052603260045260246000fd5b60009182526020808320919091015480835260089091526040918290206001546015820154600480840154955163a9059cbb60e01b81526001600160a01b03928316918101919091526024810195909552919750919350169063a9059cbb90604401602060405180830381600087803b1580156122e357600080fd5b505af11580156122f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231b9190612a39565b50816123268161314a565b925050612228565b600154600384015460048086015460405163a9059cbb60e01b81526001600160a01b0393841692810192909252602482015291169063a9059cbb90604401602060405180830381600087803b15801561238657600080fd5b505af115801561239a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123be9190612a39565b5061252f565b60006012850154610100900460ff1660028111156123f257634e487b7160e01b600052602160045260246000fd5b141561252f57835460009081526009602052604081205492505b8215612491578454600090815260096020526040902061242d600185613107565b8154811061244b57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154915060086000838152602001908152602001600020945084600401548161247d9190612f9c565b9050826124898161314a565b93505061240c565b60048401546124a09082612f9c565b600154600386015460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101849052929350169063a9059cbb90604401602060405180830381600087803b1580156124f457600080fd5b505af1158015612508573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252c9190612a39565b50505b600085815260086020526040908190206012015490517f40d231bf91823121de9e1c012d95f835ea5684dc1d93360d9510a30543345da49161257b918891610100900460ff1690612f52565b60405180910390a15050505050565b6003805490600061259a8361319c565b90915550506003546000818152600860205260409020826125b9574292505b6000868686866040516020016125d29493929190612c73565b60408051601f1981840301815291815281516020928301206000818152600984529182208054600181810183558285529484200187905591819052905490925011156126a4576000818152600960205260408120805461263490600290613107565b8154811061265257634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050620151806008600083815260200190815260200160002060050154426126859190613107565b106126a25760405162461bcd60e51b815260040161044f90612f04565b505b6000818152600960205260408120546126bf90600190613107565b6126ca90600261301a565b6126dc90678ac7230489e800006130e8565b6001546040516323b872dd60e01b8152336004820152306024820152604481018390529192506001600160a01b0316906323b872dd90606401602060405180830381600087803b15801561272f57600080fd5b505af1158015612743573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127679190612a39565b6127a65760405162461bcd60e51b815260206004820152601060248201526f119959481b5d5cdd081899481c185a5960821b604482015260640161044f565b81835560008281526009602090815260409091205460018501554260028501554360038501556004840182905586516127e791601386019190890190612881565b506014830180546001600160a01b038a166401000000000277ffffffffffffffffffffffffffffffffffffffffffffffff1990911660e08a901c171790556015830180546001600160a01b031916331790556040517f03cd1db94c84fbf802bb289f9fec190fc43fcb105eee5554433e8d642ceab1189061286f908a908a908a908990612d95565b60405180910390a15050505050505050565b82805461288d90613161565b90600052602060002090601f0160209004810192826128af57600085556128f5565b82601f106128c857805160ff19168380011785556128f5565b828001600101855582156128f5579182015b828111156128f55782518255916020019190600101906128da565b50612901929150612942565b5090565b6040518061022001604052806011906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b5b808211156129015760008155600101612943565b600060208284031215612968578081fd5b8135612973816131e3565b9392505050565b60006020828403121561298b578081fd5b8151612973816131e3565b600080604083850312156129a8578081fd5b82356129b3816131e3565b915060208301356129c3816131fb565b809150509250929050565b6000806000606084860312156129e2578081fd5b83356129ed816131e3565b925060208401356129fd816131fb565b929592945050506040919091013590565b60008060408385031215612a20578182fd5b8235612a2b816131e3565b946020939093013593505050565b600060208284031215612a4a578081fd5b8151612973816131fb565b600060208284031215612a66578081fd5b5035919050565b60008060408385031215612a7f578182fd5b50508035926020909101359150565b600060208284031215612a9f578081fd5b815167ffffffffffffffff80821115612ab6578283fd5b818401915084601f830112612ac9578283fd5b815181811115612adb57612adb6131cd565b604051601f8201601f19908116603f01168101908382118183101715612b0357612b036131cd565b81604052828152876020848701011115612b1b578586fd5b612b2c83602083016020880161311e565b979650505050505050565b600060208284031215612b48578081fd5b5051919050565b60008060408385031215612b61578182fd5b8235915060208301356129c3816131e3565b600080600060608486031215612b87578283fd5b833592506020840135612b99816131fb565b91506040840135612ba9816131fb565b809150509250925092565b600080600080600060a08688031215612bcb578081fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b8060005b6002811015612c1f5781516001600160a01b0316845260209384019390910190600101612bf7565b50505050565b60008151808452612c3d81602086016020860161311e565b601f01601f19169290920160200192915050565b60038110612c6f57634e487b7160e01b600052602160045260246000fd5b9052565b606085901b6bffffffffffffffffffffffff191681526001600160e01b0319841660148201528251600090612caf81601885016020880161311e565b6018920191820192909252603801949350505050565b6001600160e01b03198316815281546000906004908290600181811c9080831680612cf157607f831692505b6020808410821415612d1057634e487b7160e01b885260228752602488fd5b818015612d245760018114612d3957612d69565b60ff1986168a890152848a0188019650612d69565b60008b815260209020895b86811015612d5f5781548c82018b0152908501908301612d44565b505087858b010196505b50949a9950505050505050505050565b60008251612d8b81846020870161311e565b9190910192915050565b60006001600160a01b038616825263ffffffff60e01b8516602083015260806040830152612dc66080830185612c25565b905082606083015295945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e0f57835183529284019291840191600101612df3565b50909695505050505050565b600061032089835260208084018a845b6011811015612e4857815183529183019190830190600101612e2b565b505050610240840189845b6002811015612e72578151151583529183019190830190600101612e53565b50505050612e84610280840188612c51565b806102a0840152612e9781840187612c25565b915050612eb16102c08301856001600160e01b0319169052565b612ebf6102e0830184612bf3565b98975050505050505050565b600085825284602083015260806040830152612eea6080830185612c25565b90506001600160a01b038316606083015295945050505050565b6020808252602e908201527f4e6577206469737075746520726f756e64206d7573742062652073746172746560408201526d642077697468696e20612064617960901b606082015260800190565b828152604081016129736020830184612c51565b84815260808101612f7a6020830186612c51565b6001600160a01b03808516604084015280841660608401525095945050505050565b60008219821115612faf57612faf6131b7565b500190565b600082612fcf57634e487b7160e01b81526012600452602481fd5b500490565b80825b6001808611612fe65750613011565b818704821115612ff857612ff86131b7565b8086161561300557918102915b9490941c938002612fd7565b94509492505050565b6000612973600019848460008261303357506001612973565b8161304057506000612973565b816001811461305657600281146130605761308d565b6001915050612973565b60ff841115613071576130716131b7565b6001841b915084821115613087576130876131b7565b50612973565b5060208310610133831016604e8410600b84101617156130c0575081810a838111156130bb576130bb6131b7565b612973565b6130cd8484846001612fd4565b8086048211156130df576130df6131b7565b02949350505050565b6000816000190483118215151615613102576131026131b7565b500290565b600082821015613119576131196131b7565b500390565b60005b83811015613139578181015183820152602001613121565b83811115612c1f5750506000910152565b600081613159576131596131b7565b506000190190565b600181811c9082168061317557607f821691505b6020821081141561319657634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156131b0576131b06131b7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146131f857600080fd5b50565b80151581146131f857600080fdfea26469706673582212200e66ea4a5edfc6ebd8a2364676a30b97a0e04b0be80b6d19a89932b9eba6e74364736f6c6343000803003300000000000000000000000041b66dd93b03e89d29114a7613a6f9f0d4f401780000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000080fc34a2f9ffe86f41580f47368289c402dec660

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101475760003560e01c8063a3cb1604116100c8578063dbc0c0851161008c578063ec36902511610066578063ec36902514610340578063f98a4eca14610353578063fc0c546a1461036657610147565b8063dbc0c08514610312578063df133bca14610325578063e7b3387c1461033857610147565b8063a3cb16041461029d578063a7c438bc146102b0578063b9ce896b146102ed578063c6384071146102f6578063d3b5e361146102ff57610147565b80634209fff11161010f5780634209fff1146101f25780634ac6eb7c1461022e5780634d318b0e146102415780636169c308146102545780638d8242731461027757610147565b80630e1596ef1461014c5780631959ad5b1461017f5780631f379acc146101aa57806321440a77146101bf578063248638e5146101d2575b600080fd5b61016c61015a366004612a55565b60009081526006602052604090205490565b6040519081526020015b60405180910390f35b600054610192906001600160a01b031681565b6040516001600160a01b039091168152602001610176565b6101bd6101b8366004612a6d565b610379565b005b6101bd6101cd366004612a6d565b610b2c565b6101e56101e0366004612a55565b610bb6565b6040516101769190612dd7565b61021e610200366004612957565b6001600160a01b031660009081526007602052604090205460ff1690565b6040519015158152602001610176565b6101bd61023c366004612a0e565b610c18565b6101bd61024f366004612a55565b610c9e565b610267610262366004612a55565b6111fa565b6040516101769493929190612ecb565b61028a610285366004612a55565b6112ce565b6040516101769796959493929190612e1b565b6101bd6102ab366004612996565b6114d0565b61021e6102be366004612b4f565b60008281526008602090815260408083206001600160a01b038516845260160190915290205460ff1692915050565b61016c60045481565b61016c60035481565b6101bd61030d3660046129ce565b611556565b600254610192906001600160a01b031681565b6101bd610333366004612b73565b6115dd565b60035461016c565b6101bd61034e366004612a6d565b611c0c565b6101bd610361366004612a55565b611c81565b600154610192906001600160a01b031681565b600054604051630935408d60e41b815260048101849052602481018390526001600160a01b039091169063935408d09060440160206040518083038186803b1580156103c457600080fd5b505afa1580156103d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fc9190612b37565b6104585760405162461bcd60e51b815260206004820152602260248201527f6e6f2076616c75652065786973747320617420676976656e2074696d6573746160448201526106d760f41b60648201526084015b60405180910390fd5b60408051602080820185905281830184905282518083038401815260609092019092528051910120600380549060006104908361319c565b90915550506003546000828152600960209081526040822080546001818101835582855292842001849055918490529054111561055757600082815260096020526040812080546104e390600290613107565b8154811061050157634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050620151806008600083815260200190815260200160002060050154426105349190613107565b106105515760405162461bcd60e51b815260040161044f90612f04565b5061066d565b60008054906101000a90046001600160a01b03166001600160a01b0316633321fc416040518163ffffffff1660e01b815260040160206040518083038186803b1580156105a357600080fd5b505afa1580156105b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105db9190612b37565b6105e58442613107565b1061064d5760405162461bcd60e51b815260206004820152603260248201527f44697370757465206d75737420626520737461727465642077697468696e207260448201527165706f7274696e67206c6f636b2074696d6560701b606482015260840161044f565b60008481526006602052604081208054916106678361319c565b91905055505b60008181526008602090815260408083206005909252808320878155600181018790559254905163c5958af960e01b815260048101889052602481018790529192916001600160a01b039091169063c5958af99060440160006040518083038186803b1580156106dc57600080fd5b505afa1580156106f0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107189190810190612a8e565b805161072e916002840191602090910190612881565b5060005460405163703e2a4360e11b815260048101889052602481018790526001600160a01b039091169063e07c54869060440160206040518083038186803b15801561077a57600080fd5b505afa15801561078e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b2919061297a565b600380830180546001600160a01b03939093166001600160a01b0319938416179055858455601584018054909216331790915543908301554260028301556000848152600960205260408120805460018581019190915560128501805462ff00001916620100001790559054141561085e5760008781526006602052604090205461083f90600190613107565b61084a90600261301a565b60045461085791906130e8565b9050610894565b60008581526009602052604090205461087990600190613107565b61088490600261301a565b60045461089191906130e8565b90505b60048381018290556001546040516323b872dd60e01b81523392810192909252306024830152604482018390526001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156108ee57600080fd5b505af1158015610902573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109269190612a39565b6109655760405162461bcd60e51b815260206004820152601060248201526f119959481b5d5cdd081899481c185a5960821b604482015260640161044f565b60008581526009602052604090205460011415610a7557600054600383015460405163137f0a8d60e21b81526001600160a01b039182166004820152306024820152911690634dfc2a3490604401602060405180830381600087803b1580156109cd57600080fd5b505af11580156109e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a059190612b37565b6004838101919091556000546040516316d7b73f60e21b8152918201899052602482018890526001600160a01b031690635b5edcfc90604401600060405180830381600087803b158015610a5857600080fd5b505af1158015610a6c573d6000803e3d6000fd5b50505050610acc565b6000858152600960205260408120805460059291908290610aa657634e487b7160e01b600052603260045260246000fd5b906000526020600020015481526020019081526020016000206004015482600401819055505b600382015460408051868152602081018a90529081018890526001600160a01b0390911660608201527f12b7317353cd7caa8eae8057464e3de356c1429d814fb3421797eccb19043044906080015b60405180910390a150505050505050565b600054604080518082018252601a81527f6368616e67655374616b65416d6f756e742875696e74323536290000000000006020918201528151908101859052610bb2926001600160a01b0316917fca79b5a978ea700f37e874524ca56caf88471abdb2cff892cab3e91ff005e0a191015b6040516020818303038152906040528461258a565b5050565b600081815260096020908152604091829020805483518184028101840190945280845260609392830182828015610c0c57602002820191906000526020600020905b815481526020019060010190808311610bf8575b50505050509050919050565b60005460408051808201825260208082527f6368616e6765476f7665726e616e636541646472657373286164647265737329918101919091529051610bb2926001600160a01b0316917f0636769e56486090c573831c9de80fac4458ca89aa37a2afff688bfcbc1ad71191610b9d918791016001600160a01b0391909116815260200190565b6000818152600860205260409020601281015460ff1615610d0b5760405162461bcd60e51b815260206004820152602160248201527f446973707574652068617320616c7265616479206265656e20657865637574656044820152601960fa1b606482015260840161044f565b600581015415610d5d5760405162461bcd60e51b815260206004820152601d60248201527f566f74652068617320616c7265616479206265656e2074616c6c696564000000604482015260640161044f565b600354821115610da55760405162461bcd60e51b8152602060048201526013602482015272159bdd1948191bd95cc81b9bdd08195e1a5cdd606a1b604482015260640161044f565b60128101546202a3009062010000900460ff16610dc2575062093a805b80826002015442610dd39190613107565b11610e205760405162461bcd60e51b815260206004820152601f60248201527f54696d6520666f7220766f74696e6720686173206e6f7420656c617073656400604482015260640161044f565b60088201546007830154600684015460009291610e3c91612f9c565b610e469190612f9c565b600e840154600d850154600c860154929350600092610e659190612f9c565b610e6f9190612f9c565b60118501546010860154600f870154929350600092610e8e9190612f9c565b610e989190612f9c565b600b860154600a8701546009880154929350600092610eb79190612f9c565b610ec19190612f9c565b90508082610ecf85876130e8565b610ed991906130e8565b610ee391906130e8565b610f335783610efa5783610ef68161319c565b9450505b82610f0d5782610f098161319c565b9350505b81610f205781610f1c8161319c565b9250505b80610f335780610f2f8161319c565b9150505b60098601546000908390610f49906127106130e8565b610f539190612fb4565b600f8801548490610f66906127106130e8565b610f709190612fb4565b600c8901548690610f83906127106130e8565b610f8d9190612fb4565b60068a01548890610fa0906127106130e8565b610faa9190612fb4565b610fb49190612f9c565b610fbe9190612f9c565b610fc89190612f9c565b90506000838860090160010154612710610fe291906130e8565b610fec9190612fb4565b60108901548590610fff906127106130e8565b6110099190612fb4565b600d8a0154879061101c906127106130e8565b6110269190612fb4565b60078b01548990611039906127106130e8565b6110439190612fb4565b61104d9190612f9c565b6110579190612f9c565b6110619190612f9c565b9050600084896009016002015461271061107b91906130e8565b6110859190612fb4565b60118a01548690611098906127106130e8565b6110a29190612fb4565b600e8b015488906110b5906127106130e8565b6110bf9190612fb4565b60088c01548a906110d2906127106130e8565b6110dc9190612fb4565b6110e69190612f9c565b6110f09190612f9c565b6110fa9190612f9c565b905082811015801561110c5750818110155b80156111225750601289015462010000900460ff165b15611145576012890180546002919061ff001916610100835b0217905550611173565b81831115611165576012890180546001919061ff0019166101008361113b565b60128901805461ff00191690555b4260058a81019190915560128a015460158b015460008d81526020939093526040928390206003015492517fa2d4e500801849d40ad00f0f12ba92a5263f83ec68946e647be95cfbe581c7b6936111e6938f9361010090910460ff16926001600160a01b03918216929190911690612f66565b60405180910390a150505050505050505050565b6000818152600560205260408120805460018201546003830154600284018054869560609587959194909391926001600160a01b0390911690829061123e90613161565b80601f016020809104026020016040519081016040528092919081815260200182805461126a90613161565b80156112b75780601f1061128c576101008083540402835291602001916112b7565b820191906000526020600020905b81548152906001019060200180831161129a57829003601f168201915b505050505091509450945094509450509193509193565b60006112d8612905565b6112e0612924565b6000606060006112ee612924565b6000888152600860208181526040928390208054845161022081018652600183015481526002830154818501526003830154818701526004830154606082015260058301546080820152600683015460a0820152600783015460c08201529382015460e080860191909152600983015461010080870191909152600a840154610120870152600b840154610140870152600c840154610160870152600d840154610180870152600e8401546101a0870152600f8401546101c087015260108401546101e0870152601184015461020087015286518088018852601285015460ff80821615158352620100008204811615158389015260148701548a51808c01909b526001600160a01b03640100000000820481168c52601589015416988b0198909852601387018054979a969998939794909204169490939190911b91839061143690613161565b80601f016020809104026020016040519081016040528092919081815260200182805461146290613161565b80156114af5780601f10611484576101008083540402835291602001916114af565b820191906000526020600020905b81548152906001019060200180831161149257829003601f168201915b50505050509250975097509750975097509750975050919395979092949650565b33301461152b5760405162461bcd60e51b8152602060048201526024808201527f4f6e6c7920676f7665726e616e63652063616e207570646174652075736572206044820152631b1a5cdd60e21b606482015260840161044f565b6001600160a01b03919091166000908152600760205260409020805460ff1916911515919091179055565b604080518082018252601c81527f757064617465557365724c69737428616464726573732c626f6f6c290000000060209182015290516115d89130917fa3cb1604d428d5b2db415cab07e750952a0559e3ea14fc2ad01393fcccac6aee91610b9d9188918891016001600160a01b039290921682521515602082015260400190565b505050565b6003548311156116255760405162461bcd60e51b8152602060048201526013602482015272159bdd1948191bd95cc81b9bdd08195e1a5cdd606a1b604482015260640161044f565b60008381526008602052604090206005810154156116855760405162461bcd60e51b815260206004820152601d60248201527f566f74652068617320616c7265616479206265656e2074616c6c696564000000604482015260640161044f565b33600090815260168201602052604090205460ff16156116e75760405162461bcd60e51b815260206004820152601860248201527f53656e6465722068617320616c726561647920766f7465640000000000000000604482015260640161044f565b336000818152601683016020526040808220805460ff191660019081179091555490516370a0823160e01b8152600481019390935290916001600160a01b03909116906370a082319060240160206040518083038186803b15801561174b57600080fd5b505afa15801561175f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117839190612b37565b60008054604051630733bdef60e41b8152336004820152929350909182916001600160a01b03169063733bdef09060240160a06040518083038186803b1580156117cc57600080fd5b505afa1580156117e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118049190612bb4565b5050925092505080826118179190612f9c565b6118219084612f9c565b601285015490935062010000900460ff16801561183b5750845b1561196f578215611863578284600601600201600082825461185d9190612f9c565b90915550505b600054604051631c3c149f60e11b81523360048201526001600160a01b0390911690633878293e9060240160206040518083038186803b1580156118a657600080fd5b505afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190612b37565b92508215611903578284600c0160020160008282546118fd9190612f9c565b90915550505b3360009081526007602052604090205460ff16156119395760018460090160020160008282546119339190612f9c565b90915550505b6002546001600160a01b031633141561196a57600184600f0160020160008282546119649190612f9c565b90915550505b611bc3565b8515611a9957821561199857828460060160000160008282546119929190612f9c565b90915550505b600054604051631c3c149f60e11b81523360048201526001600160a01b0390911690633878293e9060240160206040518083038186803b1580156119db57600080fd5b505afa1580156119ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a139190612b37565b92508215611a38578284600c016000016000828254611a329190612f9c565b90915550505b3360009081526007602052604090205460ff1615611a6e576001846009016000016000828254611a689190612f9c565b90915550505b6002546001600160a01b031633141561196a57600184600f0160000160008282546119649190612f9c565b8215611abc5782846006016001016000828254611ab69190612f9c565b90915550505b600054604051631c3c149f60e11b81523360048201526001600160a01b0390911690633878293e9060240160206040518083038186803b158015611aff57600080fd5b505afa158015611b13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b379190612b37565b92508215611b5c578284600c016001016000828254611b569190612f9c565b90915550505b3360009081526007602052604090205460ff1615611b92576001846009016001016000828254611b8c9190612f9c565b90915550505b6002546001600160a01b0316331415611bc357600184600f016001016000828254611bbd9190612f9c565b90915550505b604080518881528715156020820152339181019190915285151560608201527fbe6f1c58cc15c8e86d6f0ef23c5a30eb33319af3b57f6b7d9b56ccfa87696b8490608001610b1b565b600054604080518082018252601c81527f6368616e67655265706f7274696e674c6f636b2875696e7432353629000000006020918201528151908101859052610bb2926001600160a01b0316917f5d183cfa1084f72f49f0f81fe5d34bf9533a659ae85960ce554cbcf02302ca309101610b9d565b6000818152600860205260409020600354821115611ce15760405162461bcd60e51b815260206004820152601560248201527f566f7465204944206d7573742062652076616c69640000000000000000000000604482015260640161044f565b601281015460ff1615611d365760405162461bcd60e51b815260206004820152601660248201527f566f746520686173206265656e20657865637574656400000000000000000000604482015260640161044f565b6000816005015411611d8a5760405162461bcd60e51b815260206004820152601460248201527f566f7465206d7573742062652074616c6c696564000000000000000000000000604482015260640161044f565b6001810154815460009081526009602052604090205414611ded5760405162461bcd60e51b815260206004820152601660248201527f4d757374206265207468652066696e616c20766f746500000000000000000000604482015260640161044f565b6001810154611dff90620151806130e8565b6005820154611e0e9042613107565b1015611e705760405162461bcd60e51b815260206004820152602b60248201527f566f7465206e6565647320746f2062652074616c6c69656420616e642074696d60448201526a65206d757374207061737360a81b606482015260840161044f565b60128101805460ff19166001179081905562010000900460ff16611fa75760016012820154610100900460ff166002811115611ebc57634e487b7160e01b600052602160045260246000fd5b1415611f5c5760148101546040516001600160a01b03640100000000830416916000916060918491611ef99160e01b906013880190602001612cc5565b60408051601f1981840301815290829052611f1391612d79565b6000604051808303816000865af19150503d8060008114611f50576040519150601f19603f3d011682016040523d82523d6000602084013e611f55565b606091505b5050505050505b60128101546040517f40d231bf91823121de9e1c012d95f835ea5684dc1d93360d9510a30543345da491611f9a918591610100900460ff1690612f52565b60405180910390a1610bb2565b600082815260056020908152604080832060018501548554855260099093529220541415611ff15780546000908152600660205260408120805491611feb8361314a565b91905055505b60008060016012850154610100900460ff16600281111561202257634e487b7160e01b600052602160045260246000fd5b14156121e057835460009081526009602052604090205491505b81156121db578354600090815260096020526040902061205d600184613107565b8154811061207b57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050600860008281526020019081526020016000209350816001141561213857600154601585015460048581015460405163a9059cbb60e01b81526001600160a01b0393841692810192909252602482015291169063a9059cbb90604401602060405180830381600087803b1580156120fe57600080fd5b505af1158015612112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121369190612a39565b505b600154601585015460048087015460405163a9059cbb60e01b81526001600160a01b0393841692810192909252602482015291169063a9059cbb90604401602060405180830381600087803b15801561219057600080fd5b505af11580156121a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121c89190612a39565b50816121d38161314a565b92505061203c565b61252f565b60026012850154610100900460ff16600281111561220e57634e487b7160e01b600052602160045260246000fd5b14156123c457835460009081526009602052604090205491505b811561232e5783546000908152600960205260409020612249600184613107565b8154811061226757634e487b7160e01b600052603260045260246000fd5b60009182526020808320919091015480835260089091526040918290206001546015820154600480840154955163a9059cbb60e01b81526001600160a01b03928316918101919091526024810195909552919750919350169063a9059cbb90604401602060405180830381600087803b1580156122e357600080fd5b505af11580156122f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231b9190612a39565b50816123268161314a565b925050612228565b600154600384015460048086015460405163a9059cbb60e01b81526001600160a01b0393841692810192909252602482015291169063a9059cbb90604401602060405180830381600087803b15801561238657600080fd5b505af115801561239a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123be9190612a39565b5061252f565b60006012850154610100900460ff1660028111156123f257634e487b7160e01b600052602160045260246000fd5b141561252f57835460009081526009602052604081205492505b8215612491578454600090815260096020526040902061242d600185613107565b8154811061244b57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154915060086000838152602001908152602001600020945084600401548161247d9190612f9c565b9050826124898161314a565b93505061240c565b60048401546124a09082612f9c565b600154600386015460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101849052929350169063a9059cbb90604401602060405180830381600087803b1580156124f457600080fd5b505af1158015612508573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252c9190612a39565b50505b600085815260086020526040908190206012015490517f40d231bf91823121de9e1c012d95f835ea5684dc1d93360d9510a30543345da49161257b918891610100900460ff1690612f52565b60405180910390a15050505050565b6003805490600061259a8361319c565b90915550506003546000818152600860205260409020826125b9574292505b6000868686866040516020016125d29493929190612c73565b60408051601f1981840301815291815281516020928301206000818152600984529182208054600181810183558285529484200187905591819052905490925011156126a4576000818152600960205260408120805461263490600290613107565b8154811061265257634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050620151806008600083815260200190815260200160002060050154426126859190613107565b106126a25760405162461bcd60e51b815260040161044f90612f04565b505b6000818152600960205260408120546126bf90600190613107565b6126ca90600261301a565b6126dc90678ac7230489e800006130e8565b6001546040516323b872dd60e01b8152336004820152306024820152604481018390529192506001600160a01b0316906323b872dd90606401602060405180830381600087803b15801561272f57600080fd5b505af1158015612743573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127679190612a39565b6127a65760405162461bcd60e51b815260206004820152601060248201526f119959481b5d5cdd081899481c185a5960821b604482015260640161044f565b81835560008281526009602090815260409091205460018501554260028501554360038501556004840182905586516127e791601386019190890190612881565b506014830180546001600160a01b038a166401000000000277ffffffffffffffffffffffffffffffffffffffffffffffff1990911660e08a901c171790556015830180546001600160a01b031916331790556040517f03cd1db94c84fbf802bb289f9fec190fc43fcb105eee5554433e8d642ceab1189061286f908a908a908a908990612d95565b60405180910390a15050505050505050565b82805461288d90613161565b90600052602060002090601f0160209004810192826128af57600085556128f5565b82601f106128c857805160ff19168380011785556128f5565b828001600101855582156128f5579182015b828111156128f55782518255916020019190600101906128da565b50612901929150612942565b5090565b6040518061022001604052806011906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b5b808211156129015760008155600101612943565b600060208284031215612968578081fd5b8135612973816131e3565b9392505050565b60006020828403121561298b578081fd5b8151612973816131e3565b600080604083850312156129a8578081fd5b82356129b3816131e3565b915060208301356129c3816131fb565b809150509250929050565b6000806000606084860312156129e2578081fd5b83356129ed816131e3565b925060208401356129fd816131fb565b929592945050506040919091013590565b60008060408385031215612a20578182fd5b8235612a2b816131e3565b946020939093013593505050565b600060208284031215612a4a578081fd5b8151612973816131fb565b600060208284031215612a66578081fd5b5035919050565b60008060408385031215612a7f578182fd5b50508035926020909101359150565b600060208284031215612a9f578081fd5b815167ffffffffffffffff80821115612ab6578283fd5b818401915084601f830112612ac9578283fd5b815181811115612adb57612adb6131cd565b604051601f8201601f19908116603f01168101908382118183101715612b0357612b036131cd565b81604052828152876020848701011115612b1b578586fd5b612b2c83602083016020880161311e565b979650505050505050565b600060208284031215612b48578081fd5b5051919050565b60008060408385031215612b61578182fd5b8235915060208301356129c3816131e3565b600080600060608486031215612b87578283fd5b833592506020840135612b99816131fb565b91506040840135612ba9816131fb565b809150509250925092565b600080600080600060a08688031215612bcb578081fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b8060005b6002811015612c1f5781516001600160a01b0316845260209384019390910190600101612bf7565b50505050565b60008151808452612c3d81602086016020860161311e565b601f01601f19169290920160200192915050565b60038110612c6f57634e487b7160e01b600052602160045260246000fd5b9052565b606085901b6bffffffffffffffffffffffff191681526001600160e01b0319841660148201528251600090612caf81601885016020880161311e565b6018920191820192909252603801949350505050565b6001600160e01b03198316815281546000906004908290600181811c9080831680612cf157607f831692505b6020808410821415612d1057634e487b7160e01b885260228752602488fd5b818015612d245760018114612d3957612d69565b60ff1986168a890152848a0188019650612d69565b60008b815260209020895b86811015612d5f5781548c82018b0152908501908301612d44565b505087858b010196505b50949a9950505050505050505050565b60008251612d8b81846020870161311e565b9190910192915050565b60006001600160a01b038616825263ffffffff60e01b8516602083015260806040830152612dc66080830185612c25565b905082606083015295945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e0f57835183529284019291840191600101612df3565b50909695505050505050565b600061032089835260208084018a845b6011811015612e4857815183529183019190830190600101612e2b565b505050610240840189845b6002811015612e72578151151583529183019190830190600101612e53565b50505050612e84610280840188612c51565b806102a0840152612e9781840187612c25565b915050612eb16102c08301856001600160e01b0319169052565b612ebf6102e0830184612bf3565b98975050505050505050565b600085825284602083015260806040830152612eea6080830185612c25565b90506001600160a01b038316606083015295945050505050565b6020808252602e908201527f4e6577206469737075746520726f756e64206d7573742062652073746172746560408201526d642077697468696e20612064617960901b606082015260800190565b828152604081016129736020830184612c51565b84815260808101612f7a6020830186612c51565b6001600160a01b03808516604084015280841660608401525095945050505050565b60008219821115612faf57612faf6131b7565b500190565b600082612fcf57634e487b7160e01b81526012600452602481fd5b500490565b80825b6001808611612fe65750613011565b818704821115612ff857612ff86131b7565b8086161561300557918102915b9490941c938002612fd7565b94509492505050565b6000612973600019848460008261303357506001612973565b8161304057506000612973565b816001811461305657600281146130605761308d565b6001915050612973565b60ff841115613071576130716131b7565b6001841b915084821115613087576130876131b7565b50612973565b5060208310610133831016604e8410600b84101617156130c0575081810a838111156130bb576130bb6131b7565b612973565b6130cd8484846001612fd4565b8086048211156130df576130df6131b7565b02949350505050565b6000816000190483118215151615613102576131026131b7565b500290565b600082821015613119576131196131b7565b500390565b60005b83811015613139578181015183820152602001613121565b83811115612c1f5750506000910152565b600081613159576131596131b7565b506000190190565b600181811c9082168061317557607f821691505b6020821081141561319657634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156131b0576131b06131b7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146131f857600080fd5b50565b80151581146131f857600080fdfea26469706673582212200e66ea4a5edfc6ebd8a2364676a30b97a0e04b0be80b6d19a89932b9eba6e74364736f6c63430008030033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000041b66dd93b03e89d29114a7613a6f9f0d4f401780000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000080fc34a2f9ffe86f41580f47368289c402dec660

-----Decoded View---------------
Arg [0] : _tellor (address): 0x41b66dd93b03e89D29114a7613A6f9f0d4F40178
Arg [1] : _disputeFee (uint256): 5000000000000000000
Arg [2] : _teamMultisig (address): 0x80fc34a2f9FfE86F41580F47368289C402DEc660

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000041b66dd93b03e89d29114a7613a6f9f0d4f40178
Arg [1] : 0000000000000000000000000000000000000000000000004563918244f40000
Arg [2] : 00000000000000000000000080fc34a2f9ffe86f41580f47368289c402dec660


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.