{"file_path":"contracts/governed-owner/SimpleGovernance.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: GPL-3.0-only\n\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n// mainly used for governed-owner to do infrequent sgn/cbridge owner operations,\n// relatively prefer easy-to-use over gas-efficiency\ncontract SimpleGovernance {\n    uint256 public constant THRESHOLD_DECIMAL = 100;\n    uint256 public constant MIN_ACTIVE_PERIOD = 3600; // one hour\n    uint256 public constant MAX_ACTIVE_PERIOD = 2419200; // four weeks\n\n    using SafeERC20 for IERC20;\n\n    enum ParamName {\n        ActivePeriod,\n        QuorumThreshold, // default threshold for votes to pass\n        FastPassThreshold // lower threshold for less critical operations\n    }\n\n    enum ProposalType {\n        ExternalDefault,\n        ExternalFastPass,\n        InternalParamChange,\n        InternalVoterUpdate,\n        InternalProxyUpdate,\n        InternalTransferToken\n    }\n\n    mapping(ParamName => uint256) public params;\n\n    struct Proposal {\n        bytes32 dataHash; // hash(proposalType, targetAddress, calldata)\n        uint256 deadline;\n        mapping(address => bool) votes;\n    }\n\n    mapping(uint256 => Proposal) public proposals;\n    uint256 public nextProposalId;\n\n    address[] public voters;\n    mapping(address => uint256) public voterPowers; // voter addr -> voting power\n\n    // NOTE: proxies must be audited open-source non-upgradable contracts with following requirements:\n    // 1. Truthfully pass along tx sender who called the proxy function as the governance proposer.\n    // 2. Do not allow arbitrary fastpass proposal with calldata constructed by the proxy callers.\n    // See ./proxies/CommonOwnerProxy.sol for example.\n    mapping(address => bool) public proposerProxies;\n\n    event Initiated(\n        address[] voters,\n        uint256[] powers,\n        address[] proxies,\n        uint256 activePeriod,\n        uint256 quorumThreshold,\n        uint256 fastPassThreshold\n    );\n\n    event ProposalCreated(\n        uint256 proposalId,\n        ProposalType proposalType,\n        address target,\n        bytes data,\n        uint256 deadline,\n        address proposer\n    );\n    event ProposalVoted(uint256 proposalId, address voter, bool vote);\n    event ProposalExecuted(uint256 proposalId);\n\n    event ParamChangeProposalCreated(uint256 proposalId, ParamName name, uint256 value);\n    event VoterUpdateProposalCreated(uint256 proposalId, address[] voters, uint256[] powers);\n    event ProxyUpdateProposalCreated(uint256 proposalId, address[] addrs, bool[] ops);\n    event TransferTokenProposalCreated(uint256 proposalId, address receiver, address token, uint256 amount);\n\n    constructor(\n        address[] memory _voters,\n        uint256[] memory _powers,\n        address[] memory _proxies,\n        uint256 _activePeriod,\n        uint256 _quorumThreshold,\n        uint256 _fastPassThreshold\n    ) {\n        require(_voters.length > 0 && _voters.length == _powers.length, \"invalid init voters\");\n        require(_activePeriod <= MAX_ACTIVE_PERIOD && _activePeriod >= MIN_ACTIVE_PERIOD, \"invalid active period\");\n        require(\n            _quorumThreshold < THRESHOLD_DECIMAL && _fastPassThreshold <= _quorumThreshold,\n            \"invalid init thresholds\"\n        );\n        for (uint256 i = 0; i < _voters.length; i++) {\n            _setVoter(_voters[i], _powers[i]);\n        }\n        for (uint256 i = 0; i < _proxies.length; i++) {\n            proposerProxies[_proxies[i]] = true;\n        }\n        params[ParamName.ActivePeriod] = _activePeriod;\n        params[ParamName.QuorumThreshold] = _quorumThreshold;\n        params[ParamName.FastPassThreshold] = _fastPassThreshold;\n        emit Initiated(_voters, _powers, _proxies, _activePeriod, _quorumThreshold, _fastPassThreshold);\n    }\n\n    /*********************************\n     * External and Public Functions *\n     *********************************/\n\n    function createProposal(address _target, bytes memory _data) external returns (uint256) {\n        return _createProposal(msg.sender, _target, _data, ProposalType.ExternalDefault);\n    }\n\n    // create proposal through proxy\n    function createProposal(\n        address _proposer,\n        address _target,\n        bytes memory _data,\n        ProposalType _type\n    ) external returns (uint256) {\n        require(proposerProxies[msg.sender], \"sender is not a valid proxy\");\n        require(_type == ProposalType.ExternalDefault || _type == ProposalType.ExternalFastPass, \"invalid type\");\n        return _createProposal(_proposer, _target, _data, _type);\n    }\n\n    function createParamChangeProposal(ParamName _name, uint256 _value) external returns (uint256) {\n        bytes memory data = abi.encode(_name, _value);\n        uint256 proposalId = _createProposal(msg.sender, address(0), data, ProposalType.InternalParamChange);\n        emit ParamChangeProposalCreated(proposalId, _name, _value);\n        return proposalId;\n    }\n\n    function createVoterUpdateProposal(address[] calldata _voters, uint256[] calldata _powers)\n        external\n        returns (uint256)\n    {\n        require(_voters.length == _powers.length, \"voters and powers length not match\");\n        bytes memory data = abi.encode(_voters, _powers);\n        uint256 proposalId = _createProposal(msg.sender, address(0), data, ProposalType.InternalVoterUpdate);\n        emit VoterUpdateProposalCreated(proposalId, _voters, _powers);\n        return proposalId;\n    }\n\n    function createProxyUpdateProposal(address[] calldata _addrs, bool[] calldata _ops) external returns (uint256) {\n        require(_addrs.length == _ops.length, \"_addrs and _ops length not match\");\n        bytes memory data = abi.encode(_addrs, _ops);\n        uint256 proposalId = _createProposal(msg.sender, address(0), data, ProposalType.InternalProxyUpdate);\n        emit ProxyUpdateProposalCreated(proposalId, _addrs, _ops);\n        return proposalId;\n    }\n\n    function createTransferTokenProposal(\n        address _receiver,\n        address _token,\n        uint256 _amount\n    ) external returns (uint256) {\n        bytes memory data = abi.encode(_receiver, _token, _amount);\n        uint256 proposalId = _createProposal(msg.sender, address(0), data, ProposalType.InternalTransferToken);\n        emit TransferTokenProposalCreated(proposalId, _receiver, _token, _amount);\n        return proposalId;\n    }\n\n    function voteProposal(uint256 _proposalId, bool _vote) external {\n        require(voterPowers[msg.sender] > 0, \"invalid voter\");\n        Proposal storage p = proposals[_proposalId];\n        require(block.timestamp < p.deadline, \"deadline passed\");\n        p.votes[msg.sender] = _vote;\n        emit ProposalVoted(_proposalId, msg.sender, _vote);\n    }\n\n    function executeProposal(\n        uint256 _proposalId,\n        ProposalType _type,\n        address _target,\n        bytes calldata _data\n    ) external {\n        require(voterPowers[msg.sender] > 0, \"only voter can execute a proposal\");\n        Proposal storage p = proposals[_proposalId];\n        require(block.timestamp < p.deadline, \"deadline passed\");\n        require(keccak256(abi.encodePacked(_type, _target, _data)) == p.dataHash, \"data hash not match\");\n        p.deadline = 0;\n\n        p.votes[msg.sender] = true;\n        (, , bool pass) = countVotes(_proposalId, _type);\n        require(pass, \"not enough votes\");\n\n        if (_type == ProposalType.ExternalDefault || _type == ProposalType.ExternalFastPass) {\n            (bool success, bytes memory res) = _target.call(_data);\n            require(success, _getRevertMsg(res));\n        } else if (_type == ProposalType.InternalParamChange) {\n            (ParamName name, uint256 value) = abi.decode((_data), (ParamName, uint256));\n            params[name] = value;\n            if (name == ParamName.ActivePeriod) {\n                require(value <= MAX_ACTIVE_PERIOD && value >= MIN_ACTIVE_PERIOD, \"invalid active period\");\n            } else if (name == ParamName.QuorumThreshold || name == ParamName.FastPassThreshold) {\n                require(\n                    params[ParamName.QuorumThreshold] >= params[ParamName.FastPassThreshold] &&\n                        value < THRESHOLD_DECIMAL &&\n                        value > 0,\n                    \"invalid threshold\"\n                );\n            }\n        } else if (_type == ProposalType.InternalVoterUpdate) {\n            (address[] memory addrs, uint256[] memory powers) = abi.decode((_data), (address[], uint256[]));\n            for (uint256 i = 0; i < addrs.length; i++) {\n                if (powers[i] > 0) {\n                    _setVoter(addrs[i], powers[i]);\n                } else {\n                    _removeVoter(addrs[i]);\n                }\n            }\n        } else if (_type == ProposalType.InternalProxyUpdate) {\n            (address[] memory addrs, bool[] memory ops) = abi.decode((_data), (address[], bool[]));\n            for (uint256 i = 0; i < addrs.length; i++) {\n                if (ops[i]) {\n                    proposerProxies[addrs[i]] = true;\n                } else {\n                    delete proposerProxies[addrs[i]];\n                }\n            }\n        } else if (_type == ProposalType.InternalTransferToken) {\n            (address receiver, address token, uint256 amount) = abi.decode((_data), (address, address, uint256));\n            _transfer(receiver, token, amount);\n        }\n        emit ProposalExecuted(_proposalId);\n    }\n\n    receive() external payable {}\n\n    /**************************\n     *  Public View Functions *\n     **************************/\n\n    function getVoters() public view returns (address[] memory, uint256[] memory) {\n        address[] memory addrs = new address[](voters.length);\n        uint256[] memory powers = new uint256[](voters.length);\n        for (uint32 i = 0; i < voters.length; i++) {\n            addrs[i] = voters[i];\n            powers[i] = voterPowers[voters[i]];\n        }\n        return (addrs, powers);\n    }\n\n    function getVote(uint256 _proposalId, address _voter) public view returns (bool) {\n        return proposals[_proposalId].votes[_voter];\n    }\n\n    function countVotes(uint256 _proposalId, ProposalType _type)\n        public\n        view\n        returns (\n            uint256,\n            uint256,\n            bool\n        )\n    {\n        uint256 yesVotes;\n        uint256 totalPower;\n        for (uint32 i = 0; i < voters.length; i++) {\n            if (getVote(_proposalId, voters[i])) {\n                yesVotes += voterPowers[voters[i]];\n            }\n            totalPower += voterPowers[voters[i]];\n        }\n        uint256 threshold;\n        if (_type == ProposalType.ExternalFastPass) {\n            threshold = params[ParamName.FastPassThreshold];\n        } else {\n            threshold = params[ParamName.QuorumThreshold];\n        }\n        bool pass = (yesVotes >= (totalPower * threshold) / THRESHOLD_DECIMAL);\n        return (totalPower, yesVotes, pass);\n    }\n\n    /**********************************\n     * Internal and Private Functions *\n     **********************************/\n\n    // create a proposal and vote yes\n    function _createProposal(\n        address _proposer,\n        address _target,\n        bytes memory _data,\n        ProposalType _type\n    ) private returns (uint256) {\n        require(voterPowers[_proposer] > 0, \"only voter can create a proposal\");\n        uint256 proposalId = nextProposalId;\n        nextProposalId += 1;\n        Proposal storage p = proposals[proposalId];\n        p.dataHash = keccak256(abi.encodePacked(_type, _target, _data));\n        p.deadline = block.timestamp + params[ParamName.ActivePeriod];\n        p.votes[_proposer] = true;\n        emit ProposalCreated(proposalId, _type, _target, _data, p.deadline, _proposer);\n        return proposalId;\n    }\n\n    function _setVoter(address _voter, uint256 _power) private {\n        require(_power > 0, \"zero power\");\n        if (voterPowers[_voter] == 0) {\n            // add new voter\n            voters.push(_voter);\n        }\n        voterPowers[_voter] = _power;\n    }\n\n    function _removeVoter(address _voter) private {\n        require(voterPowers[_voter] > 0, \"not a voter\");\n        uint256 lastIndex = voters.length - 1;\n        for (uint256 i = 0; i < voters.length; i++) {\n            if (voters[i] == _voter) {\n                if (i < lastIndex) {\n                    voters[i] = voters[lastIndex];\n                }\n                voters.pop();\n                voterPowers[_voter] = 0;\n                return;\n            }\n        }\n        revert(\"voter not found\"); // this should never happen\n    }\n\n    function _transfer(\n        address _receiver,\n        address _token,\n        uint256 _amount\n    ) private {\n        if (_token == address(0)) {\n            (bool sent, ) = _receiver.call{value: _amount, gas: 50000}(\"\");\n            require(sent, \"failed to send native token\");\n        } else {\n            IERC20(_token).safeTransfer(_receiver, _amount);\n        }\n    }\n\n    // https://ethereum.stackexchange.com/a/83577\n    // https://github.com/Uniswap/v3-periphery/blob/v1.0.0/contracts/base/Multicall.sol\n    function _getRevertMsg(bytes memory _returnData) private pure returns (string memory) {\n        // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n        if (_returnData.length < 68) return \"Transaction reverted silently\";\n        assembly {\n            // Slice the sighash.\n            _returnData := add(_returnData, 0x04)\n        }\n        return abi.decode(_returnData, (string)); // All that remains is the revert string\n    }\n}\n","deployed_bytecode":"0x6080604052600436106101635760003560e01c8063a24066fa116100c0578063df30b8ef11610074578063eaac391511610059578063eaac391514610434578063eb505dd514610454578063fd4802741461048157600080fd5b8063df30b8ef146103ff578063e6c942bd1461041f57600080fd5b8063bcfb9b61116100a5578063bcfb9b6114610384578063cdd72253146103a4578063da58c7d9146103c757600080fd5b8063a24066fa14610324578063bc3f931f1461033a57600080fd5b80633c10498c1161011757806352a84447116100fc57806352a84447146102ae57806356fd3def146102c55780638b06fdcf146102e757600080fd5b80633c10498c1461026e5780633ccbf0811461028e57600080fd5b8063197ba2b011610148578063197ba2b0146101fd5780631adc646d1461022b5780632ab09d141461025857600080fd5b8063013cf08b1461016f5780631937c784146101bd57600080fd5b3661016a57005b600080fd5b34801561017b57600080fd5b506101a361018a366004611c08565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152015b60405180910390f35b3480156101c957600080fd5b506101ed6101d8366004611c39565b60056020526000908152604090205460ff1681565b60405190151581526020016101b4565b34801561020957600080fd5b5061021d610218366004611d1b565b6104a1565b6040519081526020016101b4565b34801561023757600080fd5b5061021d610246366004611c39565b60046020526000908152604090205481565b34801561026457600080fd5b5061021d60025481565b34801561027a57600080fd5b5061021d610289366004611d6b565b6104b7565b34801561029a57600080fd5b5061021d6102a9366004611df8565b610559565b3480156102ba57600080fd5b5061021d6224ea0081565b3480156102d157600080fd5b506102e56102e0366004611e78565b610634565b005b3480156102f357600080fd5b50610307610302366004611f15565b610ce1565b6040805193845260208401929092521515908201526060016101b4565b34801561033057600080fd5b5061021d610e1081565b34801561034657600080fd5b506101ed610355366004611f41565b60008281526001602090815260408083206001600160a01b038516845260020190915290205460ff1692915050565b34801561039057600080fd5b506102e561039f366004611f7f565b610ea7565b3480156103b057600080fd5b506103b9610fc1565b6040516101b4929190611fa4565b3480156103d357600080fd5b506103e76103e2366004611c08565b611160565b6040516001600160a01b0390911681526020016101b4565b34801561040b57600080fd5b5061021d61041a366004611df8565b61118a565b34801561042b57600080fd5b5061021d606481565b34801561044057600080fd5b5061021d61044f366004612037565b611259565b34801561046057600080fd5b5061021d61046f366004612061565b60006020819052908152604090205481565b34801561048d57600080fd5b5061021d61049c36600461207c565b6112d5565b60006104b033848460006113c6565b9392505050565b604080516001600160a01b0385811660208301528416818301526060808201849052825180830390910181526080909101909152600090816104fc33828460056113c6565b604080518281526001600160a01b0389811660208301528816818301526060810187905290519192507f24acc0bfc20f5066ae099e5b19b383477c0b39b73753040457defd1086e7ce3c919081900360800190a195945050505050565b60008382146105af5760405162461bcd60e51b815260206004820181905260248201527f5f616464727320616e64205f6f7073206c656e677468206e6f74206d6174636860448201526064015b60405180910390fd5b6000858585856040516020016105c8949392919061216f565b604051602081830303815290604052905060006105e93360008460046113c6565b90507f17a666a7f3280baa6bed91a68c95dcd406666c510fb0bd72d39477ec4edc9cec8188888888604051610622959493929190612196565b60405180910390a19695505050505050565b3360009081526004602052604090205461069a5760405162461bcd60e51b815260206004820152602160248201527f6f6e6c7920766f7465722063616e206578656375746520612070726f706f73616044820152601b60fa1b60648201526084016105a6565b60008581526001602081905260409091209081015442106106ef5760405162461bcd60e51b815260206004820152600f60248201526e191958591b1a5b99481c185cdcd959608a1b60448201526064016105a6565b80546040516107089087908790879087906020016121fc565b604051602081830303815290604052805190602001201461076b5760405162461bcd60e51b815260206004820152601360248201527f646174612068617368206e6f74206d617463680000000000000000000000000060448201526064016105a6565b600060018083018290553382526002830160205260408220805460ff191690911790556107988787610ce1565b92505050806107e95760405162461bcd60e51b815260206004820152601060248201527f6e6f7420656e6f75676820766f7465730000000000000000000000000000000060448201526064016105a6565b60008660058111156107fd576107fd6121cf565b148061081a57506001866005811115610818576108186121cf565b145b156108b357600080866001600160a01b0316868660405161083c929190612236565b6000604051808303816000865af19150503d8060008114610879576040519150601f19603f3d011682016040523d82523d6000602084013e61087e565b606091505b50915091508161088d82611530565b906108ab5760405162461bcd60e51b81526004016105a6919061229e565b505050610ca5565b60028660058111156108c7576108c76121cf565b1415610a8e576000806108dc85870187612037565b91509150806000808460028111156108f6576108f66121cf565b6002811115610907576109076121cf565b8152602081019190915260400160009081209190915582600281111561092f5761092f6121cf565b141561099b576224ea00811115801561094a5750610e108110155b6109965760405162461bcd60e51b815260206004820152601560248201527f696e76616c69642061637469766520706572696f64000000000000000000000060448201526064016105a6565b610a87565b60018260028111156109af576109af6121cf565b14806109cc575060028260028111156109ca576109ca6121cf565b145b15610a8757600060208190527fabbb5caa7dda850e60932de0934eb1f9d0f59695050f761dc64e443e5030a5695460019091527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d5410801590610a2f5750606481105b8015610a3b5750600081115b610a875760405162461bcd60e51b815260206004820152601160248201527f696e76616c6964207468726573686f6c6400000000000000000000000000000060448201526064016105a6565b5050610ca5565b6003866005811115610aa257610aa26121cf565b1415610b5e57600080610ab785870187612344565b9150915060005b82518110156108ab576000828281518110610adb57610adb6123ff565b60200260200101511115610b2a57610b25838281518110610afe57610afe6123ff565b6020026020010151838381518110610b1857610b186123ff565b6020026020010151611595565b610b4c565b610b4c838281518110610b3f57610b3f6123ff565b6020026020010151611677565b80610b568161242b565b915050610abe565b6004866005811115610b7257610b726121cf565b1415610c6657600080610b8785870187612446565b9150915060005b82518110156108ab57818181518110610ba957610ba96123ff565b602002602001015115610c1257600160056000858481518110610bce57610bce6123ff565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550610c54565b60056000848381518110610c2857610c286123ff565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191690555b80610c5e8161242b565b915050610b8e565b6005866005811115610c7a57610c7a6121cf565b1415610ca55760008080610c9086880188611d6b565b925092509250610ca1838383611866565b5050505b6040518781527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f9060200160405180910390a150505050505050565b600080808080805b60035463ffffffff82161015610e0057610d4c8860038363ffffffff1681548110610d1657610d166123ff565b60009182526020808320909101549282526001815260408083206001600160a01b03909416835260029093019052205460ff1690565b15610da0576004600060038363ffffffff1681548110610d6e57610d6e6123ff565b60009182526020808320909101546001600160a01b03168352820192909252604001902054610d9d90846124fb565b92505b6004600060038363ffffffff1681548110610dbd57610dbd6123ff565b60009182526020808320909101546001600160a01b03168352820192909252604001902054610dec90836124fb565b915080610df881612513565b915050610ce9565b5060006001876005811115610e1757610e176121cf565b1415610e4f5750600260009081526020527fabbb5caa7dda850e60932de0934eb1f9d0f59695050f761dc64e443e5030a56954610e7d565b50600160009081526020527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d545b60006064610e8b8385612537565b610e959190612556565b92999398505050861015945092505050565b33600090815260046020526040902054610f035760405162461bcd60e51b815260206004820152600d60248201527f696e76616c696420766f7465720000000000000000000000000000000000000060448201526064016105a6565b6000828152600160208190526040909120908101544210610f585760405162461bcd60e51b815260206004820152600f60248201526e191958591b1a5b99481c185cdcd959608a1b60448201526064016105a6565b336000818152600283016020908152604091829020805460ff1916861515908117909155825187815291820193909352908101919091527f0def80f9a3b4c7a4251442658ccf516bf33ea4acaf31638fc6da8ebdb0f64c729060600160405180910390a1505050565b606080600060038054905067ffffffffffffffff811115610fe457610fe4611c56565b60405190808252806020026020018201604052801561100d578160200160208202803683370190505b5060035490915060009067ffffffffffffffff81111561102f5761102f611c56565b604051908082528060200260200182016040528015611058578160200160208202803683370190505b50905060005b60035463ffffffff821610156111565760038163ffffffff1681548110611087576110876123ff565b9060005260206000200160009054906101000a90046001600160a01b0316838263ffffffff16815181106110bd576110bd6123ff565b60200260200101906001600160a01b031690816001600160a01b0316815250506004600060038363ffffffff16815481106110fa576110fa6123ff565b60009182526020808320909101546001600160a01b031683528201929092526040019020548251839063ffffffff8416908110611139576111396123ff565b60209081029190910101528061114e81612513565b91505061105e565b5090939092509050565b6003818154811061117057600080fd5b6000918252602090912001546001600160a01b0316905081565b60008382146111e65760405162461bcd60e51b815260206004820152602260248201527f766f7465727320616e6420706f77657273206c656e677468206e6f74206d61746044820152610c6d60f31b60648201526084016105a6565b6000858585856040516020016111ff94939291906125c7565b604051602081830303815290604052905060006112203360008460036113c6565b90507fcdd3bbb4db706a8c147c0a0b06f84b9c6240e234dce693114df5802f80ff96da81888888886040516106229594939291906125ee565b600080838360405160200161126f92919061262f565b604051602081830303815290604052905060006112903360008460026113c6565b90507f03ca21bbd8905a0941439454af0577ee1f4cf8bd9c3d45ef0872a293fc63d9c98186866040516112c59392919061264a565b60405180910390a1949350505050565b3360009081526005602052604081205460ff166113345760405162461bcd60e51b815260206004820152601b60248201527f73656e646572206973206e6f7420612076616c69642070726f7879000000000060448201526064016105a6565b6000826005811115611348576113486121cf565b148061136557506001826005811115611363576113636121cf565b145b6113b15760405162461bcd60e51b815260206004820152600c60248201527f696e76616c69642074797065000000000000000000000000000000000000000060448201526064016105a6565b6113bd858585856113c6565b95945050505050565b6001600160a01b03841660009081526004602052604081205461142b5760405162461bcd60e51b815260206004820181905260248201527f6f6e6c7920766f7465722063616e2063726561746520612070726f706f73616c60448201526064016105a6565b6002805490600190600061143f83856124fb565b90915550506000818152600160209081526040918290209151611468918691899189910161266c565b60408051601f1981840301815291905280516020918201208255600080805290527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5546114b590426124fb565b60018083019182556001600160a01b038916600090815260028401602052604090819020805460ff1916909217909155905490517fddb3e2b975a8b576dab0af8108180d63dc83bd9bb0b5bede5f305bf9fe2cfbed9161151e91859188918b918b918e906126b2565b60405180910390a15095945050505050565b606060448251101561157557505060408051808201909152601d81527f5472616e73616374696f6e2072657665727465642073696c656e746c79000000602082015290565b6004820191508180602001905181019061158f919061270c565b92915050565b600081116115e55760405162461bcd60e51b815260206004820152600a60248201527f7a65726f20706f7765720000000000000000000000000000000000000000000060448201526064016105a6565b6001600160a01b03821660009081526004602052604090205461165b57600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790555b6001600160a01b03909116600090815260046020526040902055565b6001600160a01b0381166000908152600460205260409020546116dc5760405162461bcd60e51b815260206004820152600b60248201527f6e6f74206120766f74657200000000000000000000000000000000000000000060448201526064016105a6565b6003546000906116ee9060019061277a565b905060005b60035481101561181d57826001600160a01b03166003828154811061171a5761171a6123ff565b6000918252602090912001546001600160a01b0316141561180b57818110156117ab5760038281548110611750576117506123ff565b600091825260209091200154600380546001600160a01b03909216918390811061177c5761177c6123ff565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b60038054806117bc576117bc612791565b600082815260208082208301600019908101805473ffffffffffffffffffffffffffffffffffffffff191690559092019092556001600160a01b03949094168152600490935250506040812055565b806118158161242b565b9150506116f3565b5060405162461bcd60e51b815260206004820152600f60248201527f766f746572206e6f7420666f756e64000000000000000000000000000000000060448201526064016105a6565b6001600160a01b038216611922576000836001600160a01b03168261c35090604051600060405180830381858888f193505050503d80600081146118c6576040519150601f19603f3d011682016040523d82523d6000602084013e6118cb565b606091505b505090508061191c5760405162461bcd60e51b815260206004820152601b60248201527f6661696c656420746f2073656e64206e617469766520746f6b656e000000000060448201526064016105a6565b50505050565b6119366001600160a01b038316848361193b565b505050565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490840152611936928692916000916119e0918516908490611a70565b80519091501561193657808060200190518101906119fe91906127a7565b6119365760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016105a6565b6060611a7f8484600085611a87565b949350505050565b606082471015611aff5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016105a6565b6001600160a01b0385163b611b565760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105a6565b600080866001600160a01b03168587604051611b7291906127c4565b60006040518083038185875af1925050503d8060008114611baf576040519150601f19603f3d011682016040523d82523d6000602084013e611bb4565b606091505b5091509150611bc4828286611bcf565b979650505050505050565b60608315611bde5750816104b0565b825115611bee5782518084602001fd5b8160405162461bcd60e51b81526004016105a6919061229e565b600060208284031215611c1a57600080fd5b5035919050565b6001600160a01b0381168114611c3657600080fd5b50565b600060208284031215611c4b57600080fd5b81356104b081611c21565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611c9557611c95611c56565b604052919050565b600067ffffffffffffffff821115611cb757611cb7611c56565b50601f01601f191660200190565b600082601f830112611cd657600080fd5b8135611ce9611ce482611c9d565b611c6c565b818152846020838601011115611cfe57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215611d2e57600080fd5b8235611d3981611c21565b9150602083013567ffffffffffffffff811115611d5557600080fd5b611d6185828601611cc5565b9150509250929050565b600080600060608486031215611d8057600080fd5b8335611d8b81611c21565b92506020840135611d9b81611c21565b929592945050506040919091013590565b60008083601f840112611dbe57600080fd5b50813567ffffffffffffffff811115611dd657600080fd5b6020830191508360208260051b8501011115611df157600080fd5b9250929050565b60008060008060408587031215611e0e57600080fd5b843567ffffffffffffffff80821115611e2657600080fd5b611e3288838901611dac565b90965094506020870135915080821115611e4b57600080fd5b50611e5887828801611dac565b95989497509550505050565b803560068110611e7357600080fd5b919050565b600080600080600060808688031215611e9057600080fd5b85359450611ea060208701611e64565b93506040860135611eb081611c21565b9250606086013567ffffffffffffffff80821115611ecd57600080fd5b818801915088601f830112611ee157600080fd5b813581811115611ef057600080fd5b896020828501011115611f0257600080fd5b9699959850939650602001949392505050565b60008060408385031215611f2857600080fd5b82359150611f3860208401611e64565b90509250929050565b60008060408385031215611f5457600080fd5b823591506020830135611f6681611c21565b809150509250929050565b8015158114611c3657600080fd5b60008060408385031215611f9257600080fd5b823591506020830135611f6681611f71565b604080825283519082018190526000906020906060840190828701845b82811015611fe65781516001600160a01b031684529284019290840190600101611fc1565b5050508381038285015284518082528583019183019060005b8181101561201b57835183529284019291840191600101611fff565b5090979650505050505050565b803560038110611e7357600080fd5b6000806040838503121561204a57600080fd5b61205383612028565b946020939093013593505050565b60006020828403121561207357600080fd5b6104b082612028565b6000806000806080858703121561209257600080fd5b843561209d81611c21565b935060208501356120ad81611c21565b9250604085013567ffffffffffffffff8111156120c957600080fd5b6120d587828801611cc5565b9250506120e460608601611e64565b905092959194509250565b8183526000602080850194508260005b8581101561212d57813561211281611c21565b6001600160a01b0316875295820195908201906001016120ff565b509495945050505050565b8183526000602080850194508260005b8581101561212d57813561215b81611f71565b151587529582019590820190600101612148565b6040815260006121836040830186886120ef565b8281036020840152611bc4818587612138565b8581526060602082015260006121b06060830186886120ef565b82810360408401526121c3818587612138565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b600681106121f5576121f56121cf565b60f81b9052565b61220681866121e5565b6bffffffffffffffffffffffff198460601b16600182015281836015830137600091016015019081529392505050565b8183823760009101908152919050565b60005b83811015612261578181015183820152602001612249565b8381111561191c5750506000910152565b6000815180845261228a816020860160208601612246565b601f01601f19169290920160200192915050565b6020815260006104b06020830184612272565b600067ffffffffffffffff8211156122cb576122cb611c56565b5060051b60200190565b600082601f8301126122e657600080fd5b813560206122f6611ce4836122b1565b82815260059290921b8401810191818101908684111561231557600080fd5b8286015b8481101561233957803561232c81611c21565b8352918301918301612319565b509695505050505050565b6000806040838503121561235757600080fd5b823567ffffffffffffffff8082111561236f57600080fd5b61237b868387016122d5565b935060209150818501358181111561239257600080fd5b85019050601f810186136123a557600080fd5b80356123b3611ce4826122b1565b81815260059190911b820183019083810190888311156123d257600080fd5b928401925b828410156123f0578335825292840192908401906123d7565b80955050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561243f5761243f612415565b5060010190565b6000806040838503121561245957600080fd5b823567ffffffffffffffff8082111561247157600080fd5b61247d868387016122d5565b935060209150818501358181111561249457600080fd5b85019050601f810186136124a757600080fd5b80356124b5611ce4826122b1565b81815260059190911b820183019083810190888311156124d457600080fd5b928401925b828410156123f05783356124ec81611f71565b825292840192908401906124d9565b6000821982111561250e5761250e612415565b500190565b600063ffffffff8083168181141561252d5761252d612415565b6001019392505050565b600081600019048311821515161561255157612551612415565b500290565b60008261257357634e487b7160e01b600052601260045260246000fd5b500490565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156125aa57600080fd5b8260051b8083602087013760009401602001938452509192915050565b6040815260006125db6040830186886120ef565b8281036020840152611bc4818587612578565b8581526060602082015260006126086060830186886120ef565b82810360408401526121c3818587612578565b6003811061262b5761262b6121cf565b9052565b6040810161263d828561261b565b8260208301529392505050565b8381526060810161265e602083018561261b565b826040830152949350505050565b61267681856121e5565b6bffffffffffffffffffffffff198360601b166001820152600082516126a3816015850160208701612246565b91909101601501949350505050565b8681526000600687106126c7576126c76121cf565b8660208301526001600160a01b03808716604084015260c060608401526126f160c0840187612272565b60808401959095529290921660a09091015250949350505050565b60006020828403121561271e57600080fd5b815167ffffffffffffffff81111561273557600080fd5b8201601f8101841361274657600080fd5b8051612754611ce482611c9d565b81815285602083850101111561276957600080fd5b6113bd826020830160208601612246565b60008282101561278c5761278c612415565b500390565b634e487b7160e01b600052603160045260246000fd5b6000602082840312156127b957600080fd5b81516104b081611f71565b600082516127d6818460208701612246565b919091019291505056fea26469706673582212209af049ebcc6ca985cdde1b6bcc08f000c22a124c28477c53a0dfdd1568ea3b5464736f6c63430008090033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"libraries":{},"metadata":{"useLiteralContent":true},"optimizer":{"enabled":true,"runs":800},"outputSelection":{"*":{"*":["evm.bytecode","evm.deployedBytecode","devdoc","userdoc","metadata","abi"]}}},"optimization_runs":800,"sourcify_repo_url":null,"decoded_constructor_args":[[["0x1b9dFC56e38b0F92448659C114e2347Bd803911c","0x34dFa1226F8b3E36FE597B34eEa809a2B5c0bBf9","0xDfE4F07D1F36B8d559b25082460a4f6A72531de2","0x9F6B03Cb6d8AB8239cF1045Ab28B9Df43dfCC823","0x2FB8783C14A71C08bFC1dE8Fc3D715Dd93039BF2"],{"internalType":"address[]","name":"_voters","type":"address[]"}],[["10000","10000","10000","10000","10000"],{"internalType":"uint256[]","name":"_powers","type":"uint256[]"}],[["0xF03928DDc5e5Fa43c7f0cc94aB5adB76D25C79a6"],{"internalType":"address[]","name":"_proxies","type":"address[]"}],["86400",{"internalType":"uint256","name":"_activePeriod","type":"uint256"}],["60",{"internalType":"uint256","name":"_quorumThreshold","type":"uint256"}],["40",{"internalType":"uint256","name":"_fastPassThreshold","type":"uint256"}]],"compiler_version":"v0.8.9+commit.e5eed63a","is_verified_via_verifier_alliance":false,"verified_at":"2024-02-25T12:54:31.470339Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60806040523480156200001157600080fd5b5060405162002ef638038062002ef68339810160408190526200003491620004be565b6000865111801562000047575084518651145b620000995760405162461bcd60e51b815260206004820152601360248201527f696e76616c696420696e697420766f746572730000000000000000000000000060448201526064015b60405180910390fd5b6224ea008311158015620000af5750610e108310155b620000fd5760405162461bcd60e51b815260206004820152601560248201527f696e76616c69642061637469766520706572696f640000000000000000000000604482015260640162000090565b6064821080156200010e5750818111155b6200015c5760405162461bcd60e51b815260206004820152601760248201527f696e76616c696420696e6974207468726573686f6c6473000000000000000000604482015260640162000090565b60005b8651811015620001c857620001b3878281518110620001825762000182620005c5565b60200260200101518783815181106200019f576200019f620005c5565b60200260200101516200030060201b60201c565b80620001bf81620005db565b9150506200015f565b5060005b84518110156200023857600160056000878481518110620001f157620001f1620005c5565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806200022f81620005db565b915050620001cc565b50600060208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb58490557fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d839055600290527fabbb5caa7dda850e60932de0934eb1f9d0f59695050f761dc64e443e5030a5698190556040517f158672b778fadeb5bab2d0c5af83fa0f0e4d847119d334543d7df06d393d8fe590620002ec908890889088908890889088906200064b565b60405180910390a1505050505050620006d0565b600081116200033f5760405162461bcd60e51b815260206004820152600a6024820152693d32b937903837bbb2b960b11b604482015260640162000090565b6001600160a01b038216600090815260046020526040902054620003a957600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b03909116600090815260046020526040902055565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620004065762000406620003c5565b604052919050565b60006001600160401b038211156200042a576200042a620003c5565b5060051b60200190565b600082601f8301126200044657600080fd5b815160206200045f62000459836200040e565b620003db565b82815260059290921b840181019181810190868411156200047f57600080fd5b8286015b84811015620004b35780516001600160a01b0381168114620004a55760008081fd5b835291830191830162000483565b509695505050505050565b60008060008060008060c08789031215620004d857600080fd5b86516001600160401b0380821115620004f057600080fd5b620004fe8a838b0162000434565b97506020915081890151818111156200051657600080fd5b8901601f81018b136200052857600080fd5b80516200053962000459826200040e565b81815260059190911b8201840190848101908d8311156200055957600080fd5b928501925b8284101562000579578351825292850192908501906200055e565b60408d0151909a509450505050808211156200059457600080fd5b50620005a389828a0162000434565b945050606087015192506080870151915060a087015190509295509295509295565b634e487b7160e01b600052603260045260246000fd5b6000600019821415620005fe57634e487b7160e01b600052601160045260246000fd5b5060010190565b600081518084526020808501945080840160005b83811015620006405781516001600160a01b03168752958201959082019060010162000619565b509495945050505050565b60c0815260006200066060c083018962000605565b82810360208481019190915288518083528982019282019060005b8181101562000699578451835293830193918301916001016200067b565b50508481036040860152620006af818a62000605565b606086019890985250505050608081019290925260a0909101529392505050565b61281680620006e06000396000f3fe6080604052600436106101635760003560e01c8063a24066fa116100c0578063df30b8ef11610074578063eaac391511610059578063eaac391514610434578063eb505dd514610454578063fd4802741461048157600080fd5b8063df30b8ef146103ff578063e6c942bd1461041f57600080fd5b8063bcfb9b61116100a5578063bcfb9b6114610384578063cdd72253146103a4578063da58c7d9146103c757600080fd5b8063a24066fa14610324578063bc3f931f1461033a57600080fd5b80633c10498c1161011757806352a84447116100fc57806352a84447146102ae57806356fd3def146102c55780638b06fdcf146102e757600080fd5b80633c10498c1461026e5780633ccbf0811461028e57600080fd5b8063197ba2b011610148578063197ba2b0146101fd5780631adc646d1461022b5780632ab09d141461025857600080fd5b8063013cf08b1461016f5780631937c784146101bd57600080fd5b3661016a57005b600080fd5b34801561017b57600080fd5b506101a361018a366004611c08565b6001602081905260009182526040909120805491015482565b604080519283526020830191909152015b60405180910390f35b3480156101c957600080fd5b506101ed6101d8366004611c39565b60056020526000908152604090205460ff1681565b60405190151581526020016101b4565b34801561020957600080fd5b5061021d610218366004611d1b565b6104a1565b6040519081526020016101b4565b34801561023757600080fd5b5061021d610246366004611c39565b60046020526000908152604090205481565b34801561026457600080fd5b5061021d60025481565b34801561027a57600080fd5b5061021d610289366004611d6b565b6104b7565b34801561029a57600080fd5b5061021d6102a9366004611df8565b610559565b3480156102ba57600080fd5b5061021d6224ea0081565b3480156102d157600080fd5b506102e56102e0366004611e78565b610634565b005b3480156102f357600080fd5b50610307610302366004611f15565b610ce1565b6040805193845260208401929092521515908201526060016101b4565b34801561033057600080fd5b5061021d610e1081565b34801561034657600080fd5b506101ed610355366004611f41565b60008281526001602090815260408083206001600160a01b038516845260020190915290205460ff1692915050565b34801561039057600080fd5b506102e561039f366004611f7f565b610ea7565b3480156103b057600080fd5b506103b9610fc1565b6040516101b4929190611fa4565b3480156103d357600080fd5b506103e76103e2366004611c08565b611160565b6040516001600160a01b0390911681526020016101b4565b34801561040b57600080fd5b5061021d61041a366004611df8565b61118a565b34801561042b57600080fd5b5061021d606481565b34801561044057600080fd5b5061021d61044f366004612037565b611259565b34801561046057600080fd5b5061021d61046f366004612061565b60006020819052908152604090205481565b34801561048d57600080fd5b5061021d61049c36600461207c565b6112d5565b60006104b033848460006113c6565b9392505050565b604080516001600160a01b0385811660208301528416818301526060808201849052825180830390910181526080909101909152600090816104fc33828460056113c6565b604080518281526001600160a01b0389811660208301528816818301526060810187905290519192507f24acc0bfc20f5066ae099e5b19b383477c0b39b73753040457defd1086e7ce3c919081900360800190a195945050505050565b60008382146105af5760405162461bcd60e51b815260206004820181905260248201527f5f616464727320616e64205f6f7073206c656e677468206e6f74206d6174636860448201526064015b60405180910390fd5b6000858585856040516020016105c8949392919061216f565b604051602081830303815290604052905060006105e93360008460046113c6565b90507f17a666a7f3280baa6bed91a68c95dcd406666c510fb0bd72d39477ec4edc9cec8188888888604051610622959493929190612196565b60405180910390a19695505050505050565b3360009081526004602052604090205461069a5760405162461bcd60e51b815260206004820152602160248201527f6f6e6c7920766f7465722063616e206578656375746520612070726f706f73616044820152601b60fa1b60648201526084016105a6565b60008581526001602081905260409091209081015442106106ef5760405162461bcd60e51b815260206004820152600f60248201526e191958591b1a5b99481c185cdcd959608a1b60448201526064016105a6565b80546040516107089087908790879087906020016121fc565b604051602081830303815290604052805190602001201461076b5760405162461bcd60e51b815260206004820152601360248201527f646174612068617368206e6f74206d617463680000000000000000000000000060448201526064016105a6565b600060018083018290553382526002830160205260408220805460ff191690911790556107988787610ce1565b92505050806107e95760405162461bcd60e51b815260206004820152601060248201527f6e6f7420656e6f75676820766f7465730000000000000000000000000000000060448201526064016105a6565b60008660058111156107fd576107fd6121cf565b148061081a57506001866005811115610818576108186121cf565b145b156108b357600080866001600160a01b0316868660405161083c929190612236565b6000604051808303816000865af19150503d8060008114610879576040519150601f19603f3d011682016040523d82523d6000602084013e61087e565b606091505b50915091508161088d82611530565b906108ab5760405162461bcd60e51b81526004016105a6919061229e565b505050610ca5565b60028660058111156108c7576108c76121cf565b1415610a8e576000806108dc85870187612037565b91509150806000808460028111156108f6576108f66121cf565b6002811115610907576109076121cf565b8152602081019190915260400160009081209190915582600281111561092f5761092f6121cf565b141561099b576224ea00811115801561094a5750610e108110155b6109965760405162461bcd60e51b815260206004820152601560248201527f696e76616c69642061637469766520706572696f64000000000000000000000060448201526064016105a6565b610a87565b60018260028111156109af576109af6121cf565b14806109cc575060028260028111156109ca576109ca6121cf565b145b15610a8757600060208190527fabbb5caa7dda850e60932de0934eb1f9d0f59695050f761dc64e443e5030a5695460019091527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d5410801590610a2f5750606481105b8015610a3b5750600081115b610a875760405162461bcd60e51b815260206004820152601160248201527f696e76616c6964207468726573686f6c6400000000000000000000000000000060448201526064016105a6565b5050610ca5565b6003866005811115610aa257610aa26121cf565b1415610b5e57600080610ab785870187612344565b9150915060005b82518110156108ab576000828281518110610adb57610adb6123ff565b60200260200101511115610b2a57610b25838281518110610afe57610afe6123ff565b6020026020010151838381518110610b1857610b186123ff565b6020026020010151611595565b610b4c565b610b4c838281518110610b3f57610b3f6123ff565b6020026020010151611677565b80610b568161242b565b915050610abe565b6004866005811115610b7257610b726121cf565b1415610c6657600080610b8785870187612446565b9150915060005b82518110156108ab57818181518110610ba957610ba96123ff565b602002602001015115610c1257600160056000858481518110610bce57610bce6123ff565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550610c54565b60056000848381518110610c2857610c286123ff565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191690555b80610c5e8161242b565b915050610b8e565b6005866005811115610c7a57610c7a6121cf565b1415610ca55760008080610c9086880188611d6b565b925092509250610ca1838383611866565b5050505b6040518781527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f9060200160405180910390a150505050505050565b600080808080805b60035463ffffffff82161015610e0057610d4c8860038363ffffffff1681548110610d1657610d166123ff565b60009182526020808320909101549282526001815260408083206001600160a01b03909416835260029093019052205460ff1690565b15610da0576004600060038363ffffffff1681548110610d6e57610d6e6123ff565b60009182526020808320909101546001600160a01b03168352820192909252604001902054610d9d90846124fb565b92505b6004600060038363ffffffff1681548110610dbd57610dbd6123ff565b60009182526020808320909101546001600160a01b03168352820192909252604001902054610dec90836124fb565b915080610df881612513565b915050610ce9565b5060006001876005811115610e1757610e176121cf565b1415610e4f5750600260009081526020527fabbb5caa7dda850e60932de0934eb1f9d0f59695050f761dc64e443e5030a56954610e7d565b50600160009081526020527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d545b60006064610e8b8385612537565b610e959190612556565b92999398505050861015945092505050565b33600090815260046020526040902054610f035760405162461bcd60e51b815260206004820152600d60248201527f696e76616c696420766f7465720000000000000000000000000000000000000060448201526064016105a6565b6000828152600160208190526040909120908101544210610f585760405162461bcd60e51b815260206004820152600f60248201526e191958591b1a5b99481c185cdcd959608a1b60448201526064016105a6565b336000818152600283016020908152604091829020805460ff1916861515908117909155825187815291820193909352908101919091527f0def80f9a3b4c7a4251442658ccf516bf33ea4acaf31638fc6da8ebdb0f64c729060600160405180910390a1505050565b606080600060038054905067ffffffffffffffff811115610fe457610fe4611c56565b60405190808252806020026020018201604052801561100d578160200160208202803683370190505b5060035490915060009067ffffffffffffffff81111561102f5761102f611c56565b604051908082528060200260200182016040528015611058578160200160208202803683370190505b50905060005b60035463ffffffff821610156111565760038163ffffffff1681548110611087576110876123ff565b9060005260206000200160009054906101000a90046001600160a01b0316838263ffffffff16815181106110bd576110bd6123ff565b60200260200101906001600160a01b031690816001600160a01b0316815250506004600060038363ffffffff16815481106110fa576110fa6123ff565b60009182526020808320909101546001600160a01b031683528201929092526040019020548251839063ffffffff8416908110611139576111396123ff565b60209081029190910101528061114e81612513565b91505061105e565b5090939092509050565b6003818154811061117057600080fd5b6000918252602090912001546001600160a01b0316905081565b60008382146111e65760405162461bcd60e51b815260206004820152602260248201527f766f7465727320616e6420706f77657273206c656e677468206e6f74206d61746044820152610c6d60f31b60648201526084016105a6565b6000858585856040516020016111ff94939291906125c7565b604051602081830303815290604052905060006112203360008460036113c6565b90507fcdd3bbb4db706a8c147c0a0b06f84b9c6240e234dce693114df5802f80ff96da81888888886040516106229594939291906125ee565b600080838360405160200161126f92919061262f565b604051602081830303815290604052905060006112903360008460026113c6565b90507f03ca21bbd8905a0941439454af0577ee1f4cf8bd9c3d45ef0872a293fc63d9c98186866040516112c59392919061264a565b60405180910390a1949350505050565b3360009081526005602052604081205460ff166113345760405162461bcd60e51b815260206004820152601b60248201527f73656e646572206973206e6f7420612076616c69642070726f7879000000000060448201526064016105a6565b6000826005811115611348576113486121cf565b148061136557506001826005811115611363576113636121cf565b145b6113b15760405162461bcd60e51b815260206004820152600c60248201527f696e76616c69642074797065000000000000000000000000000000000000000060448201526064016105a6565b6113bd858585856113c6565b95945050505050565b6001600160a01b03841660009081526004602052604081205461142b5760405162461bcd60e51b815260206004820181905260248201527f6f6e6c7920766f7465722063616e2063726561746520612070726f706f73616c60448201526064016105a6565b6002805490600190600061143f83856124fb565b90915550506000818152600160209081526040918290209151611468918691899189910161266c565b60408051601f1981840301815291905280516020918201208255600080805290527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5546114b590426124fb565b60018083019182556001600160a01b038916600090815260028401602052604090819020805460ff1916909217909155905490517fddb3e2b975a8b576dab0af8108180d63dc83bd9bb0b5bede5f305bf9fe2cfbed9161151e91859188918b918b918e906126b2565b60405180910390a15095945050505050565b606060448251101561157557505060408051808201909152601d81527f5472616e73616374696f6e2072657665727465642073696c656e746c79000000602082015290565b6004820191508180602001905181019061158f919061270c565b92915050565b600081116115e55760405162461bcd60e51b815260206004820152600a60248201527f7a65726f20706f7765720000000000000000000000000000000000000000000060448201526064016105a6565b6001600160a01b03821660009081526004602052604090205461165b57600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790555b6001600160a01b03909116600090815260046020526040902055565b6001600160a01b0381166000908152600460205260409020546116dc5760405162461bcd60e51b815260206004820152600b60248201527f6e6f74206120766f74657200000000000000000000000000000000000000000060448201526064016105a6565b6003546000906116ee9060019061277a565b905060005b60035481101561181d57826001600160a01b03166003828154811061171a5761171a6123ff565b6000918252602090912001546001600160a01b0316141561180b57818110156117ab5760038281548110611750576117506123ff565b600091825260209091200154600380546001600160a01b03909216918390811061177c5761177c6123ff565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b60038054806117bc576117bc612791565b600082815260208082208301600019908101805473ffffffffffffffffffffffffffffffffffffffff191690559092019092556001600160a01b03949094168152600490935250506040812055565b806118158161242b565b9150506116f3565b5060405162461bcd60e51b815260206004820152600f60248201527f766f746572206e6f7420666f756e64000000000000000000000000000000000060448201526064016105a6565b6001600160a01b038216611922576000836001600160a01b03168261c35090604051600060405180830381858888f193505050503d80600081146118c6576040519150601f19603f3d011682016040523d82523d6000602084013e6118cb565b606091505b505090508061191c5760405162461bcd60e51b815260206004820152601b60248201527f6661696c656420746f2073656e64206e617469766520746f6b656e000000000060448201526064016105a6565b50505050565b6119366001600160a01b038316848361193b565b505050565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490840152611936928692916000916119e0918516908490611a70565b80519091501561193657808060200190518101906119fe91906127a7565b6119365760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016105a6565b6060611a7f8484600085611a87565b949350505050565b606082471015611aff5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016105a6565b6001600160a01b0385163b611b565760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105a6565b600080866001600160a01b03168587604051611b7291906127c4565b60006040518083038185875af1925050503d8060008114611baf576040519150601f19603f3d011682016040523d82523d6000602084013e611bb4565b606091505b5091509150611bc4828286611bcf565b979650505050505050565b60608315611bde5750816104b0565b825115611bee5782518084602001fd5b8160405162461bcd60e51b81526004016105a6919061229e565b600060208284031215611c1a57600080fd5b5035919050565b6001600160a01b0381168114611c3657600080fd5b50565b600060208284031215611c4b57600080fd5b81356104b081611c21565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611c9557611c95611c56565b604052919050565b600067ffffffffffffffff821115611cb757611cb7611c56565b50601f01601f191660200190565b600082601f830112611cd657600080fd5b8135611ce9611ce482611c9d565b611c6c565b818152846020838601011115611cfe57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215611d2e57600080fd5b8235611d3981611c21565b9150602083013567ffffffffffffffff811115611d5557600080fd5b611d6185828601611cc5565b9150509250929050565b600080600060608486031215611d8057600080fd5b8335611d8b81611c21565b92506020840135611d9b81611c21565b929592945050506040919091013590565b60008083601f840112611dbe57600080fd5b50813567ffffffffffffffff811115611dd657600080fd5b6020830191508360208260051b8501011115611df157600080fd5b9250929050565b60008060008060408587031215611e0e57600080fd5b843567ffffffffffffffff80821115611e2657600080fd5b611e3288838901611dac565b90965094506020870135915080821115611e4b57600080fd5b50611e5887828801611dac565b95989497509550505050565b803560068110611e7357600080fd5b919050565b600080600080600060808688031215611e9057600080fd5b85359450611ea060208701611e64565b93506040860135611eb081611c21565b9250606086013567ffffffffffffffff80821115611ecd57600080fd5b818801915088601f830112611ee157600080fd5b813581811115611ef057600080fd5b896020828501011115611f0257600080fd5b9699959850939650602001949392505050565b60008060408385031215611f2857600080fd5b82359150611f3860208401611e64565b90509250929050565b60008060408385031215611f5457600080fd5b823591506020830135611f6681611c21565b809150509250929050565b8015158114611c3657600080fd5b60008060408385031215611f9257600080fd5b823591506020830135611f6681611f71565b604080825283519082018190526000906020906060840190828701845b82811015611fe65781516001600160a01b031684529284019290840190600101611fc1565b5050508381038285015284518082528583019183019060005b8181101561201b57835183529284019291840191600101611fff565b5090979650505050505050565b803560038110611e7357600080fd5b6000806040838503121561204a57600080fd5b61205383612028565b946020939093013593505050565b60006020828403121561207357600080fd5b6104b082612028565b6000806000806080858703121561209257600080fd5b843561209d81611c21565b935060208501356120ad81611c21565b9250604085013567ffffffffffffffff8111156120c957600080fd5b6120d587828801611cc5565b9250506120e460608601611e64565b905092959194509250565b8183526000602080850194508260005b8581101561212d57813561211281611c21565b6001600160a01b0316875295820195908201906001016120ff565b509495945050505050565b8183526000602080850194508260005b8581101561212d57813561215b81611f71565b151587529582019590820190600101612148565b6040815260006121836040830186886120ef565b8281036020840152611bc4818587612138565b8581526060602082015260006121b06060830186886120ef565b82810360408401526121c3818587612138565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b600681106121f5576121f56121cf565b60f81b9052565b61220681866121e5565b6bffffffffffffffffffffffff198460601b16600182015281836015830137600091016015019081529392505050565b8183823760009101908152919050565b60005b83811015612261578181015183820152602001612249565b8381111561191c5750506000910152565b6000815180845261228a816020860160208601612246565b601f01601f19169290920160200192915050565b6020815260006104b06020830184612272565b600067ffffffffffffffff8211156122cb576122cb611c56565b5060051b60200190565b600082601f8301126122e657600080fd5b813560206122f6611ce4836122b1565b82815260059290921b8401810191818101908684111561231557600080fd5b8286015b8481101561233957803561232c81611c21565b8352918301918301612319565b509695505050505050565b6000806040838503121561235757600080fd5b823567ffffffffffffffff8082111561236f57600080fd5b61237b868387016122d5565b935060209150818501358181111561239257600080fd5b85019050601f810186136123a557600080fd5b80356123b3611ce4826122b1565b81815260059190911b820183019083810190888311156123d257600080fd5b928401925b828410156123f0578335825292840192908401906123d7565b80955050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561243f5761243f612415565b5060010190565b6000806040838503121561245957600080fd5b823567ffffffffffffffff8082111561247157600080fd5b61247d868387016122d5565b935060209150818501358181111561249457600080fd5b85019050601f810186136124a757600080fd5b80356124b5611ce4826122b1565b81815260059190911b820183019083810190888311156124d457600080fd5b928401925b828410156123f05783356124ec81611f71565b825292840192908401906124d9565b6000821982111561250e5761250e612415565b500190565b600063ffffffff8083168181141561252d5761252d612415565b6001019392505050565b600081600019048311821515161561255157612551612415565b500290565b60008261257357634e487b7160e01b600052601260045260246000fd5b500490565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156125aa57600080fd5b8260051b8083602087013760009401602001938452509192915050565b6040815260006125db6040830186886120ef565b8281036020840152611bc4818587612578565b8581526060602082015260006126086060830186886120ef565b82810360408401526121c3818587612578565b6003811061262b5761262b6121cf565b9052565b6040810161263d828561261b565b8260208301529392505050565b8381526060810161265e602083018561261b565b826040830152949350505050565b61267681856121e5565b6bffffffffffffffffffffffff198360601b166001820152600082516126a3816015850160208701612246565b91909101601501949350505050565b8681526000600687106126c7576126c76121cf565b8660208301526001600160a01b03808716604084015260c060608401526126f160c0840187612272565b60808401959095529290921660a09091015250949350505050565b60006020828403121561271e57600080fd5b815167ffffffffffffffff81111561273557600080fd5b8201601f8101841361274657600080fd5b8051612754611ce482611c9d565b81815285602083850101111561276957600080fd5b6113bd826020830160208601612246565b60008282101561278c5761278c612415565b500390565b634e487b7160e01b600052603160045260246000fd5b6000602082840312156127b957600080fd5b81516104b081611f71565b600082516127d6818460208701612246565b919091019291505056fea26469706673582212209af049ebcc6ca985cdde1b6bcc08f000c22a124c28477c53a0dfdd1568ea3b5464736f6c6343000809003300000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000050000000000000000000000001b9dfc56e38b0f92448659c114e2347bd803911c00000000000000000000000034dfa1226f8b3e36fe597b34eea809a2b5c0bbf9000000000000000000000000dfe4f07d1f36b8d559b25082460a4f6a72531de20000000000000000000000009f6b03cb6d8ab8239cf1045ab28b9df43dfcc8230000000000000000000000002fb8783c14a71c08bfc1de8fc3d715dd93039bf20000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f03928ddc5e5fa43c7f0cc94ab5adb76d25c79a6","name":"SimpleGovernance","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"default","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"@openzeppelin/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},{"file_path":"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/Address.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address[]","name":"_voters","type":"address[]"},{"internalType":"uint256[]","name":"_powers","type":"uint256[]"},{"internalType":"address[]","name":"_proxies","type":"address[]"},{"internalType":"uint256","name":"_activePeriod","type":"uint256"},{"internalType":"uint256","name":"_quorumThreshold","type":"uint256"},{"internalType":"uint256","name":"_fastPassThreshold","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"voters","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"powers","type":"uint256[]"},{"indexed":false,"internalType":"address[]","name":"proxies","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"activePeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quorumThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fastPassThreshold","type":"uint256"}],"name":"Initiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"enum SimpleGovernance.ParamName","name":"name","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"ParamChangeProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"enum SimpleGovernance.ProposalType","name":"proposalType","type":"uint8"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"deadline","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"bool","name":"vote","type":"bool"}],"name":"ProposalVoted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"addrs","type":"address[]"},{"indexed":false,"internalType":"bool[]","name":"ops","type":"bool[]"}],"name":"ProxyUpdateProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferTokenProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"voters","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"powers","type":"uint256[]"}],"name":"VoterUpdateProposalCreated","type":"event"},{"inputs":[],"name":"MAX_ACTIVE_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_ACTIVE_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"THRESHOLD_DECIMAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"enum SimpleGovernance.ProposalType","name":"_type","type":"uint8"}],"name":"countVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum SimpleGovernance.ParamName","name":"_name","type":"uint8"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"createParamChangeProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"createProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proposer","type":"address"},{"internalType":"address","name":"_target","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"enum SimpleGovernance.ProposalType","name":"_type","type":"uint8"}],"name":"createProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addrs","type":"address[]"},{"internalType":"bool[]","name":"_ops","type":"bool[]"}],"name":"createProxyUpdateProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"createTransferTokenProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_voters","type":"address[]"},{"internalType":"uint256[]","name":"_powers","type":"uint256[]"}],"name":"createVoterUpdateProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"enum SimpleGovernance.ProposalType","name":"_type","type":"uint8"},{"internalType":"address","name":"_target","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"executeProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"address","name":"_voter","type":"address"}],"name":"getVote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVoters","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextProposalId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum SimpleGovernance.ParamName","name":"","type":"uint8"}],"name":"params","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"proposerProxies","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalId","type":"uint256"},{"internalType":"bool","name":"_vote","type":"bool"}],"name":"voteProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"voterPowers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"voters","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":"00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000050000000000000000000000001b9dfc56e38b0f92448659c114e2347bd803911c00000000000000000000000034dfa1226f8b3e36fe597b34eea809a2b5c0bbf9000000000000000000000000dfe4f07d1f36b8d559b25082460a4f6a72531de20000000000000000000000009f6b03cb6d8ab8239cf1045ab28b9df43dfcc8230000000000000000000000002fb8783c14a71c08bfc1de8fc3d715dd93039bf20000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f03928ddc5e5fa43c7f0cc94ab5adb76d25c79a6"}