Address Details
contract
proxy

0x61E697F9f1D10585e42e73bf8Fe15B55337795b2

Contract Name
NounsDAOLogicV1
Creator
0x8b2f36–66963a at 0x509ebf–dad3a8
Implementation
0x0000000000000000000000000000000000000000
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
16206172
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
NounsDAOLogicV1




Optimization enabled
true
Compiler version
v0.8.6+commit.11564f7e




Optimization runs
5000
EVM Version
berlin




Verified at
2022-12-24T00:41:50.391511Z

contracts/governance/NounsDAOLogicV1.sol

// SPDX-License-Identifier: BSD-3-Clause

/// @title The Nouns DAO logic version 1

/*********************************
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░██░░░████░░██░░░████░░░ *
 * ░░██████░░░████████░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 *********************************/

// LICENSE
// NounsDAOLogicV1.sol is a modified version of Compound Lab's GovernorBravoDelegate.sol:
// https://github.com/compound-finance/compound-protocol/blob/b9b14038612d846b83f8a009a82c38974ff2dcfe/contracts/Governance/GovernorBravoDelegate.sol
//
// GovernorBravoDelegate.sol source code Copyright 2020 Compound Labs, Inc. licensed under the BSD-3-Clause license.
// With modifications by Nounders DAO.
//
// Additional conditions of BSD-3-Clause can be found here: https://opensource.org/licenses/BSD-3-Clause
//
// MODIFICATIONS
// NounsDAOLogicV1 adds:
// - Proposal Threshold basis points instead of fixed number
//   due to the Noun token's increasing supply
//
// - Quorum Votes basis points instead of fixed number
//   due to the Noun token's increasing supply
//
// - Per proposal storing of fixed `proposalThreshold`
//   and `quorumVotes` calculated using the Noun token's total supply
//   at the block the proposal was created and the basis point parameters
//
// - `ProposalCreatedWithRequirements` event that emits `ProposalCreated` parameters with
//   the addition of `proposalThreshold` and `quorumVotes`
//
// - Votes are counted from the block a proposal is created instead of
//   the proposal's voting start block to align with the parameters
//   stored with the proposal
//
// - Veto ability which allows `veteor` to halt any proposal at any stage unless
//   the proposal is executed.
//   The `veto(uint proposalId)` logic is a modified version of `cancel(uint proposalId)`
//   A `vetoed` flag was added to the `Proposal` struct to support this.
//
// NounsDAOLogicV1 removes:
// - `initialProposalId` and `_initiate()` due to this being the
//   first instance of the governance contract unlike
//   GovernorBravo which upgrades GovernorAlpha
//
// - Value passed along using `timelock.executeTransaction{value: proposal.value}`
//   in `execute(uint proposalId)`. This contract should not hold funds and does not
//   implement `receive()` or `fallback()` functions.
//

pragma solidity ^0.8.6;

import './NounsDAOInterfaces.sol';

contract NounsDAOLogicV1 is NounsDAOStorageV1, NounsDAOEvents {
    /// @notice The name of this contract
    string public constant name = 'Nouns DAO';

    /// @notice The minimum setable proposal threshold
    uint256 public constant MIN_PROPOSAL_THRESHOLD_BPS = 1; // 1 basis point or 0.01%

    /// @notice The maximum setable proposal threshold
    uint256 public constant MAX_PROPOSAL_THRESHOLD_BPS = 1_000; // 1,000 basis points or 10%

    /// @notice The minimum setable voting period
    uint256 public constant MIN_VOTING_PERIOD = 5_760; // About 24 hours

    /// @notice The max setable voting period
    uint256 public constant MAX_VOTING_PERIOD = 80_640; // About 2 weeks

    /// @notice The min setable voting delay
    uint256 public constant MIN_VOTING_DELAY = 1;

    /// @notice The max setable voting delay
    uint256 public constant MAX_VOTING_DELAY = 40_320; // About 1 week

    /// @notice The minimum setable quorum votes basis points
    uint256 public constant MIN_QUORUM_VOTES_BPS = 200; // 200 basis points or 2%

    /// @notice The maximum setable quorum votes basis points
    uint256 public constant MAX_QUORUM_VOTES_BPS = 2_000; // 2,000 basis points or 20%

    /// @notice The maximum number of actions that can be included in a proposal
    uint256 public constant proposalMaxOperations = 10; // 10 actions

    /// @notice The EIP-712 typehash for the contract's domain
    bytes32 public constant DOMAIN_TYPEHASH =
        keccak256('EIP712Domain(string name,uint256 chainId,address verifyingContract)');

    /// @notice The EIP-712 typehash for the ballot struct used by the contract
    bytes32 public constant BALLOT_TYPEHASH = keccak256('Ballot(uint256 proposalId,uint8 support)');

    /**
     * @notice Used to initialize the contract during delegator contructor
     * @param timelock_ The address of the NounsDAOExecutor
     * @param nouns_ The address of the NOUN tokens
     * @param vetoer_ The address allowed to unilaterally veto proposals
     * @param votingPeriod_ The initial voting period
     * @param votingDelay_ The initial voting delay
     * @param proposalThresholdBPS_ The initial proposal threshold in basis points
     * * @param quorumVotesBPS_ The initial quorum votes threshold in basis points
     */
    function initialize(
        address timelock_,
        address nouns_,
        address vetoer_,
        uint256 votingPeriod_,
        uint256 votingDelay_,
        uint256 proposalThresholdBPS_,
        uint256 quorumVotesBPS_
    ) public virtual {
        require(address(timelock) == address(0), 'NounsDAO::initialize: can only initialize once');
        require(msg.sender == admin, 'NounsDAO::initialize: admin only');
        require(timelock_ != address(0), 'NounsDAO::initialize: invalid timelock address');
        require(nouns_ != address(0), 'NounsDAO::initialize: invalid nouns address');
        require(
            votingPeriod_ >= MIN_VOTING_PERIOD && votingPeriod_ <= MAX_VOTING_PERIOD,
            'NounsDAO::initialize: invalid voting period'
        );
        require(
            votingDelay_ >= MIN_VOTING_DELAY && votingDelay_ <= MAX_VOTING_DELAY,
            'NounsDAO::initialize: invalid voting delay'
        );
        require(
            proposalThresholdBPS_ >= MIN_PROPOSAL_THRESHOLD_BPS && proposalThresholdBPS_ <= MAX_PROPOSAL_THRESHOLD_BPS,
            'NounsDAO::initialize: invalid proposal threshold'
        );
        require(
            quorumVotesBPS_ >= MIN_QUORUM_VOTES_BPS && quorumVotesBPS_ <= MAX_QUORUM_VOTES_BPS,
            'NounsDAO::initialize: invalid proposal threshold'
        );

        emit VotingPeriodSet(votingPeriod, votingPeriod_);
        emit VotingDelaySet(votingDelay, votingDelay_);
        emit ProposalThresholdBPSSet(proposalThresholdBPS, proposalThresholdBPS_);
        emit QuorumVotesBPSSet(quorumVotesBPS, quorumVotesBPS_);

        timelock = INounsDAOExecutor(timelock_);
        nouns = NounsTokenLike(nouns_);
        vetoer = vetoer_;
        votingPeriod = votingPeriod_;
        votingDelay = votingDelay_;
        proposalThresholdBPS = proposalThresholdBPS_;
        quorumVotesBPS = quorumVotesBPS_;
    }

    struct ProposalTemp {
        uint256 totalSupply;
        uint256 proposalThreshold;
        uint256 latestProposalId;
        uint256 startBlock;
        uint256 endBlock;
    }

    /**
     * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold
     * @param targets Target addresses for proposal calls
     * @param values Eth values for proposal calls
     * @param signatures Function signatures for proposal calls
     * @param calldatas Calldatas for proposal calls
     * @param description String description of the proposal
     * @return Proposal id of new proposal
     */
    function propose(
        address[] memory targets,
        uint256[] memory values,
        string[] memory signatures,
        bytes[] memory calldatas,
        string memory description
    ) public returns (uint256) {
        ProposalTemp memory temp;

        temp.totalSupply = nouns.totalSupply();

        temp.proposalThreshold = bps2Uint(proposalThresholdBPS, temp.totalSupply);

        require(
            nouns.getPriorVotes(msg.sender, block.number - 1) > temp.proposalThreshold,
            'NounsDAO::propose: proposer votes below proposal threshold'
        );
        require(
            targets.length == values.length &&
                targets.length == signatures.length &&
                targets.length == calldatas.length,
            'NounsDAO::propose: proposal function information arity mismatch'
        );
        require(targets.length != 0, 'NounsDAO::propose: must provide actions');
        require(targets.length <= proposalMaxOperations, 'NounsDAO::propose: too many actions');

        temp.latestProposalId = latestProposalIds[msg.sender];
        if (temp.latestProposalId != 0) {
            ProposalState proposersLatestProposalState = state(temp.latestProposalId);
            require(
                proposersLatestProposalState != ProposalState.Active,
                'NounsDAO::propose: one live proposal per proposer, found an already active proposal'
            );
            require(
                proposersLatestProposalState != ProposalState.Pending,
                'NounsDAO::propose: one live proposal per proposer, found an already pending proposal'
            );
        }

        temp.startBlock = block.number + votingDelay;
        temp.endBlock = temp.startBlock + votingPeriod;

        proposalCount++;
        Proposal storage newProposal = proposals[proposalCount];

        newProposal.id = proposalCount;
        newProposal.proposer = msg.sender;
        newProposal.proposalThreshold = temp.proposalThreshold;
        newProposal.quorumVotes = bps2Uint(quorumVotesBPS, temp.totalSupply);
        newProposal.eta = 0;
        newProposal.targets = targets;
        newProposal.values = values;
        newProposal.signatures = signatures;
        newProposal.calldatas = calldatas;
        newProposal.startBlock = temp.startBlock;
        newProposal.endBlock = temp.endBlock;
        newProposal.forVotes = 0;
        newProposal.againstVotes = 0;
        newProposal.abstainVotes = 0;
        newProposal.canceled = false;
        newProposal.executed = false;
        newProposal.vetoed = false;

        latestProposalIds[newProposal.proposer] = newProposal.id;

        /// @notice Maintains backwards compatibility with GovernorBravo events
        emit ProposalCreated(
            newProposal.id,
            msg.sender,
            targets,
            values,
            signatures,
            calldatas,
            newProposal.startBlock,
            newProposal.endBlock,
            description
        );

        /// @notice Updated event with `proposalThreshold` and `quorumVotes`
        emit ProposalCreatedWithRequirements(
            newProposal.id,
            msg.sender,
            targets,
            values,
            signatures,
            calldatas,
            newProposal.startBlock,
            newProposal.endBlock,
            newProposal.proposalThreshold,
            newProposal.quorumVotes,
            description
        );

        return newProposal.id;
    }

    /**
     * @notice Queues a proposal of state succeeded
     * @param proposalId The id of the proposal to queue
     */
    function queue(uint256 proposalId) external {
        require(
            state(proposalId) == ProposalState.Succeeded,
            'NounsDAO::queue: proposal can only be queued if it is succeeded'
        );
        Proposal storage proposal = proposals[proposalId];
        uint256 eta = block.timestamp + timelock.delay();
        for (uint256 i = 0; i < proposal.targets.length; i++) {
            queueOrRevertInternal(
                proposal.targets[i],
                proposal.values[i],
                proposal.signatures[i],
                proposal.calldatas[i],
                eta
            );
        }
        proposal.eta = eta;
        emit ProposalQueued(proposalId, eta);
    }

    function queueOrRevertInternal(
        address target,
        uint256 value,
        string memory signature,
        bytes memory data,
        uint256 eta
    ) internal {
        require(
            !timelock.queuedTransactions(keccak256(abi.encode(target, value, signature, data, eta))),
            'NounsDAO::queueOrRevertInternal: identical proposal action already queued at eta'
        );
        timelock.queueTransaction(target, value, signature, data, eta);
    }

    /**
     * @notice Executes a queued proposal if eta has passed
     * @param proposalId The id of the proposal to execute
     */
    function execute(uint256 proposalId) external {
        require(
            state(proposalId) == ProposalState.Queued,
            'NounsDAO::execute: proposal can only be executed if it is queued'
        );
        Proposal storage proposal = proposals[proposalId];
        proposal.executed = true;
        for (uint256 i = 0; i < proposal.targets.length; i++) {
            timelock.executeTransaction(
                proposal.targets[i],
                proposal.values[i],
                proposal.signatures[i],
                proposal.calldatas[i],
                proposal.eta
            );
        }
        emit ProposalExecuted(proposalId);
    }

    /**
     * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold
     * @param proposalId The id of the proposal to cancel
     */
    function cancel(uint256 proposalId) external {
        require(state(proposalId) != ProposalState.Executed, 'NounsDAO::cancel: cannot cancel executed proposal');

        Proposal storage proposal = proposals[proposalId];
        require(
            msg.sender == proposal.proposer ||
                nouns.getPriorVotes(proposal.proposer, block.number - 1) < proposal.proposalThreshold,
            'NounsDAO::cancel: proposer above threshold'
        );

        proposal.canceled = true;
        for (uint256 i = 0; i < proposal.targets.length; i++) {
            timelock.cancelTransaction(
                proposal.targets[i],
                proposal.values[i],
                proposal.signatures[i],
                proposal.calldatas[i],
                proposal.eta
            );
        }

        emit ProposalCanceled(proposalId);
    }

    /**
     * @notice Vetoes a proposal only if sender is the vetoer and the proposal has not been executed.
     * @param proposalId The id of the proposal to veto
     */
    function veto(uint256 proposalId) external {
        require(vetoer != address(0), 'NounsDAO::veto: veto power burned');
        require(msg.sender == vetoer, 'NounsDAO::veto: only vetoer');
        require(state(proposalId) != ProposalState.Executed, 'NounsDAO::veto: cannot veto executed proposal');

        Proposal storage proposal = proposals[proposalId];

        proposal.vetoed = true;
        for (uint256 i = 0; i < proposal.targets.length; i++) {
            timelock.cancelTransaction(
                proposal.targets[i],
                proposal.values[i],
                proposal.signatures[i],
                proposal.calldatas[i],
                proposal.eta
            );
        }

        emit ProposalVetoed(proposalId);
    }

    /**
     * @notice Gets actions of a proposal
     * @param proposalId the id of the proposal
     * @return targets
     * @return values
     * @return signatures
     * @return calldatas
     */
    function getActions(uint256 proposalId)
        external
        view
        returns (
            address[] memory targets,
            uint256[] memory values,
            string[] memory signatures,
            bytes[] memory calldatas
        )
    {
        Proposal storage p = proposals[proposalId];
        return (p.targets, p.values, p.signatures, p.calldatas);
    }

    /**
     * @notice Gets the receipt for a voter on a given proposal
     * @param proposalId the id of proposal
     * @param voter The address of the voter
     * @return The voting receipt
     */
    function getReceipt(uint256 proposalId, address voter) external view returns (Receipt memory) {
        return proposals[proposalId].receipts[voter];
    }

    /**
     * @notice Gets the state of a proposal
     * @param proposalId The id of the proposal
     * @return Proposal state
     */
    function state(uint256 proposalId) public view returns (ProposalState) {
        require(proposalCount >= proposalId, 'NounsDAO::state: invalid proposal id');
        Proposal storage proposal = proposals[proposalId];
        if (proposal.vetoed) {
            return ProposalState.Vetoed;
        } else if (proposal.canceled) {
            return ProposalState.Canceled;
        } else if (block.number <= proposal.startBlock) {
            return ProposalState.Pending;
        } else if (block.number <= proposal.endBlock) {
            return ProposalState.Active;
        } else if (proposal.forVotes <= proposal.againstVotes || proposal.forVotes < proposal.quorumVotes) {
            return ProposalState.Defeated;
        } else if (proposal.eta == 0) {
            return ProposalState.Succeeded;
        } else if (proposal.executed) {
            return ProposalState.Executed;
        } else if (block.timestamp >= proposal.eta + timelock.GRACE_PERIOD()) {
            return ProposalState.Expired;
        } else {
            return ProposalState.Queued;
        }
    }

    /**
     * @notice Cast a vote for a proposal
     * @param proposalId The id of the proposal to vote on
     * @param support The support value for the vote. 0=against, 1=for, 2=abstain
     */
    function castVote(uint256 proposalId, uint8 support) external {
        emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), '');
    }

    /**
     * @notice Cast a vote for a proposal with a reason
     * @param proposalId The id of the proposal to vote on
     * @param support The support value for the vote. 0=against, 1=for, 2=abstain
     * @param reason The reason given for the vote by the voter
     */
    function castVoteWithReason(
        uint256 proposalId,
        uint8 support,
        string calldata reason
    ) external {
        emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), reason);
    }

    /**
     * @notice Cast a vote for a proposal by signature
     * @dev External function that accepts EIP-712 signatures for voting on proposals.
     */
    function castVoteBySig(
        uint256 proposalId,
        uint8 support,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        bytes32 domainSeparator = keccak256(
            abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainIdInternal(), address(this))
        );
        bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support));
        bytes32 digest = keccak256(abi.encodePacked('\x19\x01', domainSeparator, structHash));
        address signatory = ecrecover(digest, v, r, s);
        require(signatory != address(0), 'NounsDAO::castVoteBySig: invalid signature');
        emit VoteCast(signatory, proposalId, support, castVoteInternal(signatory, proposalId, support), '');
    }

    /**
     * @notice Internal function that caries out voting logic
     * @param voter The voter that is casting their vote
     * @param proposalId The id of the proposal to vote on
     * @param support The support value for the vote. 0=against, 1=for, 2=abstain
     * @return The number of votes cast
     */
    function castVoteInternal(
        address voter,
        uint256 proposalId,
        uint8 support
    ) internal returns (uint96) {
        require(state(proposalId) == ProposalState.Active, 'NounsDAO::castVoteInternal: voting is closed');
        require(support <= 2, 'NounsDAO::castVoteInternal: invalid vote type');
        Proposal storage proposal = proposals[proposalId];
        Receipt storage receipt = proposal.receipts[voter];
        require(receipt.hasVoted == false, 'NounsDAO::castVoteInternal: voter already voted');

        /// @notice: Unlike GovernerBravo, votes are considered from the block the proposal was created in order to normalize quorumVotes and proposalThreshold metrics
        uint96 votes = nouns.getPriorVotes(voter, proposal.startBlock - votingDelay);

        if (support == 0) {
            proposal.againstVotes = proposal.againstVotes + votes;
        } else if (support == 1) {
            proposal.forVotes = proposal.forVotes + votes;
        } else if (support == 2) {
            proposal.abstainVotes = proposal.abstainVotes + votes;
        }

        receipt.hasVoted = true;
        receipt.support = support;
        receipt.votes = votes;

        return votes;
    }

    /**
     * @notice Admin function for setting the voting delay
     * @param newVotingDelay new voting delay, in blocks
     */
    function _setVotingDelay(uint256 newVotingDelay) external {
        require(msg.sender == admin, 'NounsDAO::_setVotingDelay: admin only');
        require(
            newVotingDelay >= MIN_VOTING_DELAY && newVotingDelay <= MAX_VOTING_DELAY,
            'NounsDAO::_setVotingDelay: invalid voting delay'
        );
        uint256 oldVotingDelay = votingDelay;
        votingDelay = newVotingDelay;

        emit VotingDelaySet(oldVotingDelay, votingDelay);
    }

    /**
     * @notice Admin function for setting the voting period
     * @param newVotingPeriod new voting period, in blocks
     */
    function _setVotingPeriod(uint256 newVotingPeriod) external {
        require(msg.sender == admin, 'NounsDAO::_setVotingPeriod: admin only');
        require(
            newVotingPeriod >= MIN_VOTING_PERIOD && newVotingPeriod <= MAX_VOTING_PERIOD,
            'NounsDAO::_setVotingPeriod: invalid voting period'
        );
        uint256 oldVotingPeriod = votingPeriod;
        votingPeriod = newVotingPeriod;

        emit VotingPeriodSet(oldVotingPeriod, votingPeriod);
    }

    /**
     * @notice Admin function for setting the proposal threshold basis points
     * @dev newProposalThresholdBPS must be greater than the hardcoded min
     * @param newProposalThresholdBPS new proposal threshold
     */
    function _setProposalThresholdBPS(uint256 newProposalThresholdBPS) external {
        require(msg.sender == admin, 'NounsDAO::_setProposalThresholdBPS: admin only');
        require(
            newProposalThresholdBPS >= MIN_PROPOSAL_THRESHOLD_BPS &&
                newProposalThresholdBPS <= MAX_PROPOSAL_THRESHOLD_BPS,
            'NounsDAO::_setProposalThreshold: invalid proposal threshold'
        );
        uint256 oldProposalThresholdBPS = proposalThresholdBPS;
        proposalThresholdBPS = newProposalThresholdBPS;

        emit ProposalThresholdBPSSet(oldProposalThresholdBPS, proposalThresholdBPS);
    }

    /**
     * @notice Admin function for setting the quorum votes basis points
     * @dev newQuorumVotesBPS must be greater than the hardcoded min
     * @param newQuorumVotesBPS new proposal threshold
     */
    function _setQuorumVotesBPS(uint256 newQuorumVotesBPS) external {
        require(msg.sender == admin, 'NounsDAO::_setQuorumVotesBPS: admin only');
        require(
            newQuorumVotesBPS >= MIN_QUORUM_VOTES_BPS && newQuorumVotesBPS <= MAX_QUORUM_VOTES_BPS,
            'NounsDAO::_setProposalThreshold: invalid proposal threshold'
        );
        uint256 oldQuorumVotesBPS = quorumVotesBPS;
        quorumVotesBPS = newQuorumVotesBPS;

        emit QuorumVotesBPSSet(oldQuorumVotesBPS, quorumVotesBPS);
    }

    /**
     * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.
     * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.
     * @param newPendingAdmin New pending admin.
     */
    function _setPendingAdmin(address newPendingAdmin) external {
        // Check caller = admin
        require(msg.sender == admin, 'NounsDAO::_setPendingAdmin: admin only');

        // Save current value, if any, for inclusion in log
        address oldPendingAdmin = pendingAdmin;

        // Store pendingAdmin with value newPendingAdmin
        pendingAdmin = newPendingAdmin;

        // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)
        emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);
    }

    /**
     * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin
     * @dev Admin function for pending admin to accept role and update admin
     */
    function _acceptAdmin() external {
        // Check caller is pendingAdmin and pendingAdmin ≠ address(0)
        require(msg.sender == pendingAdmin && msg.sender != address(0), 'NounsDAO::_acceptAdmin: pending admin only');

        // Save current values for inclusion in log
        address oldAdmin = admin;
        address oldPendingAdmin = pendingAdmin;

        // Store admin with value pendingAdmin
        admin = pendingAdmin;

        // Clear the pending value
        pendingAdmin = address(0);

        emit NewAdmin(oldAdmin, admin);
        emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);
    }

    /**
     * @notice Changes vetoer address
     * @dev Vetoer function for updating vetoer address
     */
    function _setVetoer(address newVetoer) public {
        require(msg.sender == vetoer, 'NounsDAO::_setVetoer: vetoer only');

        emit NewVetoer(vetoer, newVetoer);

        vetoer = newVetoer;
    }

    /**
     * @notice Burns veto priviledges
     * @dev Vetoer function destroying veto power forever
     */
    function _burnVetoPower() public {
        // Check caller is pendingAdmin and pendingAdmin ≠ address(0)
        require(msg.sender == vetoer, 'NounsDAO::_burnVetoPower: vetoer only');

        _setVetoer(address(0));
    }

    /**
     * @notice Current proposal threshold using Noun Total Supply
     * Differs from `GovernerBravo` which uses fixed amount
     */
    function proposalThreshold() public view returns (uint256) {
        return bps2Uint(proposalThresholdBPS, nouns.totalSupply());
    }

    /**
     * @notice Current quorum votes using Noun Total Supply
     * Differs from `GovernerBravo` which uses fixed amount
     */
    function quorumVotes() public view returns (uint256) {
        return bps2Uint(quorumVotesBPS, nouns.totalSupply());
    }

    function bps2Uint(uint256 bps, uint256 number) internal pure returns (uint256) {
        return (number * bps) / 10000;
    }

    function getChainIdInternal() internal view returns (uint256) {
        uint256 chainId;
        assembly {
            chainId := chainid()
        }
        return chainId;
    }
}
        

/contracts/governance/NounsDAOInterfaces.sol

// SPDX-License-Identifier: BSD-3-Clause

/// @title Nouns DAO Logic interfaces and events

/*********************************
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░██░░░████░░██░░░████░░░ *
 * ░░██████░░░████████░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 *********************************/

// LICENSE
// NounsDAOInterfaces.sol is a modified version of Compound Lab's GovernorBravoInterfaces.sol:
// https://github.com/compound-finance/compound-protocol/blob/b9b14038612d846b83f8a009a82c38974ff2dcfe/contracts/Governance/GovernorBravoInterfaces.sol
//
// GovernorBravoInterfaces.sol source code Copyright 2020 Compound Labs, Inc. licensed under the BSD-3-Clause license.
// With modifications by Nounders DAO.
//
// Additional conditions of BSD-3-Clause can be found here: https://opensource.org/licenses/BSD-3-Clause
//
// MODIFICATIONS
// NounsDAOEvents, NounsDAOProxyStorage, NounsDAOStorageV1 add support for changes made by Nouns DAO to GovernorBravo.sol
// See NounsDAOLogicV1.sol for more details.
// NounsDAOStorageV1Adjusted and NounsDAOStorageV2 add support for a dynamic vote quorum.
// See NounsDAOLogicV2.sol for more details.

pragma solidity ^0.8.6;

contract NounsDAOEvents {
    /// @notice An event emitted when a new proposal is created
    event ProposalCreated(
        uint256 id,
        address proposer,
        address[] targets,
        uint256[] values,
        string[] signatures,
        bytes[] calldatas,
        uint256 startBlock,
        uint256 endBlock,
        string description
    );

    /// @notice An event emitted when a new proposal is created, which includes additional information
    event ProposalCreatedWithRequirements(
        uint256 id,
        address proposer,
        address[] targets,
        uint256[] values,
        string[] signatures,
        bytes[] calldatas,
        uint256 startBlock,
        uint256 endBlock,
        uint256 proposalThreshold,
        uint256 quorumVotes,
        string description
    );

    /// @notice An event emitted when a vote has been cast on a proposal
    /// @param voter The address which casted a vote
    /// @param proposalId The proposal id which was voted on
    /// @param support Support value for the vote. 0=against, 1=for, 2=abstain
    /// @param votes Number of votes which were cast by the voter
    /// @param reason The reason given for the vote by the voter
    event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 votes, string reason);

    /// @notice An event emitted when a proposal has been canceled
    event ProposalCanceled(uint256 id);

    /// @notice An event emitted when a proposal has been queued in the NounsDAOExecutor
    event ProposalQueued(uint256 id, uint256 eta);

    /// @notice An event emitted when a proposal has been executed in the NounsDAOExecutor
    event ProposalExecuted(uint256 id);

    /// @notice An event emitted when a proposal has been vetoed by vetoAddress
    event ProposalVetoed(uint256 id);

    /// @notice An event emitted when the voting delay is set
    event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);

    /// @notice An event emitted when the voting period is set
    event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);

    /// @notice Emitted when implementation is changed
    event NewImplementation(address oldImplementation, address newImplementation);

    /// @notice Emitted when proposal threshold basis points is set
    event ProposalThresholdBPSSet(uint256 oldProposalThresholdBPS, uint256 newProposalThresholdBPS);

    /// @notice Emitted when quorum votes basis points is set
    event QuorumVotesBPSSet(uint256 oldQuorumVotesBPS, uint256 newQuorumVotesBPS);

    /// @notice Emitted when pendingAdmin is changed
    event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);

    /// @notice Emitted when pendingAdmin is accepted, which means admin is updated
    event NewAdmin(address oldAdmin, address newAdmin);

    /// @notice Emitted when vetoer is changed
    event NewVetoer(address oldVetoer, address newVetoer);
}

contract NounsDAOEventsV2 is NounsDAOEvents {
    /// @notice Emitted when minQuorumVotesBPS is set
    event MinQuorumVotesBPSSet(uint16 oldMinQuorumVotesBPS, uint16 newMinQuorumVotesBPS);

    /// @notice Emitted when maxQuorumVotesBPS is set
    event MaxQuorumVotesBPSSet(uint16 oldMaxQuorumVotesBPS, uint16 newMaxQuorumVotesBPS);

    /// @notice Emitted when quorumCoefficient is set
    event QuorumCoefficientSet(uint32 oldQuorumCoefficient, uint32 newQuorumCoefficient);

    /// @notice Emitted when a voter cast a vote requesting a gas refund.
    event RefundableVote(address indexed voter, uint256 refundAmount, bool refundSent);

    /// @notice Emitted when admin withdraws the DAO's balance.
    event Withdraw(uint256 amount, bool sent);

    /// @notice Emitted when pendingVetoer is changed
    event NewPendingVetoer(address oldPendingVetoer, address newPendingVetoer);
}

contract NounsDAOProxyStorage {
    /// @notice Administrator for this contract
    address public admin;

    /// @notice Pending administrator for this contract
    address public pendingAdmin;

    /// @notice Active brains of Governor
    address public implementation;
}

/**
 * @title Storage for Governor Bravo Delegate
 * @notice For future upgrades, do not change NounsDAOStorageV1. Create a new
 * contract which implements NounsDAOStorageV1 and following the naming convention
 * NounsDAOStorageVX.
 */
contract NounsDAOStorageV1 is NounsDAOProxyStorage {
    /// @notice Vetoer who has the ability to veto any proposal
    address public vetoer;

    /// @notice The delay before voting on a proposal may take place, once proposed, in blocks
    uint256 public votingDelay;

    /// @notice The duration of voting on a proposal, in blocks
    uint256 public votingPeriod;

    /// @notice The basis point number of votes required in order for a voter to become a proposer. *DIFFERS from GovernerBravo
    uint256 public proposalThresholdBPS;

    /// @notice The basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed. *DIFFERS from GovernerBravo
    uint256 public quorumVotesBPS;

    /// @notice The total number of proposals
    uint256 public proposalCount;

    /// @notice The address of the Nouns DAO Executor NounsDAOExecutor
    INounsDAOExecutor public timelock;

    /// @notice The address of the Nouns tokens
    NounsTokenLike public nouns;

    /// @notice The official record of all proposals ever proposed
    mapping(uint256 => Proposal) public proposals;

    /// @notice The latest proposal for each proposer
    mapping(address => uint256) public latestProposalIds;

    struct Proposal {
        /// @notice Unique id for looking up a proposal
        uint256 id;
        /// @notice Creator of the proposal
        address proposer;
        /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 proposalThreshold;
        /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 quorumVotes;
        /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
        uint256 eta;
        /// @notice the ordered list of target addresses for calls to be made
        address[] targets;
        /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made
        uint256[] values;
        /// @notice The ordered list of function signatures to be called
        string[] signatures;
        /// @notice The ordered list of calldata to be passed to each call
        bytes[] calldatas;
        /// @notice The block at which voting begins: holders must delegate their votes prior to this block
        uint256 startBlock;
        /// @notice The block at which voting ends: votes must be cast prior to this block
        uint256 endBlock;
        /// @notice Current number of votes in favor of this proposal
        uint256 forVotes;
        /// @notice Current number of votes in opposition to this proposal
        uint256 againstVotes;
        /// @notice Current number of votes for abstaining for this proposal
        uint256 abstainVotes;
        /// @notice Flag marking whether the proposal has been canceled
        bool canceled;
        /// @notice Flag marking whether the proposal has been vetoed
        bool vetoed;
        /// @notice Flag marking whether the proposal has been executed
        bool executed;
        /// @notice Receipts of ballots for the entire set of voters
        mapping(address => Receipt) receipts;
    }

    /// @notice Ballot receipt record for a voter
    struct Receipt {
        /// @notice Whether or not a vote has been cast
        bool hasVoted;
        /// @notice Whether or not the voter supports the proposal or abstains
        uint8 support;
        /// @notice The number of votes the voter had, which were cast
        uint96 votes;
    }

    /// @notice Possible states that a proposal may be in
    enum ProposalState {
        Pending,
        Active,
        Canceled,
        Defeated,
        Succeeded,
        Queued,
        Expired,
        Executed,
        Vetoed
    }
}

/**
 * @title Extra fields added to the `Proposal` struct from NounsDAOStorageV1
 * @notice The following fields were added to the `Proposal` struct:
 * - `Proposal.totalSupply`
 * - `Proposal.creationBlock`
 */
contract NounsDAOStorageV1Adjusted is NounsDAOProxyStorage {
    /// @notice Vetoer who has the ability to veto any proposal
    address public vetoer;

    /// @notice The delay before voting on a proposal may take place, once proposed, in blocks
    uint256 public votingDelay;

    /// @notice The duration of voting on a proposal, in blocks
    uint256 public votingPeriod;

    /// @notice The basis point number of votes required in order for a voter to become a proposer. *DIFFERS from GovernerBravo
    uint256 public proposalThresholdBPS;

    /// @notice The basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed. *DIFFERS from GovernerBravo
    uint256 public quorumVotesBPS;

    /// @notice The total number of proposals
    uint256 public proposalCount;

    /// @notice The address of the Nouns DAO Executor NounsDAOExecutor
    INounsDAOExecutor public timelock;

    /// @notice The address of the Nouns tokens
    NounsTokenLike public nouns;

    /// @notice The official record of all proposals ever proposed
    mapping(uint256 => Proposal) internal _proposals;

    /// @notice The latest proposal for each proposer
    mapping(address => uint256) public latestProposalIds;

    struct Proposal {
        /// @notice Unique id for looking up a proposal
        uint256 id;
        /// @notice Creator of the proposal
        address proposer;
        /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 proposalThreshold;
        /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 quorumVotes;
        /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
        uint256 eta;
        /// @notice the ordered list of target addresses for calls to be made
        address[] targets;
        /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made
        uint256[] values;
        /// @notice The ordered list of function signatures to be called
        string[] signatures;
        /// @notice The ordered list of calldata to be passed to each call
        bytes[] calldatas;
        /// @notice The block at which voting begins: holders must delegate their votes prior to this block
        uint256 startBlock;
        /// @notice The block at which voting ends: votes must be cast prior to this block
        uint256 endBlock;
        /// @notice Current number of votes in favor of this proposal
        uint256 forVotes;
        /// @notice Current number of votes in opposition to this proposal
        uint256 againstVotes;
        /// @notice Current number of votes for abstaining for this proposal
        uint256 abstainVotes;
        /// @notice Flag marking whether the proposal has been canceled
        bool canceled;
        /// @notice Flag marking whether the proposal has been vetoed
        bool vetoed;
        /// @notice Flag marking whether the proposal has been executed
        bool executed;
        /// @notice Receipts of ballots for the entire set of voters
        mapping(address => Receipt) receipts;
        /// @notice The total supply at the time of proposal creation
        uint256 totalSupply;
        /// @notice The block at which this proposal was created
        uint256 creationBlock;
    }

    /// @notice Ballot receipt record for a voter
    struct Receipt {
        /// @notice Whether or not a vote has been cast
        bool hasVoted;
        /// @notice Whether or not the voter supports the proposal or abstains
        uint8 support;
        /// @notice The number of votes the voter had, which were cast
        uint96 votes;
    }

    /// @notice Possible states that a proposal may be in
    enum ProposalState {
        Pending,
        Active,
        Canceled,
        Defeated,
        Succeeded,
        Queued,
        Expired,
        Executed,
        Vetoed
    }
}

/**
 * @title Storage for Governor Bravo Delegate
 * @notice For future upgrades, do not change NounsDAOStorageV2. Create a new
 * contract which implements NounsDAOStorageV2 and following the naming convention
 * NounsDAOStorageVX.
 */
contract NounsDAOStorageV2 is NounsDAOStorageV1Adjusted {
    DynamicQuorumParamsCheckpoint[] public quorumParamsCheckpoints;

    /// @notice Pending new vetoer
    address public pendingVetoer;

    struct DynamicQuorumParams {
        /// @notice The minimum basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed.
        uint16 minQuorumVotesBPS;
        /// @notice The maximum basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed.
        uint16 maxQuorumVotesBPS;
        /// @notice The dynamic quorum coefficient
        /// @dev Assumed to be fixed point integer with 6 decimals, i.e 0.2 is represented as 0.2 * 1e6 = 200000
        uint32 quorumCoefficient;
    }

    /// @notice A checkpoint for storing dynamic quorum params from a given block
    struct DynamicQuorumParamsCheckpoint {
        /// @notice The block at which the new values were set
        uint32 fromBlock;
        /// @notice The parameter values of this checkpoint
        DynamicQuorumParams params;
    }

    struct ProposalCondensed {
        /// @notice Unique id for looking up a proposal
        uint256 id;
        /// @notice Creator of the proposal
        address proposer;
        /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 proposalThreshold;
        /// @notice The minimum number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo
        uint256 quorumVotes;
        /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
        uint256 eta;
        /// @notice The block at which voting begins: holders must delegate their votes prior to this block
        uint256 startBlock;
        /// @notice The block at which voting ends: votes must be cast prior to this block
        uint256 endBlock;
        /// @notice Current number of votes in favor of this proposal
        uint256 forVotes;
        /// @notice Current number of votes in opposition to this proposal
        uint256 againstVotes;
        /// @notice Current number of votes for abstaining for this proposal
        uint256 abstainVotes;
        /// @notice Flag marking whether the proposal has been canceled
        bool canceled;
        /// @notice Flag marking whether the proposal has been vetoed
        bool vetoed;
        /// @notice Flag marking whether the proposal has been executed
        bool executed;
        /// @notice The total supply at the time of proposal creation
        uint256 totalSupply;
        /// @notice The block at which this proposal was created
        uint256 creationBlock;
    }
}

interface INounsDAOExecutor {
    function delay() external view returns (uint256);

    function GRACE_PERIOD() external view returns (uint256);

    function acceptAdmin() external;

    function queuedTransactions(bytes32 hash) external view returns (bool);

    function queueTransaction(
        address target,
        uint256 value,
        string calldata signature,
        bytes calldata data,
        uint256 eta
    ) external returns (bytes32);

    function cancelTransaction(
        address target,
        uint256 value,
        string calldata signature,
        bytes calldata data,
        uint256 eta
    ) external;

    function executeTransaction(
        address target,
        uint256 value,
        string calldata signature,
        bytes calldata data,
        uint256 eta
    ) external payable returns (bytes memory);
}

interface NounsTokenLike {
    function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96);

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

Contract ABI

[{"type":"event","name":"NewAdmin","inputs":[{"type":"address","name":"oldAdmin","internalType":"address","indexed":false},{"type":"address","name":"newAdmin","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"NewImplementation","inputs":[{"type":"address","name":"oldImplementation","internalType":"address","indexed":false},{"type":"address","name":"newImplementation","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"NewPendingAdmin","inputs":[{"type":"address","name":"oldPendingAdmin","internalType":"address","indexed":false},{"type":"address","name":"newPendingAdmin","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"NewVetoer","inputs":[{"type":"address","name":"oldVetoer","internalType":"address","indexed":false},{"type":"address","name":"newVetoer","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"ProposalCanceled","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ProposalCreated","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"address","name":"proposer","internalType":"address","indexed":false},{"type":"address[]","name":"targets","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"values","internalType":"uint256[]","indexed":false},{"type":"string[]","name":"signatures","internalType":"string[]","indexed":false},{"type":"bytes[]","name":"calldatas","internalType":"bytes[]","indexed":false},{"type":"uint256","name":"startBlock","internalType":"uint256","indexed":false},{"type":"uint256","name":"endBlock","internalType":"uint256","indexed":false},{"type":"string","name":"description","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"ProposalCreatedWithRequirements","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"address","name":"proposer","internalType":"address","indexed":false},{"type":"address[]","name":"targets","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"values","internalType":"uint256[]","indexed":false},{"type":"string[]","name":"signatures","internalType":"string[]","indexed":false},{"type":"bytes[]","name":"calldatas","internalType":"bytes[]","indexed":false},{"type":"uint256","name":"startBlock","internalType":"uint256","indexed":false},{"type":"uint256","name":"endBlock","internalType":"uint256","indexed":false},{"type":"uint256","name":"proposalThreshold","internalType":"uint256","indexed":false},{"type":"uint256","name":"quorumVotes","internalType":"uint256","indexed":false},{"type":"string","name":"description","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"ProposalExecuted","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ProposalQueued","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"uint256","name":"eta","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ProposalThresholdBPSSet","inputs":[{"type":"uint256","name":"oldProposalThresholdBPS","internalType":"uint256","indexed":false},{"type":"uint256","name":"newProposalThresholdBPS","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ProposalVetoed","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"QuorumVotesBPSSet","inputs":[{"type":"uint256","name":"oldQuorumVotesBPS","internalType":"uint256","indexed":false},{"type":"uint256","name":"newQuorumVotesBPS","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"VoteCast","inputs":[{"type":"address","name":"voter","internalType":"address","indexed":true},{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"uint8","name":"support","internalType":"uint8","indexed":false},{"type":"uint256","name":"votes","internalType":"uint256","indexed":false},{"type":"string","name":"reason","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"VotingDelaySet","inputs":[{"type":"uint256","name":"oldVotingDelay","internalType":"uint256","indexed":false},{"type":"uint256","name":"newVotingDelay","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"VotingPeriodSet","inputs":[{"type":"uint256","name":"oldVotingPeriod","internalType":"uint256","indexed":false},{"type":"uint256","name":"newVotingPeriod","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"BALLOT_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DOMAIN_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_PROPOSAL_THRESHOLD_BPS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_QUORUM_VOTES_BPS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_VOTING_DELAY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_VOTING_PERIOD","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_PROPOSAL_THRESHOLD_BPS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_QUORUM_VOTES_BPS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_VOTING_DELAY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_VOTING_PERIOD","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_acceptAdmin","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_burnVetoPower","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_setPendingAdmin","inputs":[{"type":"address","name":"newPendingAdmin","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_setProposalThresholdBPS","inputs":[{"type":"uint256","name":"newProposalThresholdBPS","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_setQuorumVotesBPS","inputs":[{"type":"uint256","name":"newQuorumVotesBPS","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_setVetoer","inputs":[{"type":"address","name":"newVetoer","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_setVotingDelay","inputs":[{"type":"uint256","name":"newVotingDelay","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_setVotingPeriod","inputs":[{"type":"uint256","name":"newVotingPeriod","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"admin","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancel","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"castVote","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"},{"type":"uint8","name":"support","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"castVoteBySig","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"},{"type":"uint8","name":"support","internalType":"uint8"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"castVoteWithReason","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"},{"type":"uint8","name":"support","internalType":"uint8"},{"type":"string","name":"reason","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"execute","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"targets","internalType":"address[]"},{"type":"uint256[]","name":"values","internalType":"uint256[]"},{"type":"string[]","name":"signatures","internalType":"string[]"},{"type":"bytes[]","name":"calldatas","internalType":"bytes[]"}],"name":"getActions","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct NounsDAOStorageV1.Receipt","components":[{"type":"bool","name":"hasVoted","internalType":"bool"},{"type":"uint8","name":"support","internalType":"uint8"},{"type":"uint96","name":"votes","internalType":"uint96"}]}],"name":"getReceipt","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"},{"type":"address","name":"voter","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"implementation","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"address","name":"timelock_","internalType":"address"},{"type":"address","name":"nouns_","internalType":"address"},{"type":"address","name":"vetoer_","internalType":"address"},{"type":"uint256","name":"votingPeriod_","internalType":"uint256"},{"type":"uint256","name":"votingDelay_","internalType":"uint256"},{"type":"uint256","name":"proposalThresholdBPS_","internalType":"uint256"},{"type":"uint256","name":"quorumVotesBPS_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"latestProposalIds","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract NounsTokenLike"}],"name":"nouns","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingAdmin","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"proposalCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"proposalMaxOperations","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"proposalThreshold","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"proposalThresholdBPS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"address","name":"proposer","internalType":"address"},{"type":"uint256","name":"proposalThreshold","internalType":"uint256"},{"type":"uint256","name":"quorumVotes","internalType":"uint256"},{"type":"uint256","name":"eta","internalType":"uint256"},{"type":"uint256","name":"startBlock","internalType":"uint256"},{"type":"uint256","name":"endBlock","internalType":"uint256"},{"type":"uint256","name":"forVotes","internalType":"uint256"},{"type":"uint256","name":"againstVotes","internalType":"uint256"},{"type":"uint256","name":"abstainVotes","internalType":"uint256"},{"type":"bool","name":"canceled","internalType":"bool"},{"type":"bool","name":"vetoed","internalType":"bool"},{"type":"bool","name":"executed","internalType":"bool"}],"name":"proposals","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"propose","inputs":[{"type":"address[]","name":"targets","internalType":"address[]"},{"type":"uint256[]","name":"values","internalType":"uint256[]"},{"type":"string[]","name":"signatures","internalType":"string[]"},{"type":"bytes[]","name":"calldatas","internalType":"bytes[]"},{"type":"string","name":"description","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"queue","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"quorumVotes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"quorumVotesBPS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"enum NounsDAOStorageV1.ProposalState"}],"name":"state","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract INounsDAOExecutor"}],"name":"timelock","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"veto","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"vetoer","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"votingDelay","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"votingPeriod","inputs":[]}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b506146cf806100206000396000f3fe608060405234801561001057600080fd5b50600436106103155760003560e01c80636f3eff28116101a7578063c82fbd08116100ee578063deaaa7cc11610097578063e9c714f211610071578063e9c714f2146107f2578063f851a440146107fa578063fe0d94c11461080d57600080fd5b8063deaaa7cc14610704578063e23a9a521461072b578063e48083fe146106a757600080fd5b8063da35c664116100c8578063da35c664146106d5578063da95691a146106de578063ddf0b009146106f157600080fd5b8063c82fbd08146106a7578063d33219b4146106af578063d8bff440146106c257600080fd5b8063a64e024a11610150578063b71d1a0c1161012a578063b71d1a0c14610683578063bb67758214610696578063bf7a29631461069f57600080fd5b8063a64e024a14610668578063b112626314610672578063b58131b01461067b57600080fd5b806383cce0e11161018157806383cce0e11461063957806396300b7d1461064257806397d048e51461065557600080fd5b80636f3eff281461060b5780637b3c71d31461061e5780637bdbe4d01461063157600080fd5b80632230e1551161026b5780633932abb11161021457806340e58ee5116101ee57806340e58ee5146105d257806356781388146105e55780635c60da1b146105f857600080fd5b80633932abb1146105965780633bccf4fd1461059f5780633e4f49e6146105b257600080fd5b80632b4656c8116102455780632b4656c81461054d5780632de45f1814610560578063328dd9821461057357600080fd5b80632230e1551461051257806324bc1a641461051a578063267822471461052257600080fd5b806317977c61116102cd5780631e7b5d3a116102a75780631e7b5d3a146104d957806320606b70146104e2578063215809ca1461050957600080fd5b806317977c61146104935780631d28dec7146104b35780631dfb1b5a146104c657600080fd5b806306fdde03116102fe57806306fdde031461042c5780630ea2d98c1461047557806314a67ea41461048a57600080fd5b8063013cf08b1461031a57806302a251a314610415575b600080fd5b6103a0610328366004613ece565b600b602081905260009182526040909120805460018201546002830154600384015460048501546009860154600a87015497870154600c880154600d890154600e9099015497996001600160a01b039097169895979496939592949192909160ff80821691610100810482169162010000909104168d565b604080519d8e526001600160a01b03909c1660208e01529a8c019990995260608b019790975260808a019590955260a089019390935260c088019190915260e08701526101008601526101208501521515610140840152151561016083015215156101808201526101a0015b60405180910390f35b61041e60055481565b60405190815260200161040c565b6104686040518060400160405280600981526020017f4e6f756e732044414f000000000000000000000000000000000000000000000081525081565b60405161040c91906142f4565b610488610483366004613ece565b610820565b005b61041e60065481565b61041e6104a1366004613cc7565b600c6020526000908152604090205481565b6104886104c1366004613ece565b610972565b6104886104d4366004613ece565b610c62565b61041e6103e881565b61041e7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b61041e61168081565b61041e60c881565b61041e610da5565b600154610535906001600160a01b031681565b6040516001600160a01b03909116815260200161040c565b61048861055b366004613ce2565b610e3d565b600a54610535906001600160a01b031681565b610586610581366004613ece565b61137e565b60405161040c9493929190614274565b61041e60045481565b6104886105ad366004613fbd565b61160f565b6105c56105c0366004613ece565b6118c0565b60405161040c91906142cc565b6104886105e0366004613ece565b611aad565b6104886105f3366004613f13565b611e1e565b600254610535906001600160a01b031681565b610488610619366004613ece565b611e8e565b61048861062c366004613f36565b611fd1565b61041e600a81565b61041e60075481565b610488610650366004613cc7565b612021565b610488610663366004613ece565b612122565b61041e62013b0081565b61041e619d8081565b61041e612265565b610488610691366004613cc7565b6122bb565b61041e6107d081565b6104886123ad565b61041e600181565b600954610535906001600160a01b031681565b600354610535906001600160a01b031681565b61041e60085481565b61041e6106ec366004613d4a565b612439565b6104886106ff366004613ece565b612b6b565b61041e7f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b6107bd610739366004613ee7565b6040805160608101825260008082526020820181905291810191909152506000918252600b602090815260408084206001600160a01b03939093168452600f9092018152918190208151606081018352905460ff8082161515835261010082041693820193909352620100009092046bffffffffffffffffffffffff169082015290565b6040805182511515815260208084015160ff1690820152918101516bffffffffffffffffffffffff169082015260600161040c565b610488612eb7565b600054610535906001600160a01b031681565b61048861081b366004613ece565b613008565b6000546001600160a01b031633146108a55760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a2061646d6960448201527f6e206f6e6c79000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61168081101580156108ba575062013b008111155b61092c5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a20696e766160448201527f6c696420766f74696e6720706572696f64000000000000000000000000000000606482015260840161089c565b600580549082905560408051828152602081018490527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e882891015b60405180910390a15050565b6003546001600160a01b03166109f05760405162461bcd60e51b815260206004820152602160248201527f4e6f756e7344414f3a3a7665746f3a207665746f20706f776572206275726e6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161089c565b6003546001600160a01b03163314610a4a5760405162461bcd60e51b815260206004820152601b60248201527f4e6f756e7344414f3a3a7665746f3a206f6e6c79207665746f65720000000000604482015260640161089c565b6007610a55826118c0565b6008811115610a6657610a66614657565b1415610ada5760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a7665746f3a2063616e6e6f74207665746f206578656360448201527f757465642070726f706f73616c00000000000000000000000000000000000000606482015260840161089c565b6000818152600b60205260408120600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055905b6005820154811015610c31576009546005830180546001600160a01b039092169163591fcdfe919084908110610b5057610b5061466d565b6000918252602090912001546006850180546001600160a01b039092169185908110610b7e57610b7e61466d565b9060005260206000200154856007018581548110610b9e57610b9e61466d565b90600052602060002001866008018681548110610bbd57610bbd61466d565b9060005260206000200187600401546040518663ffffffff1660e01b8152600401610bec95949392919061423a565b600060405180830381600087803b158015610c0657600080fd5b505af1158015610c1a573d6000803e3d6000fd5b505050508080610c2990614608565b915050610b18565b506040518281527fde0cea2a3a0097cc3d981d40c375407760e85bc9c5e69aea449ac3885f8615c690602001610966565b6000546001600160a01b03163314610ce25760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a2061646d696e60448201527f206f6e6c79000000000000000000000000000000000000000000000000000000606482015260840161089c565b60018110158015610cf55750619d808111155b610d675760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a20696e76616c60448201527f696420766f74696e672064656c61790000000000000000000000000000000000606482015260840161089c565b600480549082905560408051828152602081018490527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a939101610966565b6000610e38600754600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfb57600080fd5b505afa158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e339190613e3e565b613246565b905090565b6009546001600160a01b031615610ebc5760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a2063616e206f6e6c79206960448201527f6e697469616c697a65206f6e6365000000000000000000000000000000000000606482015260840161089c565b6000546001600160a01b03163314610f165760405162461bcd60e51b815260206004820181905260248201527f4e6f756e7344414f3a3a696e697469616c697a653a2061646d696e206f6e6c79604482015260640161089c565b6001600160a01b038716610f925760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420746960448201527f6d656c6f636b2061646472657373000000000000000000000000000000000000606482015260840161089c565b6001600160a01b03861661100e5760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c6964206e6f60448201527f756e732061646472657373000000000000000000000000000000000000000000606482015260840161089c565b6116808410158015611023575062013b008411155b6110955760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420766f60448201527f74696e6720706572696f64000000000000000000000000000000000000000000606482015260840161089c565b600183101580156110a85750619d808311155b61111a5760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420766f60448201527f74696e672064656c617900000000000000000000000000000000000000000000606482015260840161089c565b6001821015801561112d57506103e88211155b61119f5760405162461bcd60e51b815260206004820152603060248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420707260448201527f6f706f73616c207468726573686f6c6400000000000000000000000000000000606482015260840161089c565b60c881101580156111b257506107d08111155b6112245760405162461bcd60e51b815260206004820152603060248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420707260448201527f6f706f73616c207468726573686f6c6400000000000000000000000000000000606482015260840161089c565b60055460408051918252602082018690527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a160045460408051918252602082018590527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a160065460408051918252602082018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a58910160405180910390a160075460408051918252602082018390527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b910160405180910390a1600980547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b03998a1617909155600a8054821697891697909717909655600380549096169490961693909317909355600555600491909155600655600755565b6060806060806000600b60008781526020019081526020016000209050806005018160060182600701836008018380548060200260200160405190810160405280929190818152602001828054801561140057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116113e2575b505050505093508280548060200260200160405190810160405280929190818152602001828054801561145257602002820191906000526020600020905b81548152602001906001019080831161143e575b5050505050925081805480602002602001604051908101604052809291908181526020016000905b82821015611526578382906000526020600020018054611499906145d3565b80601f01602080910402602001604051908101604052809291908181526020018280546114c5906145d3565b80156115125780601f106114e757610100808354040283529160200191611512565b820191906000526020600020905b8154815290600101906020018083116114f557829003601f168201915b50505050508152602001906001019061147a565b50505050915080805480602002602001604051908101604052809291908181526020016000905b828210156115f957838290600052602060002001805461156c906145d3565b80601f0160208091040260200160405190810160405280929190818152602001828054611598906145d3565b80156115e55780601f106115ba576101008083540402835291602001916115e5565b820191906000526020600020905b8154815290600101906020018083116115c857829003601f168201915b50505050508152602001906001019061154d565b5050505090509450945094509450509193509193565b604080518082018252600981527f4e6f756e732044414f000000000000000000000000000000000000000000000060209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527fe1dd93b3612547b4bb7c3d429f3df8508d84f5a4f63b5e2e44340b94698e6b3b81840152466060820152306080808301919091528351808303909101815260a0820184528051908301207f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f60c083015260e0820189905260ff881661010080840191909152845180840390910181526101208301909452835193909201929092207f19010000000000000000000000000000000000000000000000000000000000006101408401526101428301829052610162830181905290916000906101820160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa1580156117b7573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166118405760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63617374566f746542795369673a20696e76616c696460448201527f207369676e617475726500000000000000000000000000000000000000000000606482015260840161089c565b806001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48a8a611878858e8e613266565b6040805193845260ff90921660208401526bffffffffffffffffffffffff169082015260806060820181905260009082015260a00160405180910390a2505050505050505050565b60008160085410156119395760405162461bcd60e51b8152602060048201526024808201527f4e6f756e7344414f3a3a73746174653a20696e76616c69642070726f706f736160448201527f6c20696400000000000000000000000000000000000000000000000000000000606482015260840161089c565b6000828152600b60205260409020600e810154610100900460ff16156119625750600892915050565b600e81015460ff16156119785750600292915050565b8060090154431161198c5750600092915050565b80600a015443116119a05750600192915050565b80600c015481600b01541115806119be5750806003015481600b0154105b156119cc5750600392915050565b60048101546119de5750600492915050565b600e81015462010000900460ff16156119fa5750600792915050565b600960009054906101000a90046001600160a01b03166001600160a01b031663c1a287e26040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4857600080fd5b505afa158015611a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a809190613e3e565b8160040154611a8f9190614515565b4210611a9e5750600692915050565b50600592915050565b50919050565b6007611ab8826118c0565b6008811115611ac957611ac9614657565b1415611b3d5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a63616e63656c3a2063616e6e6f742063616e63656c2060448201527f65786563757465642070726f706f73616c000000000000000000000000000000606482015260840161089c565b6000818152600b6020526040902060018101546001600160a01b0316331480611c3257506002810154600a546001808401546001600160a01b039283169263782d6fe192911690611b8e904361458c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b158015611bea57600080fd5b505afa158015611bfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c22919061400b565b6bffffffffffffffffffffffff16105b611ca45760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63616e63656c3a2070726f706f7365722061626f766560448201527f207468726573686f6c6400000000000000000000000000000000000000000000606482015260840161089c565b600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560005b6005820154811015611ded576009546005830180546001600160a01b039092169163591fcdfe919084908110611d0c57611d0c61466d565b6000918252602090912001546006850180546001600160a01b039092169185908110611d3a57611d3a61466d565b9060005260206000200154856007018581548110611d5a57611d5a61466d565b90600052602060002001866008018681548110611d7957611d7961466d565b9060005260206000200187600401546040518663ffffffff1660e01b8152600401611da895949392919061423a565b600060405180830381600087803b158015611dc257600080fd5b505af1158015611dd6573d6000803e3d6000fd5b505050508080611de590614608565b915050611cd4565b506040518281527f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90602001610966565b337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48383611e4d848383613266565b6040805193845260ff90921660208401526bffffffffffffffffffffffff169082015260806060820181905260009082015260a00160405180910390a25050565b6000546001600160a01b03163314611f0e5760405162461bcd60e51b815260206004820152602860248201527f4e6f756e7344414f3a3a5f73657451756f72756d566f7465734250533a20616460448201527f6d696e206f6e6c79000000000000000000000000000000000000000000000000606482015260840161089c565b60c88110158015611f2157506107d08111155b611f935760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c640000000000606482015260840161089c565b600780549082905560408051828152602081018490527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b9101610966565b337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48585612000848383613266565b8686604051612013959493929190614443565b60405180910390a250505050565b6003546001600160a01b031633146120a15760405162461bcd60e51b815260206004820152602160248201527f4e6f756e7344414f3a3a5f7365745665746f65723a207665746f6572206f6e6c60448201527f7900000000000000000000000000000000000000000000000000000000000000606482015260840161089c565b600354604080516001600160a01b03928316815291831660208301527fc5644f3588a066b15dcf6b636b74aadca57cfaccf608d9de7d8786364b7a8d02910160405180910390a1600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000546001600160a01b031633146121a25760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c644260448201527f50533a2061646d696e206f6e6c79000000000000000000000000000000000000606482015260840161089c565b600181101580156121b557506103e88111155b6122275760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c640000000000606482015260840161089c565b600680549082905560408051828152602081018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a589101610966565b6000610e38600654600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfb57600080fd5b6000546001600160a01b0316331461233b5760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f73657450656e64696e6741646d696e3a2061646d6960448201527f6e206f6e6c790000000000000000000000000000000000000000000000000000606482015260840161089c565b600180546001600160a01b038381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610966565b6003546001600160a01b0316331461242d5760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f6275726e5665746f506f7765723a207665746f657260448201527f206f6e6c79000000000000000000000000000000000000000000000000000000606482015260840161089c565b6124376000612021565b565b600061246d6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bb57600080fd5b505afa1580156124cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f39190613e3e565b80825260065461250291613246565b60208201819052600a546001600160a01b031663782d6fe13361252660014361458c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b15801561258257600080fd5b505afa158015612596573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ba919061400b565b6bffffffffffffffffffffffff161161263b5760405162461bcd60e51b815260206004820152603a60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73657220766f746560448201527f732062656c6f772070726f706f73616c207468726573686f6c64000000000000606482015260840161089c565b8551875114801561264d575084518751145b801561265a575083518751145b6126cc5760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73616c2066756e6360448201527f74696f6e20696e666f726d6174696f6e206172697479206d69736d6174636800606482015260840161089c565b86516127405760405162461bcd60e51b815260206004820152602760248201527f4e6f756e7344414f3a3a70726f706f73653a206d7573742070726f766964652060448201527f616374696f6e7300000000000000000000000000000000000000000000000000606482015260840161089c565b600a875111156127b85760405162461bcd60e51b815260206004820152602360248201527f4e6f756e7344414f3a3a70726f706f73653a20746f6f206d616e79206163746960448201527f6f6e730000000000000000000000000000000000000000000000000000000000606482015260840161089c565b336000908152600c60205260409081902054908201819052156129445760006127e482604001516118c0565b905060018160088111156127fa576127fa614657565b14156128945760405162461bcd60e51b815260206004820152605360248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527f616479206163746976652070726f706f73616c00000000000000000000000000608482015260a40161089c565b60008160088111156128a8576128a8614657565b14156129425760405162461bcd60e51b815260206004820152605460248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527f6164792070656e64696e672070726f706f73616c000000000000000000000000608482015260a40161089c565b505b6004546129519043614515565b6060820181905260055461296491614515565b60808201526008805490600061297983614608565b90915550506008546000818152600b602090815260409091209182556001820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055820151600282015560075482516129d89190613246565b60038201556000600482015587516129f990600583019060208b01906137d5565b508651612a0f90600683019060208a0190613852565b508551612a25906007830190602089019061388d565b508451612a3b90600883019060208801906138e6565b506060820151600982019081556080830151600a83019081556000600b8401819055600c808501829055600d8501829055600e850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000169055845460018601546001600160a01b031683526020919091526040918290208190559254915490517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e093612af893909233928e928e928e928e9291908e90614307565b60405180910390a17f6af0134faa0f9290c1d686d55012aca80302d31d5c856e4bc7954f7613dc7f878160000154338a8a8a8a876009015488600a015489600201548a600301548e604051612b579b9a9998979695949392919061439d565b60405180910390a154979650505050505050565b6004612b76826118c0565b6008811115612b8757612b87614657565b14612bfa5760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a71756575653a2070726f706f73616c2063616e206f6e60448201527f6c79206265207175657565642069662069742069732073756363656564656400606482015260840161089c565b6000818152600b6020908152604080832060095482517f6a42b8f800000000000000000000000000000000000000000000000000000000815292519194936001600160a01b0390911692636a42b8f89260048083019392829003018186803b158015612c6557600080fd5b505afa158015612c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c9d9190613e3e565b612ca79042614515565b905060005b6005830154811015612e7157612e5f836005018281548110612cd057612cd061466d565b6000918252602090912001546006850180546001600160a01b039092169184908110612cfe57612cfe61466d565b9060005260206000200154856007018481548110612d1e57612d1e61466d565b906000526020600020018054612d33906145d3565b80601f0160208091040260200160405190810160405280929190818152602001828054612d5f906145d3565b8015612dac5780601f10612d8157610100808354040283529160200191612dac565b820191906000526020600020905b815481529060010190602001808311612d8f57829003601f168201915b5050505050866008018581548110612dc657612dc661466d565b906000526020600020018054612ddb906145d3565b80601f0160208091040260200160405190810160405280929190818152602001828054612e07906145d3565b8015612e545780601f10612e2957610100808354040283529160200191612e54565b820191906000526020600020905b815481529060010190602001808311612e3757829003601f168201915b5050505050866135df565b80612e6981614608565b915050612cac565b506004820181905560408051848152602081018390527f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892910160405180910390a1505050565b6001546001600160a01b031633148015612ed057503315155b612f425760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a5f61636365707441646d696e3a2070656e64696e672060448201527f61646d696e206f6e6c7900000000000000000000000000000000000000000000606482015260840161089c565b60008054600180546001600160a01b038082167fffffffffffffffffffffffff000000000000000000000000000000000000000080861682179096559490911690915560408051919092168082526020820184905292917ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc910160405180910390a1600154604080516001600160a01b03808516825290921660208301527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610966565b6005613013826118c0565b600881111561302457613024614657565b14613099576040805162461bcd60e51b81526020600482015260248101919091527f4e6f756e7344414f3a3a657865637574653a2070726f706f73616c2063616e2060448201527f6f6e6c7920626520657865637574656420696620697420697320717565756564606482015260840161089c565b6000818152600b60205260408120600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff1662010000179055905b6005820154811015613215576009546005830180546001600160a01b0390921691630825f38f9190849081106131105761311061466d565b6000918252602090912001546006850180546001600160a01b03909216918590811061313e5761313e61466d565b906000526020600020015485600701858154811061315e5761315e61466d565b9060005260206000200186600801868154811061317d5761317d61466d565b9060005260206000200187600401546040518663ffffffff1660e01b81526004016131ac95949392919061423a565b600060405180830381600087803b1580156131c657600080fd5b505af11580156131da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132029190810190613e57565b508061320d81614608565b9150506130d8565b506040518281527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90602001610966565b6000612710613255848461454f565b61325f919061452d565b9392505050565b60006001613273846118c0565b600881111561328457613284614657565b146132f75760405162461bcd60e51b815260206004820152602c60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746960448201527f6e6720697320636c6f7365640000000000000000000000000000000000000000606482015260840161089c565b60028260ff1611156133715760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20696e766160448201527f6c696420766f7465207479706500000000000000000000000000000000000000606482015260840161089c565b6000838152600b602090815260408083206001600160a01b0388168452600f8101909252909120805460ff16156134105760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746560448201527f7220616c726561647920766f7465640000000000000000000000000000000000606482015260840161089c565b600a5460045460098401546000926001600160a01b03169163782d6fe1918a916134399161458c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b15801561349557600080fd5b505afa1580156134a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134cd919061400b565b905060ff85166134ff57806bffffffffffffffffffffffff1683600c01546134f59190614515565b600c840155613563565b8460ff166001141561353357806bffffffffffffffffffffffff1683600b01546135299190614515565b600b840155613563565b8460ff166002141561356357806bffffffffffffffffffffffff1683600d015461355d9190614515565b600d8401555b81546bffffffffffffffffffffffff821662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff60ff8816610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009093169290921760011791909116179091559150509392505050565b6009546040516001600160a01b039091169063f2b065379061360d90889088908890889088906020016141ed565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161364191815260200190565b60206040518083038186803b15801561365957600080fd5b505afa15801561366d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136919190613e1c565b1561372a5760405162461bcd60e51b815260206004820152605060248201527f4e6f756e7344414f3a3a71756575654f72526576657274496e7465726e616c3a60448201527f206964656e746963616c2070726f706f73616c20616374696f6e20616c72656160648201527f6479207175657565642061742065746100000000000000000000000000000000608482015260a40161089c565b6009546040517f3a66f9010000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690633a66f9019061377b90889088908890889088906004016141ed565b602060405180830381600087803b15801561379557600080fd5b505af11580156137a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cd9190613e3e565b505050505050565b828054828255906000526020600020908101928215613842579160200282015b8281111561384257825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039091161782556020909201916001909101906137f5565b5061384e92915061393f565b5090565b828054828255906000526020600020908101928215613842579160200282015b82811115613842578251825591602001919060010190613872565b8280548282559060005260206000209081019282156138da579160200282015b828111156138da57825180516138ca918491602090910190613954565b50916020019190600101906138ad565b5061384e9291506139c7565b828054828255906000526020600020908101928215613933579160200282015b828111156139335782518051613923918491602090910190613954565b5091602001919060010190613906565b5061384e9291506139e4565b5b8082111561384e5760008155600101613940565b828054613960906145d3565b90600052602060002090601f0160209004810192826139825760008555613842565b82601f1061399b57805160ff1916838001178555613842565b828001600101855582156138425791820182811115613842578251825591602001919060010190613872565b8082111561384e5760006139db8282613a01565b506001016139c7565b8082111561384e5760006139f88282613a01565b506001016139e4565b508054613a0d906145d3565b6000825580601f10613a1d575050565b601f016020900490600052602060002090810190613a3b919061393f565b50565b6000613a51613a4c846144ed565b614498565b9050828152838383011115613a6557600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114613a9357600080fd5b919050565b600082601f830112613aa957600080fd5b81356020613ab9613a4c836144c9565b80838252828201915082860187848660051b8901011115613ad957600080fd5b60005b85811015613aff57613aed82613a7c565b84529284019290840190600101613adc565b5090979650505050505050565b600082601f830112613b1d57600080fd5b81356020613b2d613a4c836144c9565b80838252828201915082860187848660051b8901011115613b4d57600080fd5b60005b85811015613aff57813567ffffffffffffffff811115613b6f57600080fd5b8801603f81018a13613b8057600080fd5b613b918a8783013560408401613a3e565b8552509284019290840190600101613b50565b600082601f830112613bb557600080fd5b81356020613bc5613a4c836144c9565b80838252828201915082860187848660051b8901011115613be557600080fd5b6000805b86811015613c2857823567ffffffffffffffff811115613c07578283fd5b613c158b88838d0101613c96565b8652509385019391850191600101613be9565b509198975050505050505050565b600082601f830112613c4757600080fd5b81356020613c57613a4c836144c9565b80838252828201915082860187848660051b8901011115613c7757600080fd5b60005b85811015613aff57813584529284019290840190600101613c7a565b600082601f830112613ca757600080fd5b61325f83833560208501613a3e565b803560ff81168114613a9357600080fd5b600060208284031215613cd957600080fd5b61325f82613a7c565b600080600080600080600060e0888a031215613cfd57600080fd5b613d0688613a7c565b9650613d1460208901613a7c565b9550613d2260408901613a7c565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080600080600060a08688031215613d6257600080fd5b853567ffffffffffffffff80821115613d7a57600080fd5b613d8689838a01613a98565b96506020880135915080821115613d9c57600080fd5b613da889838a01613c36565b95506040880135915080821115613dbe57600080fd5b613dca89838a01613ba4565b94506060880135915080821115613de057600080fd5b613dec89838a01613b0c565b93506080880135915080821115613e0257600080fd5b50613e0f88828901613c96565b9150509295509295909350565b600060208284031215613e2e57600080fd5b8151801515811461325f57600080fd5b600060208284031215613e5057600080fd5b5051919050565b600060208284031215613e6957600080fd5b815167ffffffffffffffff811115613e8057600080fd5b8201601f81018413613e9157600080fd5b8051613e9f613a4c826144ed565b818152856020838501011115613eb457600080fd5b613ec58260208301602086016145a3565b95945050505050565b600060208284031215613ee057600080fd5b5035919050565b60008060408385031215613efa57600080fd5b82359150613f0a60208401613a7c565b90509250929050565b60008060408385031215613f2657600080fd5b82359150613f0a60208401613cb6565b60008060008060608587031215613f4c57600080fd5b84359350613f5c60208601613cb6565b9250604085013567ffffffffffffffff80821115613f7957600080fd5b818701915087601f830112613f8d57600080fd5b813581811115613f9c57600080fd5b886020828501011115613fae57600080fd5b95989497505060200194505050565b600080600080600060a08688031215613fd557600080fd5b85359450613fe560208701613cb6565b9350613ff360408701613cb6565b94979396509394606081013594506080013592915050565b60006020828403121561401d57600080fd5b81516bffffffffffffffffffffffff8116811461325f57600080fd5b600081518084526020808501945080840160005b838110156140725781516001600160a01b03168752958201959082019060010161404d565b509495945050505050565b600081518084526020808501808196508360051b8101915082860160005b858110156140c55782840389526140b3848351614102565b9885019893509084019060010161409b565b5091979650505050505050565b600081518084526020808501945080840160005b83811015614072578151875295820195908201906001016140e6565b6000815180845261411a8160208601602086016145a3565b601f01601f19169290920160200192915050565b8054600090600181811c908083168061414857607f831692505b602080841082141561416a57634e487b7160e01b600052602260045260246000fd5b83885281801561418157600181146141b3576141e1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616828a01526040890196506141e1565b876000528160002060005b868110156141d95781548b82018501529085019083016141be565b8a0183019750505b50505050505092915050565b6001600160a01b038616815284602082015260a06040820152600061421560a0830186614102565b82810360608401526142278186614102565b9150508260808301529695505050505050565b6001600160a01b038616815284602082015260a06040820152600061426260a083018661412e565b8281036060840152614227818661412e565b6080815260006142876080830187614039565b828103602084015261429981876140d2565b905082810360408401526142ad818661407d565b905082810360608401526142c1818561407d565b979650505050505050565b60208101600983106142ee57634e487b7160e01b600052602160045260246000fd5b91905290565b60208152600061325f6020830184614102565b60006101208b83526001600160a01b038b1660208401528060408401526143308184018b614039565b90508281036060840152614344818a6140d2565b90508281036080840152614358818961407d565b905082810360a084015261436c818861407d565b90508560c08401528460e084015282810361010084015261438d8185614102565b9c9b505050505050505050505050565b60006101608d83526001600160a01b038d1660208401528060408401526143c68184018d614039565b905082810360608401526143da818c6140d2565b905082810360808401526143ee818b61407d565b905082810360a0840152614402818a61407d565b90508760c08401528660e084015285610100840152846101208401528281036101408401526144318185614102565b9e9d5050505050505050505050505050565b85815260ff851660208201526bffffffffffffffffffffffff8416604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b604051601f8201601f1916810167ffffffffffffffff811182821017156144c1576144c1614683565b604052919050565b600067ffffffffffffffff8211156144e3576144e3614683565b5060051b60200190565b600067ffffffffffffffff82111561450757614507614683565b50601f01601f191660200190565b6000821982111561452857614528614641565b500190565b60008261454a57634e487b7160e01b600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561458757614587614641565b500290565b60008282101561459e5761459e614641565b500390565b60005b838110156145be5781810151838201526020016145a6565b838111156145cd576000848401525b50505050565b600181811c908216806145e757607f821691505b60208210811415611aa757634e487b7160e01b600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561463a5761463a614641565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea26469706673582212208dc1504ea4aef7242fe984c45260900e92d954e158ac4bec468f03db7a63bfab64736f6c63430008060033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106103155760003560e01c80636f3eff28116101a7578063c82fbd08116100ee578063deaaa7cc11610097578063e9c714f211610071578063e9c714f2146107f2578063f851a440146107fa578063fe0d94c11461080d57600080fd5b8063deaaa7cc14610704578063e23a9a521461072b578063e48083fe146106a757600080fd5b8063da35c664116100c8578063da35c664146106d5578063da95691a146106de578063ddf0b009146106f157600080fd5b8063c82fbd08146106a7578063d33219b4146106af578063d8bff440146106c257600080fd5b8063a64e024a11610150578063b71d1a0c1161012a578063b71d1a0c14610683578063bb67758214610696578063bf7a29631461069f57600080fd5b8063a64e024a14610668578063b112626314610672578063b58131b01461067b57600080fd5b806383cce0e11161018157806383cce0e11461063957806396300b7d1461064257806397d048e51461065557600080fd5b80636f3eff281461060b5780637b3c71d31461061e5780637bdbe4d01461063157600080fd5b80632230e1551161026b5780633932abb11161021457806340e58ee5116101ee57806340e58ee5146105d257806356781388146105e55780635c60da1b146105f857600080fd5b80633932abb1146105965780633bccf4fd1461059f5780633e4f49e6146105b257600080fd5b80632b4656c8116102455780632b4656c81461054d5780632de45f1814610560578063328dd9821461057357600080fd5b80632230e1551461051257806324bc1a641461051a578063267822471461052257600080fd5b806317977c61116102cd5780631e7b5d3a116102a75780631e7b5d3a146104d957806320606b70146104e2578063215809ca1461050957600080fd5b806317977c61146104935780631d28dec7146104b35780631dfb1b5a146104c657600080fd5b806306fdde03116102fe57806306fdde031461042c5780630ea2d98c1461047557806314a67ea41461048a57600080fd5b8063013cf08b1461031a57806302a251a314610415575b600080fd5b6103a0610328366004613ece565b600b602081905260009182526040909120805460018201546002830154600384015460048501546009860154600a87015497870154600c880154600d890154600e9099015497996001600160a01b039097169895979496939592949192909160ff80821691610100810482169162010000909104168d565b604080519d8e526001600160a01b03909c1660208e01529a8c019990995260608b019790975260808a019590955260a089019390935260c088019190915260e08701526101008601526101208501521515610140840152151561016083015215156101808201526101a0015b60405180910390f35b61041e60055481565b60405190815260200161040c565b6104686040518060400160405280600981526020017f4e6f756e732044414f000000000000000000000000000000000000000000000081525081565b60405161040c91906142f4565b610488610483366004613ece565b610820565b005b61041e60065481565b61041e6104a1366004613cc7565b600c6020526000908152604090205481565b6104886104c1366004613ece565b610972565b6104886104d4366004613ece565b610c62565b61041e6103e881565b61041e7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b61041e61168081565b61041e60c881565b61041e610da5565b600154610535906001600160a01b031681565b6040516001600160a01b03909116815260200161040c565b61048861055b366004613ce2565b610e3d565b600a54610535906001600160a01b031681565b610586610581366004613ece565b61137e565b60405161040c9493929190614274565b61041e60045481565b6104886105ad366004613fbd565b61160f565b6105c56105c0366004613ece565b6118c0565b60405161040c91906142cc565b6104886105e0366004613ece565b611aad565b6104886105f3366004613f13565b611e1e565b600254610535906001600160a01b031681565b610488610619366004613ece565b611e8e565b61048861062c366004613f36565b611fd1565b61041e600a81565b61041e60075481565b610488610650366004613cc7565b612021565b610488610663366004613ece565b612122565b61041e62013b0081565b61041e619d8081565b61041e612265565b610488610691366004613cc7565b6122bb565b61041e6107d081565b6104886123ad565b61041e600181565b600954610535906001600160a01b031681565b600354610535906001600160a01b031681565b61041e60085481565b61041e6106ec366004613d4a565b612439565b6104886106ff366004613ece565b612b6b565b61041e7f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b6107bd610739366004613ee7565b6040805160608101825260008082526020820181905291810191909152506000918252600b602090815260408084206001600160a01b03939093168452600f9092018152918190208151606081018352905460ff8082161515835261010082041693820193909352620100009092046bffffffffffffffffffffffff169082015290565b6040805182511515815260208084015160ff1690820152918101516bffffffffffffffffffffffff169082015260600161040c565b610488612eb7565b600054610535906001600160a01b031681565b61048861081b366004613ece565b613008565b6000546001600160a01b031633146108a55760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a2061646d6960448201527f6e206f6e6c79000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61168081101580156108ba575062013b008111155b61092c5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a20696e766160448201527f6c696420766f74696e6720706572696f64000000000000000000000000000000606482015260840161089c565b600580549082905560408051828152602081018490527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e882891015b60405180910390a15050565b6003546001600160a01b03166109f05760405162461bcd60e51b815260206004820152602160248201527f4e6f756e7344414f3a3a7665746f3a207665746f20706f776572206275726e6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161089c565b6003546001600160a01b03163314610a4a5760405162461bcd60e51b815260206004820152601b60248201527f4e6f756e7344414f3a3a7665746f3a206f6e6c79207665746f65720000000000604482015260640161089c565b6007610a55826118c0565b6008811115610a6657610a66614657565b1415610ada5760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a7665746f3a2063616e6e6f74207665746f206578656360448201527f757465642070726f706f73616c00000000000000000000000000000000000000606482015260840161089c565b6000818152600b60205260408120600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055905b6005820154811015610c31576009546005830180546001600160a01b039092169163591fcdfe919084908110610b5057610b5061466d565b6000918252602090912001546006850180546001600160a01b039092169185908110610b7e57610b7e61466d565b9060005260206000200154856007018581548110610b9e57610b9e61466d565b90600052602060002001866008018681548110610bbd57610bbd61466d565b9060005260206000200187600401546040518663ffffffff1660e01b8152600401610bec95949392919061423a565b600060405180830381600087803b158015610c0657600080fd5b505af1158015610c1a573d6000803e3d6000fd5b505050508080610c2990614608565b915050610b18565b506040518281527fde0cea2a3a0097cc3d981d40c375407760e85bc9c5e69aea449ac3885f8615c690602001610966565b6000546001600160a01b03163314610ce25760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a2061646d696e60448201527f206f6e6c79000000000000000000000000000000000000000000000000000000606482015260840161089c565b60018110158015610cf55750619d808111155b610d675760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a20696e76616c60448201527f696420766f74696e672064656c61790000000000000000000000000000000000606482015260840161089c565b600480549082905560408051828152602081018490527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a939101610966565b6000610e38600754600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfb57600080fd5b505afa158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e339190613e3e565b613246565b905090565b6009546001600160a01b031615610ebc5760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a2063616e206f6e6c79206960448201527f6e697469616c697a65206f6e6365000000000000000000000000000000000000606482015260840161089c565b6000546001600160a01b03163314610f165760405162461bcd60e51b815260206004820181905260248201527f4e6f756e7344414f3a3a696e697469616c697a653a2061646d696e206f6e6c79604482015260640161089c565b6001600160a01b038716610f925760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420746960448201527f6d656c6f636b2061646472657373000000000000000000000000000000000000606482015260840161089c565b6001600160a01b03861661100e5760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c6964206e6f60448201527f756e732061646472657373000000000000000000000000000000000000000000606482015260840161089c565b6116808410158015611023575062013b008411155b6110955760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420766f60448201527f74696e6720706572696f64000000000000000000000000000000000000000000606482015260840161089c565b600183101580156110a85750619d808311155b61111a5760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420766f60448201527f74696e672064656c617900000000000000000000000000000000000000000000606482015260840161089c565b6001821015801561112d57506103e88211155b61119f5760405162461bcd60e51b815260206004820152603060248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420707260448201527f6f706f73616c207468726573686f6c6400000000000000000000000000000000606482015260840161089c565b60c881101580156111b257506107d08111155b6112245760405162461bcd60e51b815260206004820152603060248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420707260448201527f6f706f73616c207468726573686f6c6400000000000000000000000000000000606482015260840161089c565b60055460408051918252602082018690527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a160045460408051918252602082018590527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a160065460408051918252602082018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a58910160405180910390a160075460408051918252602082018390527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b910160405180910390a1600980547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b03998a1617909155600a8054821697891697909717909655600380549096169490961693909317909355600555600491909155600655600755565b6060806060806000600b60008781526020019081526020016000209050806005018160060182600701836008018380548060200260200160405190810160405280929190818152602001828054801561140057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116113e2575b505050505093508280548060200260200160405190810160405280929190818152602001828054801561145257602002820191906000526020600020905b81548152602001906001019080831161143e575b5050505050925081805480602002602001604051908101604052809291908181526020016000905b82821015611526578382906000526020600020018054611499906145d3565b80601f01602080910402602001604051908101604052809291908181526020018280546114c5906145d3565b80156115125780601f106114e757610100808354040283529160200191611512565b820191906000526020600020905b8154815290600101906020018083116114f557829003601f168201915b50505050508152602001906001019061147a565b50505050915080805480602002602001604051908101604052809291908181526020016000905b828210156115f957838290600052602060002001805461156c906145d3565b80601f0160208091040260200160405190810160405280929190818152602001828054611598906145d3565b80156115e55780601f106115ba576101008083540402835291602001916115e5565b820191906000526020600020905b8154815290600101906020018083116115c857829003601f168201915b50505050508152602001906001019061154d565b5050505090509450945094509450509193509193565b604080518082018252600981527f4e6f756e732044414f000000000000000000000000000000000000000000000060209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527fe1dd93b3612547b4bb7c3d429f3df8508d84f5a4f63b5e2e44340b94698e6b3b81840152466060820152306080808301919091528351808303909101815260a0820184528051908301207f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f60c083015260e0820189905260ff881661010080840191909152845180840390910181526101208301909452835193909201929092207f19010000000000000000000000000000000000000000000000000000000000006101408401526101428301829052610162830181905290916000906101820160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa1580156117b7573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166118405760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63617374566f746542795369673a20696e76616c696460448201527f207369676e617475726500000000000000000000000000000000000000000000606482015260840161089c565b806001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48a8a611878858e8e613266565b6040805193845260ff90921660208401526bffffffffffffffffffffffff169082015260806060820181905260009082015260a00160405180910390a2505050505050505050565b60008160085410156119395760405162461bcd60e51b8152602060048201526024808201527f4e6f756e7344414f3a3a73746174653a20696e76616c69642070726f706f736160448201527f6c20696400000000000000000000000000000000000000000000000000000000606482015260840161089c565b6000828152600b60205260409020600e810154610100900460ff16156119625750600892915050565b600e81015460ff16156119785750600292915050565b8060090154431161198c5750600092915050565b80600a015443116119a05750600192915050565b80600c015481600b01541115806119be5750806003015481600b0154105b156119cc5750600392915050565b60048101546119de5750600492915050565b600e81015462010000900460ff16156119fa5750600792915050565b600960009054906101000a90046001600160a01b03166001600160a01b031663c1a287e26040518163ffffffff1660e01b815260040160206040518083038186803b158015611a4857600080fd5b505afa158015611a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a809190613e3e565b8160040154611a8f9190614515565b4210611a9e5750600692915050565b50600592915050565b50919050565b6007611ab8826118c0565b6008811115611ac957611ac9614657565b1415611b3d5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a63616e63656c3a2063616e6e6f742063616e63656c2060448201527f65786563757465642070726f706f73616c000000000000000000000000000000606482015260840161089c565b6000818152600b6020526040902060018101546001600160a01b0316331480611c3257506002810154600a546001808401546001600160a01b039283169263782d6fe192911690611b8e904361458c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b158015611bea57600080fd5b505afa158015611bfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c22919061400b565b6bffffffffffffffffffffffff16105b611ca45760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63616e63656c3a2070726f706f7365722061626f766560448201527f207468726573686f6c6400000000000000000000000000000000000000000000606482015260840161089c565b600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560005b6005820154811015611ded576009546005830180546001600160a01b039092169163591fcdfe919084908110611d0c57611d0c61466d565b6000918252602090912001546006850180546001600160a01b039092169185908110611d3a57611d3a61466d565b9060005260206000200154856007018581548110611d5a57611d5a61466d565b90600052602060002001866008018681548110611d7957611d7961466d565b9060005260206000200187600401546040518663ffffffff1660e01b8152600401611da895949392919061423a565b600060405180830381600087803b158015611dc257600080fd5b505af1158015611dd6573d6000803e3d6000fd5b505050508080611de590614608565b915050611cd4565b506040518281527f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90602001610966565b337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48383611e4d848383613266565b6040805193845260ff90921660208401526bffffffffffffffffffffffff169082015260806060820181905260009082015260a00160405180910390a25050565b6000546001600160a01b03163314611f0e5760405162461bcd60e51b815260206004820152602860248201527f4e6f756e7344414f3a3a5f73657451756f72756d566f7465734250533a20616460448201527f6d696e206f6e6c79000000000000000000000000000000000000000000000000606482015260840161089c565b60c88110158015611f2157506107d08111155b611f935760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c640000000000606482015260840161089c565b600780549082905560408051828152602081018490527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b9101610966565b337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48585612000848383613266565b8686604051612013959493929190614443565b60405180910390a250505050565b6003546001600160a01b031633146120a15760405162461bcd60e51b815260206004820152602160248201527f4e6f756e7344414f3a3a5f7365745665746f65723a207665746f6572206f6e6c60448201527f7900000000000000000000000000000000000000000000000000000000000000606482015260840161089c565b600354604080516001600160a01b03928316815291831660208301527fc5644f3588a066b15dcf6b636b74aadca57cfaccf608d9de7d8786364b7a8d02910160405180910390a1600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000546001600160a01b031633146121a25760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c644260448201527f50533a2061646d696e206f6e6c79000000000000000000000000000000000000606482015260840161089c565b600181101580156121b557506103e88111155b6122275760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c640000000000606482015260840161089c565b600680549082905560408051828152602081018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a589101610966565b6000610e38600654600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfb57600080fd5b6000546001600160a01b0316331461233b5760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f73657450656e64696e6741646d696e3a2061646d6960448201527f6e206f6e6c790000000000000000000000000000000000000000000000000000606482015260840161089c565b600180546001600160a01b038381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610966565b6003546001600160a01b0316331461242d5760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f6275726e5665746f506f7765723a207665746f657260448201527f206f6e6c79000000000000000000000000000000000000000000000000000000606482015260840161089c565b6124376000612021565b565b600061246d6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bb57600080fd5b505afa1580156124cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f39190613e3e565b80825260065461250291613246565b60208201819052600a546001600160a01b031663782d6fe13361252660014361458c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b15801561258257600080fd5b505afa158015612596573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ba919061400b565b6bffffffffffffffffffffffff161161263b5760405162461bcd60e51b815260206004820152603a60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73657220766f746560448201527f732062656c6f772070726f706f73616c207468726573686f6c64000000000000606482015260840161089c565b8551875114801561264d575084518751145b801561265a575083518751145b6126cc5760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73616c2066756e6360448201527f74696f6e20696e666f726d6174696f6e206172697479206d69736d6174636800606482015260840161089c565b86516127405760405162461bcd60e51b815260206004820152602760248201527f4e6f756e7344414f3a3a70726f706f73653a206d7573742070726f766964652060448201527f616374696f6e7300000000000000000000000000000000000000000000000000606482015260840161089c565b600a875111156127b85760405162461bcd60e51b815260206004820152602360248201527f4e6f756e7344414f3a3a70726f706f73653a20746f6f206d616e79206163746960448201527f6f6e730000000000000000000000000000000000000000000000000000000000606482015260840161089c565b336000908152600c60205260409081902054908201819052156129445760006127e482604001516118c0565b905060018160088111156127fa576127fa614657565b14156128945760405162461bcd60e51b815260206004820152605360248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527f616479206163746976652070726f706f73616c00000000000000000000000000608482015260a40161089c565b60008160088111156128a8576128a8614657565b14156129425760405162461bcd60e51b815260206004820152605460248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527f6164792070656e64696e672070726f706f73616c000000000000000000000000608482015260a40161089c565b505b6004546129519043614515565b6060820181905260055461296491614515565b60808201526008805490600061297983614608565b90915550506008546000818152600b602090815260409091209182556001820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055820151600282015560075482516129d89190613246565b60038201556000600482015587516129f990600583019060208b01906137d5565b508651612a0f90600683019060208a0190613852565b508551612a25906007830190602089019061388d565b508451612a3b90600883019060208801906138e6565b506060820151600982019081556080830151600a83019081556000600b8401819055600c808501829055600d8501829055600e850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000169055845460018601546001600160a01b031683526020919091526040918290208190559254915490517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e093612af893909233928e928e928e928e9291908e90614307565b60405180910390a17f6af0134faa0f9290c1d686d55012aca80302d31d5c856e4bc7954f7613dc7f878160000154338a8a8a8a876009015488600a015489600201548a600301548e604051612b579b9a9998979695949392919061439d565b60405180910390a154979650505050505050565b6004612b76826118c0565b6008811115612b8757612b87614657565b14612bfa5760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a71756575653a2070726f706f73616c2063616e206f6e60448201527f6c79206265207175657565642069662069742069732073756363656564656400606482015260840161089c565b6000818152600b6020908152604080832060095482517f6a42b8f800000000000000000000000000000000000000000000000000000000815292519194936001600160a01b0390911692636a42b8f89260048083019392829003018186803b158015612c6557600080fd5b505afa158015612c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c9d9190613e3e565b612ca79042614515565b905060005b6005830154811015612e7157612e5f836005018281548110612cd057612cd061466d565b6000918252602090912001546006850180546001600160a01b039092169184908110612cfe57612cfe61466d565b9060005260206000200154856007018481548110612d1e57612d1e61466d565b906000526020600020018054612d33906145d3565b80601f0160208091040260200160405190810160405280929190818152602001828054612d5f906145d3565b8015612dac5780601f10612d8157610100808354040283529160200191612dac565b820191906000526020600020905b815481529060010190602001808311612d8f57829003601f168201915b5050505050866008018581548110612dc657612dc661466d565b906000526020600020018054612ddb906145d3565b80601f0160208091040260200160405190810160405280929190818152602001828054612e07906145d3565b8015612e545780601f10612e2957610100808354040283529160200191612e54565b820191906000526020600020905b815481529060010190602001808311612e3757829003601f168201915b5050505050866135df565b80612e6981614608565b915050612cac565b506004820181905560408051848152602081018390527f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892910160405180910390a1505050565b6001546001600160a01b031633148015612ed057503315155b612f425760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a5f61636365707441646d696e3a2070656e64696e672060448201527f61646d696e206f6e6c7900000000000000000000000000000000000000000000606482015260840161089c565b60008054600180546001600160a01b038082167fffffffffffffffffffffffff000000000000000000000000000000000000000080861682179096559490911690915560408051919092168082526020820184905292917ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc910160405180910390a1600154604080516001600160a01b03808516825290921660208301527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610966565b6005613013826118c0565b600881111561302457613024614657565b14613099576040805162461bcd60e51b81526020600482015260248101919091527f4e6f756e7344414f3a3a657865637574653a2070726f706f73616c2063616e2060448201527f6f6e6c7920626520657865637574656420696620697420697320717565756564606482015260840161089c565b6000818152600b60205260408120600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff1662010000179055905b6005820154811015613215576009546005830180546001600160a01b0390921691630825f38f9190849081106131105761311061466d565b6000918252602090912001546006850180546001600160a01b03909216918590811061313e5761313e61466d565b906000526020600020015485600701858154811061315e5761315e61466d565b9060005260206000200186600801868154811061317d5761317d61466d565b9060005260206000200187600401546040518663ffffffff1660e01b81526004016131ac95949392919061423a565b600060405180830381600087803b1580156131c657600080fd5b505af11580156131da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132029190810190613e57565b508061320d81614608565b9150506130d8565b506040518281527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90602001610966565b6000612710613255848461454f565b61325f919061452d565b9392505050565b60006001613273846118c0565b600881111561328457613284614657565b146132f75760405162461bcd60e51b815260206004820152602c60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746960448201527f6e6720697320636c6f7365640000000000000000000000000000000000000000606482015260840161089c565b60028260ff1611156133715760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20696e766160448201527f6c696420766f7465207479706500000000000000000000000000000000000000606482015260840161089c565b6000838152600b602090815260408083206001600160a01b0388168452600f8101909252909120805460ff16156134105760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746560448201527f7220616c726561647920766f7465640000000000000000000000000000000000606482015260840161089c565b600a5460045460098401546000926001600160a01b03169163782d6fe1918a916134399161458c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b15801561349557600080fd5b505afa1580156134a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134cd919061400b565b905060ff85166134ff57806bffffffffffffffffffffffff1683600c01546134f59190614515565b600c840155613563565b8460ff166001141561353357806bffffffffffffffffffffffff1683600b01546135299190614515565b600b840155613563565b8460ff166002141561356357806bffffffffffffffffffffffff1683600d015461355d9190614515565b600d8401555b81546bffffffffffffffffffffffff821662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff60ff8816610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009093169290921760011791909116179091559150509392505050565b6009546040516001600160a01b039091169063f2b065379061360d90889088908890889088906020016141ed565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161364191815260200190565b60206040518083038186803b15801561365957600080fd5b505afa15801561366d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136919190613e1c565b1561372a5760405162461bcd60e51b815260206004820152605060248201527f4e6f756e7344414f3a3a71756575654f72526576657274496e7465726e616c3a60448201527f206964656e746963616c2070726f706f73616c20616374696f6e20616c72656160648201527f6479207175657565642061742065746100000000000000000000000000000000608482015260a40161089c565b6009546040517f3a66f9010000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690633a66f9019061377b90889088908890889088906004016141ed565b602060405180830381600087803b15801561379557600080fd5b505af11580156137a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cd9190613e3e565b505050505050565b828054828255906000526020600020908101928215613842579160200282015b8281111561384257825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039091161782556020909201916001909101906137f5565b5061384e92915061393f565b5090565b828054828255906000526020600020908101928215613842579160200282015b82811115613842578251825591602001919060010190613872565b8280548282559060005260206000209081019282156138da579160200282015b828111156138da57825180516138ca918491602090910190613954565b50916020019190600101906138ad565b5061384e9291506139c7565b828054828255906000526020600020908101928215613933579160200282015b828111156139335782518051613923918491602090910190613954565b5091602001919060010190613906565b5061384e9291506139e4565b5b8082111561384e5760008155600101613940565b828054613960906145d3565b90600052602060002090601f0160209004810192826139825760008555613842565b82601f1061399b57805160ff1916838001178555613842565b828001600101855582156138425791820182811115613842578251825591602001919060010190613872565b8082111561384e5760006139db8282613a01565b506001016139c7565b8082111561384e5760006139f88282613a01565b506001016139e4565b508054613a0d906145d3565b6000825580601f10613a1d575050565b601f016020900490600052602060002090810190613a3b919061393f565b50565b6000613a51613a4c846144ed565b614498565b9050828152838383011115613a6557600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114613a9357600080fd5b919050565b600082601f830112613aa957600080fd5b81356020613ab9613a4c836144c9565b80838252828201915082860187848660051b8901011115613ad957600080fd5b60005b85811015613aff57613aed82613a7c565b84529284019290840190600101613adc565b5090979650505050505050565b600082601f830112613b1d57600080fd5b81356020613b2d613a4c836144c9565b80838252828201915082860187848660051b8901011115613b4d57600080fd5b60005b85811015613aff57813567ffffffffffffffff811115613b6f57600080fd5b8801603f81018a13613b8057600080fd5b613b918a8783013560408401613a3e565b8552509284019290840190600101613b50565b600082601f830112613bb557600080fd5b81356020613bc5613a4c836144c9565b80838252828201915082860187848660051b8901011115613be557600080fd5b6000805b86811015613c2857823567ffffffffffffffff811115613c07578283fd5b613c158b88838d0101613c96565b8652509385019391850191600101613be9565b509198975050505050505050565b600082601f830112613c4757600080fd5b81356020613c57613a4c836144c9565b80838252828201915082860187848660051b8901011115613c7757600080fd5b60005b85811015613aff57813584529284019290840190600101613c7a565b600082601f830112613ca757600080fd5b61325f83833560208501613a3e565b803560ff81168114613a9357600080fd5b600060208284031215613cd957600080fd5b61325f82613a7c565b600080600080600080600060e0888a031215613cfd57600080fd5b613d0688613a7c565b9650613d1460208901613a7c565b9550613d2260408901613a7c565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080600080600060a08688031215613d6257600080fd5b853567ffffffffffffffff80821115613d7a57600080fd5b613d8689838a01613a98565b96506020880135915080821115613d9c57600080fd5b613da889838a01613c36565b95506040880135915080821115613dbe57600080fd5b613dca89838a01613ba4565b94506060880135915080821115613de057600080fd5b613dec89838a01613b0c565b93506080880135915080821115613e0257600080fd5b50613e0f88828901613c96565b9150509295509295909350565b600060208284031215613e2e57600080fd5b8151801515811461325f57600080fd5b600060208284031215613e5057600080fd5b5051919050565b600060208284031215613e6957600080fd5b815167ffffffffffffffff811115613e8057600080fd5b8201601f81018413613e9157600080fd5b8051613e9f613a4c826144ed565b818152856020838501011115613eb457600080fd5b613ec58260208301602086016145a3565b95945050505050565b600060208284031215613ee057600080fd5b5035919050565b60008060408385031215613efa57600080fd5b82359150613f0a60208401613a7c565b90509250929050565b60008060408385031215613f2657600080fd5b82359150613f0a60208401613cb6565b60008060008060608587031215613f4c57600080fd5b84359350613f5c60208601613cb6565b9250604085013567ffffffffffffffff80821115613f7957600080fd5b818701915087601f830112613f8d57600080fd5b813581811115613f9c57600080fd5b886020828501011115613fae57600080fd5b95989497505060200194505050565b600080600080600060a08688031215613fd557600080fd5b85359450613fe560208701613cb6565b9350613ff360408701613cb6565b94979396509394606081013594506080013592915050565b60006020828403121561401d57600080fd5b81516bffffffffffffffffffffffff8116811461325f57600080fd5b600081518084526020808501945080840160005b838110156140725781516001600160a01b03168752958201959082019060010161404d565b509495945050505050565b600081518084526020808501808196508360051b8101915082860160005b858110156140c55782840389526140b3848351614102565b9885019893509084019060010161409b565b5091979650505050505050565b600081518084526020808501945080840160005b83811015614072578151875295820195908201906001016140e6565b6000815180845261411a8160208601602086016145a3565b601f01601f19169290920160200192915050565b8054600090600181811c908083168061414857607f831692505b602080841082141561416a57634e487b7160e01b600052602260045260246000fd5b83885281801561418157600181146141b3576141e1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616828a01526040890196506141e1565b876000528160002060005b868110156141d95781548b82018501529085019083016141be565b8a0183019750505b50505050505092915050565b6001600160a01b038616815284602082015260a06040820152600061421560a0830186614102565b82810360608401526142278186614102565b9150508260808301529695505050505050565b6001600160a01b038616815284602082015260a06040820152600061426260a083018661412e565b8281036060840152614227818661412e565b6080815260006142876080830187614039565b828103602084015261429981876140d2565b905082810360408401526142ad818661407d565b905082810360608401526142c1818561407d565b979650505050505050565b60208101600983106142ee57634e487b7160e01b600052602160045260246000fd5b91905290565b60208152600061325f6020830184614102565b60006101208b83526001600160a01b038b1660208401528060408401526143308184018b614039565b90508281036060840152614344818a6140d2565b90508281036080840152614358818961407d565b905082810360a084015261436c818861407d565b90508560c08401528460e084015282810361010084015261438d8185614102565b9c9b505050505050505050505050565b60006101608d83526001600160a01b038d1660208401528060408401526143c68184018d614039565b905082810360608401526143da818c6140d2565b905082810360808401526143ee818b61407d565b905082810360a0840152614402818a61407d565b90508760c08401528660e084015285610100840152846101208401528281036101408401526144318185614102565b9e9d5050505050505050505050505050565b85815260ff851660208201526bffffffffffffffffffffffff8416604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b604051601f8201601f1916810167ffffffffffffffff811182821017156144c1576144c1614683565b604052919050565b600067ffffffffffffffff8211156144e3576144e3614683565b5060051b60200190565b600067ffffffffffffffff82111561450757614507614683565b50601f01601f191660200190565b6000821982111561452857614528614641565b500190565b60008261454a57634e487b7160e01b600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561458757614587614641565b500290565b60008282101561459e5761459e614641565b500390565b60005b838110156145be5781810151838201526020016145a6565b838111156145cd576000848401525b50505050565b600181811c908216806145e757607f821691505b60208210811415611aa757634e487b7160e01b600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561463a5761463a614641565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea26469706673582212208dc1504ea4aef7242fe984c45260900e92d954e158ac4bec468f03db7a63bfab64736f6c63430008060033