Address Details
contract

0xf0EE62005149B008bD3991EdfEA2cAd5EAE592aA

Contract Name
GovernedOwnerProxy
Creator
0x4e59b4–b4956c at 0x1c4eb5–08240e
Balance
( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
13813389
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
GovernedOwnerProxy




Optimization enabled
true
Compiler version
v0.8.9+commit.e5eed63a




Optimization runs
800
EVM Version
london




Verified at
2022-07-01T03:35:03.926053Z

contracts/governed-owner/GovernedOwnerProxy.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.9;

import "./proxies/CommonOwnerProxy.sol";
import "./proxies/BridgeOwnerProxy.sol";
import "./proxies/MessageOwnerProxy.sol";
import "./proxies/SgnOwnerProxy.sol";
import "./proxies/UpgradeableOwnerProxy.sol";

contract GovernedOwnerProxy is
    CommonOwnerProxy,
    BridgeOwnerProxy,
    MessageOwnerProxy,
    SgnOwnerProxy,
    UpgradeableOwnerProxy
{
    constructor(address _initializer) OwnerProxyBase(_initializer) {}
}
        

/_openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}
          

/_openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}
          

/_openzeppelin/contracts/utils/Address.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}
          

/contracts/governed-owner/SimpleGovernance.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

// mainly used for governed-owner to do infrequent sgn/cbridge owner operations,
// relatively prefer easy-to-use over gas-efficiency
contract SimpleGovernance {
    uint256 public constant THRESHOLD_DECIMAL = 100;
    uint256 public constant MIN_ACTIVE_PERIOD = 3600; // one hour
    uint256 public constant MAX_ACTIVE_PERIOD = 2419200; // four weeks

    using SafeERC20 for IERC20;

    enum ParamName {
        ActivePeriod,
        QuorumThreshold, // default threshold for votes to pass
        FastPassThreshold // lower threshold for less critical operations
    }

    enum ProposalType {
        ExternalDefault,
        ExternalFastPass,
        InternalParamChange,
        InternalVoterUpdate,
        InternalProxyUpdate,
        InternalTransferToken
    }

    mapping(ParamName => uint256) public params;

    struct Proposal {
        bytes32 dataHash; // hash(proposalType, targetAddress, calldata)
        uint256 deadline;
        mapping(address => bool) votes;
    }

    mapping(uint256 => Proposal) public proposals;
    uint256 public nextProposalId;

    address[] public voters;
    mapping(address => uint256) public voterPowers; // voter addr -> voting power

    // NOTE: proxies must be audited open-source non-upgradable contracts with following requirements:
    // 1. Truthfully pass along tx sender who called the proxy function as the governance proposer.
    // 2. Do not allow arbitrary fastpass proposal with calldata constructed by the proxy callers.
    // See ./proxies/CommonOwnerProxy.sol for example.
    mapping(address => bool) public proposerProxies;

    event Initiated(
        address[] voters,
        uint256[] powers,
        address[] proxies,
        uint256 activePeriod,
        uint256 quorumThreshold,
        uint256 fastPassThreshold
    );

    event ProposalCreated(
        uint256 proposalId,
        ProposalType proposalType,
        address target,
        bytes data,
        uint256 deadline,
        address proposer
    );
    event ProposalVoted(uint256 proposalId, address voter, bool vote);
    event ProposalExecuted(uint256 proposalId);

    event ParamChangeProposalCreated(uint256 proposalId, ParamName name, uint256 value);
    event VoterUpdateProposalCreated(uint256 proposalId, address[] voters, uint256[] powers);
    event ProxyUpdateProposalCreated(uint256 proposalId, address[] addrs, bool[] ops);
    event TransferTokenProposalCreated(uint256 proposalId, address receiver, address token, uint256 amount);

    constructor(
        address[] memory _voters,
        uint256[] memory _powers,
        address[] memory _proxies,
        uint256 _activePeriod,
        uint256 _quorumThreshold,
        uint256 _fastPassThreshold
    ) {
        require(_voters.length > 0 && _voters.length == _powers.length, "invalid init voters");
        require(_activePeriod <= MAX_ACTIVE_PERIOD && _activePeriod >= MIN_ACTIVE_PERIOD, "invalid active period");
        require(
            _quorumThreshold < THRESHOLD_DECIMAL && _fastPassThreshold <= _quorumThreshold,
            "invalid init thresholds"
        );
        for (uint256 i = 0; i < _voters.length; i++) {
            _setVoter(_voters[i], _powers[i]);
        }
        for (uint256 i = 0; i < _proxies.length; i++) {
            proposerProxies[_proxies[i]] = true;
        }
        params[ParamName.ActivePeriod] = _activePeriod;
        params[ParamName.QuorumThreshold] = _quorumThreshold;
        params[ParamName.FastPassThreshold] = _fastPassThreshold;
        emit Initiated(_voters, _powers, _proxies, _activePeriod, _quorumThreshold, _fastPassThreshold);
    }

    /*********************************
     * External and Public Functions *
     *********************************/

    function createProposal(address _target, bytes memory _data) external returns (uint256) {
        return _createProposal(msg.sender, _target, _data, ProposalType.ExternalDefault);
    }

    // create proposal through proxy
    function createProposal(
        address _proposer,
        address _target,
        bytes memory _data,
        ProposalType _type
    ) external returns (uint256) {
        require(proposerProxies[msg.sender], "sender is not a valid proxy");
        require(_type == ProposalType.ExternalDefault || _type == ProposalType.ExternalFastPass, "invalid type");
        return _createProposal(_proposer, _target, _data, _type);
    }

    function createParamChangeProposal(ParamName _name, uint256 _value) external returns (uint256) {
        bytes memory data = abi.encode(_name, _value);
        uint256 proposalId = _createProposal(msg.sender, address(0), data, ProposalType.InternalParamChange);
        emit ParamChangeProposalCreated(proposalId, _name, _value);
        return proposalId;
    }

    function createVoterUpdateProposal(address[] calldata _voters, uint256[] calldata _powers)
        external
        returns (uint256)
    {
        require(_voters.length == _powers.length, "voters and powers length not match");
        bytes memory data = abi.encode(_voters, _powers);
        uint256 proposalId = _createProposal(msg.sender, address(0), data, ProposalType.InternalVoterUpdate);
        emit VoterUpdateProposalCreated(proposalId, _voters, _powers);
        return proposalId;
    }

    function createProxyUpdateProposal(address[] calldata _addrs, bool[] calldata _ops) external returns (uint256) {
        require(_addrs.length == _ops.length, "_addrs and _ops length not match");
        bytes memory data = abi.encode(_addrs, _ops);
        uint256 proposalId = _createProposal(msg.sender, address(0), data, ProposalType.InternalProxyUpdate);
        emit ProxyUpdateProposalCreated(proposalId, _addrs, _ops);
        return proposalId;
    }

    function createTransferTokenProposal(
        address _receiver,
        address _token,
        uint256 _amount
    ) external returns (uint256) {
        bytes memory data = abi.encode(_receiver, _token, _amount);
        uint256 proposalId = _createProposal(msg.sender, address(0), data, ProposalType.InternalTransferToken);
        emit TransferTokenProposalCreated(proposalId, _receiver, _token, _amount);
        return proposalId;
    }

    function voteProposal(uint256 _proposalId, bool _vote) external {
        require(voterPowers[msg.sender] > 0, "invalid voter");
        Proposal storage p = proposals[_proposalId];
        require(block.timestamp < p.deadline, "deadline passed");
        p.votes[msg.sender] = _vote;
        emit ProposalVoted(_proposalId, msg.sender, _vote);
    }

    function executeProposal(
        uint256 _proposalId,
        ProposalType _type,
        address _target,
        bytes calldata _data
    ) external {
        require(voterPowers[msg.sender] > 0, "only voter can execute a proposal");
        Proposal storage p = proposals[_proposalId];
        require(block.timestamp < p.deadline, "deadline passed");
        require(keccak256(abi.encodePacked(_type, _target, _data)) == p.dataHash, "data hash not match");
        p.deadline = 0;

        p.votes[msg.sender] = true;
        (, , bool pass) = countVotes(_proposalId, _type);
        require(pass, "not enough votes");

        if (_type == ProposalType.ExternalDefault || _type == ProposalType.ExternalFastPass) {
            (bool success, bytes memory res) = _target.call(_data);
            require(success, _getRevertMsg(res));
        } else if (_type == ProposalType.InternalParamChange) {
            (ParamName name, uint256 value) = abi.decode((_data), (ParamName, uint256));
            params[name] = value;
            if (name == ParamName.ActivePeriod) {
                require(value <= MAX_ACTIVE_PERIOD && value >= MIN_ACTIVE_PERIOD, "invalid active period");
            } else if (name == ParamName.QuorumThreshold || name == ParamName.FastPassThreshold) {
                require(
                    params[ParamName.QuorumThreshold] >= params[ParamName.FastPassThreshold] &&
                        value < THRESHOLD_DECIMAL &&
                        value > 0,
                    "invalid threshold"
                );
            }
        } else if (_type == ProposalType.InternalVoterUpdate) {
            (address[] memory addrs, uint256[] memory powers) = abi.decode((_data), (address[], uint256[]));
            for (uint256 i = 0; i < addrs.length; i++) {
                if (powers[i] > 0) {
                    _setVoter(addrs[i], powers[i]);
                } else {
                    _removeVoter(addrs[i]);
                }
            }
        } else if (_type == ProposalType.InternalProxyUpdate) {
            (address[] memory addrs, bool[] memory ops) = abi.decode((_data), (address[], bool[]));
            for (uint256 i = 0; i < addrs.length; i++) {
                if (ops[i]) {
                    proposerProxies[addrs[i]] = true;
                } else {
                    delete proposerProxies[addrs[i]];
                }
            }
        } else if (_type == ProposalType.InternalTransferToken) {
            (address receiver, address token, uint256 amount) = abi.decode((_data), (address, address, uint256));
            _transfer(receiver, token, amount);
        }
        emit ProposalExecuted(_proposalId);
    }

    receive() external payable {}

    /**************************
     *  Public View Functions *
     **************************/

    function getVoters() public view returns (address[] memory, uint256[] memory) {
        address[] memory addrs = new address[](voters.length);
        uint256[] memory powers = new uint256[](voters.length);
        for (uint32 i = 0; i < voters.length; i++) {
            addrs[i] = voters[i];
            powers[i] = voterPowers[voters[i]];
        }
        return (addrs, powers);
    }

    function getVote(uint256 _proposalId, address _voter) public view returns (bool) {
        return proposals[_proposalId].votes[_voter];
    }

    function countVotes(uint256 _proposalId, ProposalType _type)
        public
        view
        returns (
            uint256,
            uint256,
            bool
        )
    {
        uint256 yesVotes;
        uint256 totalPower;
        for (uint32 i = 0; i < voters.length; i++) {
            if (getVote(_proposalId, voters[i])) {
                yesVotes += voterPowers[voters[i]];
            }
            totalPower += voterPowers[voters[i]];
        }
        uint256 threshold;
        if (_type == ProposalType.ExternalFastPass) {
            threshold = params[ParamName.FastPassThreshold];
        } else {
            threshold = params[ParamName.QuorumThreshold];
        }
        bool pass = (yesVotes >= (totalPower * threshold) / THRESHOLD_DECIMAL);
        return (totalPower, yesVotes, pass);
    }

    /**********************************
     * Internal and Private Functions *
     **********************************/

    // create a proposal and vote yes
    function _createProposal(
        address _proposer,
        address _target,
        bytes memory _data,
        ProposalType _type
    ) private returns (uint256) {
        require(voterPowers[_proposer] > 0, "only voter can create a proposal");
        uint256 proposalId = nextProposalId;
        nextProposalId += 1;
        Proposal storage p = proposals[proposalId];
        p.dataHash = keccak256(abi.encodePacked(_type, _target, _data));
        p.deadline = block.timestamp + params[ParamName.ActivePeriod];
        p.votes[_proposer] = true;
        emit ProposalCreated(proposalId, _type, _target, _data, p.deadline, _proposer);
        return proposalId;
    }

    function _setVoter(address _voter, uint256 _power) private {
        require(_power > 0, "zero power");
        if (voterPowers[_voter] == 0) {
            // add new voter
            voters.push(_voter);
        }
        voterPowers[_voter] = _power;
    }

    function _removeVoter(address _voter) private {
        require(voterPowers[_voter] > 0, "not a voter");
        uint256 lastIndex = voters.length - 1;
        for (uint256 i = 0; i < voters.length; i++) {
            if (voters[i] == _voter) {
                if (i < lastIndex) {
                    voters[i] = voters[lastIndex];
                }
                voters.pop();
                voterPowers[_voter] = 0;
                return;
            }
        }
        revert("voter not found"); // this should never happen
    }

    function _transfer(
        address _receiver,
        address _token,
        uint256 _amount
    ) private {
        if (_token == address(0)) {
            (bool sent, ) = _receiver.call{value: _amount, gas: 50000}("");
            require(sent, "failed to send native token");
        } else {
            IERC20(_token).safeTransfer(_receiver, _amount);
        }
    }

    // https://ethereum.stackexchange.com/a/83577
    // https://github.com/Uniswap/v3-periphery/blob/v1.0.0/contracts/base/Multicall.sol
    function _getRevertMsg(bytes memory _returnData) private pure returns (string memory) {
        // If the _res length is less than 68, then the transaction failed silently (without a revert message)
        if (_returnData.length < 68) return "Transaction reverted silently";
        assembly {
            // Slice the sighash.
            _returnData := add(_returnData, 0x04)
        }
        return abi.decode(_returnData, (string)); // All that remains is the revert string
    }
}
          

/contracts/governed-owner/interfaces/IBridgeOwner.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity >=0.8.0;

interface IBridgeOwner {
    // for bridges

    function resetSigners(address[] calldata _signers, uint256[] calldata _powers) external;

    function notifyResetSigners() external;

    function increaseNoticePeriod(uint256 _period) external;

    function setWrap(address _token) external;

    function setSupply(address _token, uint256 _supply) external;

    function increaseSupply(address _token, uint256 _delta) external;

    function decreaseSupply(address _token, uint256 _delta) external;

    function addGovernor(address _account) external;

    function removeGovernor(address _account) external;

    // for bridge tokens

    function updateBridge(address _bridge) external;

    function updateBridgeSupplyCap(address _bridge, uint256 _cap) external;

    function setBridgeTokenSwapCap(address _bridgeToken, uint256 _swapCap) external;
}
          

/contracts/governed-owner/interfaces/ICommonOwner.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity >=0.8.0;

interface ICommonOwner {
    function transferOwnership(address _newOwner) external;

    function addPauser(address _account) external;

    function removePauser(address _account) external;
}
          

/contracts/governed-owner/interfaces/IMessageOwner.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity >=0.8.0;

interface IMessageOwner {
    function setFeePerByte(uint256 _fee) external;

    function setFeeBase(uint256 _fee) external;

    function setLiquidityBridge(address _addr) external;

    function setPegBridge(address _addr) external;

    function setPegVault(address _addr) external;

    function setPegBridgeV2(address _addr) external;

    function setPegVaultV2(address _addr) external;

    function setPreExecuteMessageGasUsage(uint256 _usage) external;
}
          

/contracts/governed-owner/interfaces/ISgnOwner.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity >=0.8.0;

interface ISgnOwner {
    function setWhitelistEnabled(bool _whitelistEnabled) external;

    function addWhitelisted(address _account) external;

    function removeWhitelisted(address _account) external;

    function setGovContract(address _addr) external;

    function setRewardContract(address _addr) external;

    function setMaxSlashFactor(uint256 _maxSlashFactor) external;
}
          

/contracts/governed-owner/interfaces/IUpgradeableOwner.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity >=0.8.0;

interface IUpgradeableOwner {
    function changeProxyAdmin(address _proxy, address _newAdmin) external;

    function upgrade(address _proxy, address _implementation) external;

    function upgradeAndCall(
        address _proxy,
        address _implementation,
        bytes calldata _data
    ) external;

    function upgradeTo(address _implementation) external;

    function upgradeToAndCall(address _implementation, bytes calldata _data) external;
}
          

/contracts/governed-owner/proxies/BridgeOwnerProxy.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.9;

import "./OwnerProxyBase.sol";
import "../interfaces/IBridgeOwner.sol";
import {SimpleGovernance as sg} from "../SimpleGovernance.sol";
import {OwnerDataTypes as dt} from "./OwnerDataTypes.sol";

abstract contract BridgeOwnerProxy is OwnerProxyBase {
    // for bridges
    event ResetSignersProposalCreated(uint256 proposalId, address target, address[] signers, uint256[] powers);
    event NotifyResetSignersProposalCreated(uint256 proposalId, address target);
    event IncreaseNoticePeriodProposalCreated(uint256 proposalId, address target, uint256 period);
    event SetNativeWrapProposalCreated(uint256 proposalId, address target, address token);
    event UpdateSupplyProposalCreated(
        uint256 proposalId,
        address target,
        dt.Action action,
        address token,
        uint256 supply
    );
    event UpdateGovernorProposalCreated(uint256 proposalId, address target, dt.Action action, address account);

    // for bridge tokens
    event UpdateBridgeProposalCreated(uint256 proposalId, address target, address bridgeAddr);
    event UpdateBridgeSupplyCapProposalCreated(uint256 proposalId, address target, address bridge, uint256 cap);
    event SetBridgeTokenSwapCapProposalCreated(uint256 proposalId, address target, address bridgeToken, uint256 cap);

    function proposeResetSigners(
        address _target,
        address[] calldata _signers,
        uint256[] calldata _powers
    ) external {
        bytes memory data = abi.encodeWithSelector(IBridgeOwner.resetSigners.selector, _signers, _powers);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit ResetSignersProposalCreated(proposalId, _target, _signers, _powers);
    }

    function proposeNotifyResetSigners(address _target) external {
        bytes memory data = abi.encodeWithSelector(IBridgeOwner.notifyResetSigners.selector);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalFastPass);
        emit NotifyResetSignersProposalCreated(proposalId, _target);
    }

    function proposeIncreaseNoticePeriod(address _target, uint256 _period) external {
        bytes memory data = abi.encodeWithSelector(IBridgeOwner.increaseNoticePeriod.selector, _period);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit IncreaseNoticePeriodProposalCreated(proposalId, _target, _period);
    }

    function proposeSetNativeWrap(address _target, address _token) external {
        bytes memory data = abi.encodeWithSelector(IBridgeOwner.setWrap.selector, _token);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit SetNativeWrapProposalCreated(proposalId, _target, _token);
    }

    function proposeUpdateSupply(
        address _target,
        dt.Action _action,
        address _token,
        uint256 _supply
    ) external {
        bytes4 selector;
        if (_action == dt.Action.Set) {
            selector = IBridgeOwner.setSupply.selector;
        } else if (_action == dt.Action.Add) {
            selector = IBridgeOwner.increaseSupply.selector;
        } else if (_action == dt.Action.Remove) {
            selector = IBridgeOwner.decreaseSupply.selector;
        } else {
            revert("invalid action");
        }
        bytes memory data = abi.encodeWithSelector(selector, _token, _supply);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalFastPass);
        emit UpdateSupplyProposalCreated(proposalId, _target, _action, _token, _supply);
    }

    function proposeUpdateGovernor(
        address _target,
        dt.Action _action,
        address _account
    ) external {
        bytes4 selector;
        if (_action == dt.Action.Add) {
            selector = IBridgeOwner.addGovernor.selector;
        } else if (_action == dt.Action.Remove) {
            selector = IBridgeOwner.removeGovernor.selector;
        } else {
            revert("invalid action");
        }
        bytes memory data = abi.encodeWithSelector(selector, _account);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalFastPass);
        emit UpdateGovernorProposalCreated(proposalId, _target, _action, _account);
    }

    function proposeUpdateBridgeSupplyCap(
        address _target,
        address _bridge,
        uint256 _cap
    ) external {
        bytes memory data = abi.encodeWithSelector(IBridgeOwner.updateBridgeSupplyCap.selector, _bridge, _cap);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit UpdateBridgeSupplyCapProposalCreated(proposalId, _target, _bridge, _cap);
    }

    function proposeSetBridgeTokenSwapCap(
        address _target,
        address _bridgeToken,
        uint256 _swapCap
    ) external {
        bytes memory data = abi.encodeWithSelector(IBridgeOwner.setBridgeTokenSwapCap.selector, _bridgeToken, _swapCap);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit SetBridgeTokenSwapCapProposalCreated(proposalId, _target, _bridgeToken, _swapCap);
    }
}
          

/contracts/governed-owner/proxies/CommonOwnerProxy.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.9;

import "./OwnerProxyBase.sol";
import "../interfaces/ICommonOwner.sol";
import {SimpleGovernance as sg} from "../SimpleGovernance.sol";
import {OwnerDataTypes as dt} from "./OwnerDataTypes.sol";

abstract contract CommonOwnerProxy is OwnerProxyBase {
    event TransferOwnershipProposalCreated(uint256 proposalId, address target, uint256 newOwner);
    event UpdatePauserProposalCreated(uint256 proposalId, address target, dt.Action action, address account);

    function proposeTransferOwnership(address _target, uint256 _newOwner) external {
        bytes memory data = abi.encodeWithSelector(ICommonOwner.transferOwnership.selector, _newOwner);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit TransferOwnershipProposalCreated(proposalId, _target, _newOwner);
    }

    function proposeUpdatePauser(
        address _target,
        dt.Action _action,
        address _account
    ) external {
        bytes4 selector;
        if (_action == dt.Action.Add) {
            selector = ICommonOwner.addPauser.selector;
        } else if (_action == dt.Action.Remove) {
            selector = ICommonOwner.removePauser.selector;
        } else {
            revert("invalid action");
        }
        bytes memory data = abi.encodeWithSelector(selector, _account);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalFastPass);
        emit UpdatePauserProposalCreated(proposalId, _target, _action, _account);
    }
}
          

/contracts/governed-owner/proxies/MessageOwnerProxy.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.9;

import "./OwnerProxyBase.sol";
import "../interfaces/IMessageOwner.sol";
import {SimpleGovernance as sg} from "../SimpleGovernance.sol";
import {OwnerDataTypes as dt} from "./OwnerDataTypes.sol";

abstract contract MessageOwnerProxy is OwnerProxyBase {
    event SetMsgFeeProposalCreated(uint256 proposalId, address target, dt.MsgFeeType feeType, uint256 fee);
    event SetBridgeAddressProposalCreated(
        uint256 proposalId,
        address target,
        dt.BridgeType bridgeType,
        address bridgeAddr
    );
    event SetPreExecuteMessageGasUsageProposalCreated(uint256 proposalId, address target, uint256 usage);

    function proposeSetMsgFee(
        address _target,
        dt.MsgFeeType _feeType,
        uint256 _fee
    ) external {
        bytes4 selector;
        if (_feeType == dt.MsgFeeType.PerByte) {
            selector = IMessageOwner.setFeePerByte.selector;
        } else if (_feeType == dt.MsgFeeType.Base) {
            selector = IMessageOwner.setFeeBase.selector;
        } else {
            revert("invalid fee type");
        }
        bytes memory data = abi.encodeWithSelector(selector, _fee);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalFastPass);
        emit SetMsgFeeProposalCreated(proposalId, _target, _feeType, _fee);
    }

    function proposeSetBridgeAddress(
        address _target,
        dt.BridgeType _bridgeType,
        address _bridgeAddr
    ) external {
        bytes4 selector;
        if (_bridgeType == dt.BridgeType.Liquidity) {
            selector = IMessageOwner.setLiquidityBridge.selector;
        } else if (_bridgeType == dt.BridgeType.PegBridge) {
            selector = IMessageOwner.setPegBridge.selector;
        } else if (_bridgeType == dt.BridgeType.PegVault) {
            selector = IMessageOwner.setPegVault.selector;
        } else if (_bridgeType == dt.BridgeType.PegBridgeV2) {
            selector = IMessageOwner.setPegBridgeV2.selector;
        } else if (_bridgeType == dt.BridgeType.PegVaultV2) {
            selector = IMessageOwner.setPegVaultV2.selector;
        } else {
            revert("invalid bridge type");
        }
        bytes memory data = abi.encodeWithSelector(selector, _bridgeAddr);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit SetBridgeAddressProposalCreated(proposalId, _target, _bridgeType, _bridgeAddr);
    }

    function proposeSetPreExecuteMessageGasUsage(address _target, uint256 _usage) external {
        bytes memory data = abi.encodeWithSelector(IMessageOwner.setPreExecuteMessageGasUsage.selector, _usage);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit SetPreExecuteMessageGasUsageProposalCreated(proposalId, _target, _usage);
    }
}
          

/contracts/governed-owner/proxies/OwnerDataTypes.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity >=0.8.0;

library OwnerDataTypes {
    enum Action {
        Set,
        Add,
        Remove
    }

    enum MsgFeeType {
        PerByte,
        Base
    }

    enum BridgeType {
        Liquidity,
        PegBridge,
        PegVault,
        PegBridgeV2,
        PegVaultV2
    }
}
          

/contracts/governed-owner/proxies/OwnerProxyBase.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity >=0.8.0;

import "../SimpleGovernance.sol";

abstract contract OwnerProxyBase {
    SimpleGovernance public gov;
    address private initializer;

    constructor(address _initializer) {
        initializer = _initializer;
    }

    function initGov(SimpleGovernance _gov) public {
        require(msg.sender == initializer, "only initializer can init");
        require(address(gov) == address(0), "gov addr already set");
        gov = _gov;
    }
}
          

/contracts/governed-owner/proxies/SgnOwnerProxy.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.9;

import "./OwnerProxyBase.sol";
import "../interfaces/ISgnOwner.sol";
import {SimpleGovernance as sg} from "../SimpleGovernance.sol";
import {OwnerDataTypes as dt} from "./OwnerDataTypes.sol";

abstract contract SgnOwnerProxy is OwnerProxyBase {
    event SetWhitelistEnableProposalCreated(uint256 proposalId, address target, bool enabled);
    event UpdateWhitelistedProposalCreated(uint256 proposalId, address target, dt.Action action, address account);
    event SetGovContractProposalCreated(uint256 proposalId, address target, address addr);
    event SetRewardContractProposalCreated(uint256 proposalId, address target, address addr);
    event SetMaxSlashFactorProposalCreated(uint256 proposalId, address target, uint256 maxSlashFactor);
    event DrainTokenProposalCreated(uint256 proposalId, address target, address token, uint256 amount);

    function proposeSetWhitelistEnable(address _target, bool _enable) external {
        bytes memory data = abi.encodeWithSelector(ISgnOwner.setWhitelistEnabled.selector, _enable);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit SetWhitelistEnableProposalCreated(proposalId, _target, _enable);
    }

    function proposeUpdateWhitelisted(
        address _target,
        dt.Action _action,
        address _account
    ) external {
        bytes4 selector;
        if (_action == dt.Action.Add) {
            selector = ISgnOwner.addWhitelisted.selector;
        } else if (_action == dt.Action.Remove) {
            selector = ISgnOwner.removeWhitelisted.selector;
        } else {
            revert("invalid action");
        }
        bytes memory data = abi.encodeWithSelector(selector, _account);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalFastPass);
        emit UpdateWhitelistedProposalCreated(proposalId, _target, _action, _account);
    }

    function proposeSetGovContract(address _target, address _addr) external {
        bytes memory data = abi.encodeWithSelector(ISgnOwner.setGovContract.selector, _addr);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit SetGovContractProposalCreated(proposalId, _target, _addr);
    }

    function proposeSetRewardContract(address _target, address _addr) external {
        bytes memory data = abi.encodeWithSelector(ISgnOwner.setRewardContract.selector, _addr);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit SetRewardContractProposalCreated(proposalId, _target, _addr);
    }

    function proposeSetMaxSlashFactor(address _target, uint256 _maxSlashFactor) external {
        bytes memory data = abi.encodeWithSelector(ISgnOwner.setMaxSlashFactor.selector, _maxSlashFactor);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit SetMaxSlashFactorProposalCreated(proposalId, _target, _maxSlashFactor);
    }

    function proposeDrainToken(
        address _target,
        address _token,
        uint256 _amount
    ) external {
        bytes memory data;
        if (_token == address(0)) {
            data = abi.encodeWithSelector(bytes4(keccak256(bytes("drainToken(uint256"))), _amount);
        } else {
            data = abi.encodeWithSelector(bytes4(keccak256(bytes("drainToken(address,uint256"))), _token, _amount);
        }
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit DrainTokenProposalCreated(proposalId, _target, _token, _amount);
    }
}
          

/contracts/governed-owner/proxies/UpgradeableOwnerProxy.sol

// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.9;

import "./OwnerProxyBase.sol";
import "../interfaces/IUpgradeableOwner.sol";
import {SimpleGovernance as sg} from "../SimpleGovernance.sol";
import {OwnerDataTypes as dt} from "./OwnerDataTypes.sol";

abstract contract UpgradeableOwnerProxy is OwnerProxyBase {
    event ChangeProxyAdminProposalCreated(uint256 proposalId, address target, address proxy, address newAdmin);
    event UpgradeProposalCreated(uint256 proposalId, address target, address proxy, address implementation);
    event UpgradeAndCallProposalCreated(
        uint256 proposalId,
        address target,
        address proxy,
        address implementation,
        bytes data
    );
    event UpgradeToProposalCreated(uint256 proposalId, address target, address implementation);
    event UpgradeToAndCallProposalCreated(uint256 proposalId, address target, address implementation, bytes data);

    function proposeChangeProxyAdmin(
        address _target,
        address _proxy,
        address _newAdmin
    ) external {
        bytes memory data = abi.encodeWithSelector(IUpgradeableOwner.changeProxyAdmin.selector, _proxy, _newAdmin);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit ChangeProxyAdminProposalCreated(proposalId, _target, _proxy, _newAdmin);
    }

    function proposeUpgrade(
        address _target,
        address _proxy,
        address _implementation
    ) external {
        bytes memory data = abi.encodeWithSelector(IUpgradeableOwner.upgrade.selector, _proxy, _implementation);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit UpgradeProposalCreated(proposalId, _target, _proxy, _implementation);
    }

    function proposeUpgradeAndCall(
        address _target,
        address _proxy,
        address _implementation,
        bytes calldata _data
    ) external {
        bytes memory data = abi.encodeWithSelector(
            IUpgradeableOwner.upgradeAndCall.selector,
            _proxy,
            _implementation,
            _data
        );
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit UpgradeAndCallProposalCreated(proposalId, _target, _proxy, _implementation, _data);
    }

    function proposeUpgradeTo(address _target, address _implementation) external {
        bytes memory data = abi.encodeWithSelector(IUpgradeableOwner.upgradeTo.selector, _implementation);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit UpgradeToProposalCreated(proposalId, _target, _implementation);
    }

    function proposeUpgradeToAndCall(
        address _target,
        address _implementation,
        bytes calldata _data
    ) external {
        bytes memory data = abi.encodeWithSelector(IUpgradeableOwner.upgradeToAndCall.selector, _implementation, _data);
        uint256 proposalId = gov.createProposal(msg.sender, _target, data, sg.ProposalType.ExternalDefault);
        emit UpgradeToAndCallProposalCreated(proposalId, _target, _implementation, _data);
    }
}
          

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_initializer","internalType":"address"}]},{"type":"event","name":"ChangeProxyAdminProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"proxy","internalType":"address","indexed":false},{"type":"address","name":"newAdmin","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"DrainTokenProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"IncreaseNoticePeriodProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint256","name":"period","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"NotifyResetSignersProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"ResetSignersProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address[]","name":"signers","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"powers","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"SetBridgeAddressProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint8","name":"bridgeType","internalType":"enum OwnerDataTypes.BridgeType","indexed":false},{"type":"address","name":"bridgeAddr","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetBridgeTokenSwapCapProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"bridgeToken","internalType":"address","indexed":false},{"type":"uint256","name":"cap","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetGovContractProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"addr","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetMaxSlashFactorProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint256","name":"maxSlashFactor","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetMsgFeeProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint8","name":"feeType","internalType":"enum OwnerDataTypes.MsgFeeType","indexed":false},{"type":"uint256","name":"fee","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetNativeWrapProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"token","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetPreExecuteMessageGasUsageProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint256","name":"usage","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetRewardContractProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"addr","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetWhitelistEnableProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"bool","name":"enabled","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"TransferOwnershipProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint256","name":"newOwner","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"UpdateBridgeProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"bridgeAddr","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"UpdateBridgeSupplyCapProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"bridge","internalType":"address","indexed":false},{"type":"uint256","name":"cap","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"UpdateGovernorProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint8","name":"action","internalType":"enum OwnerDataTypes.Action","indexed":false},{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"UpdatePauserProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint8","name":"action","internalType":"enum OwnerDataTypes.Action","indexed":false},{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"UpdateSupplyProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint8","name":"action","internalType":"enum OwnerDataTypes.Action","indexed":false},{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"supply","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"UpdateWhitelistedProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"uint8","name":"action","internalType":"enum OwnerDataTypes.Action","indexed":false},{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"UpgradeAndCallProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"proxy","internalType":"address","indexed":false},{"type":"address","name":"implementation","internalType":"address","indexed":false},{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"UpgradeProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"proxy","internalType":"address","indexed":false},{"type":"address","name":"implementation","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"UpgradeToAndCallProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"implementation","internalType":"address","indexed":false},{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"UpgradeToProposalCreated","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256","indexed":false},{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"address","name":"implementation","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract SimpleGovernance"}],"name":"gov","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initGov","inputs":[{"type":"address","name":"_gov","internalType":"contract SimpleGovernance"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeChangeProxyAdmin","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_proxy","internalType":"address"},{"type":"address","name":"_newAdmin","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeDrainToken","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeIncreaseNoticePeriod","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint256","name":"_period","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeNotifyResetSigners","inputs":[{"type":"address","name":"_target","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeResetSigners","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address[]","name":"_signers","internalType":"address[]"},{"type":"uint256[]","name":"_powers","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeSetBridgeAddress","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint8","name":"_bridgeType","internalType":"enum OwnerDataTypes.BridgeType"},{"type":"address","name":"_bridgeAddr","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeSetBridgeTokenSwapCap","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_bridgeToken","internalType":"address"},{"type":"uint256","name":"_swapCap","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeSetGovContract","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_addr","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeSetMaxSlashFactor","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint256","name":"_maxSlashFactor","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeSetMsgFee","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint8","name":"_feeType","internalType":"enum OwnerDataTypes.MsgFeeType"},{"type":"uint256","name":"_fee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeSetNativeWrap","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeSetPreExecuteMessageGasUsage","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint256","name":"_usage","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeSetRewardContract","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_addr","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeSetWhitelistEnable","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"bool","name":"_enable","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeTransferOwnership","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint256","name":"_newOwner","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeUpdateBridgeSupplyCap","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_bridge","internalType":"address"},{"type":"uint256","name":"_cap","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeUpdateGovernor","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint8","name":"_action","internalType":"enum OwnerDataTypes.Action"},{"type":"address","name":"_account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeUpdatePauser","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint8","name":"_action","internalType":"enum OwnerDataTypes.Action"},{"type":"address","name":"_account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeUpdateSupply","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint8","name":"_action","internalType":"enum OwnerDataTypes.Action"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_supply","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeUpdateWhitelisted","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"uint8","name":"_action","internalType":"enum OwnerDataTypes.Action"},{"type":"address","name":"_account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeUpgrade","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_proxy","internalType":"address"},{"type":"address","name":"_implementation","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeUpgradeAndCall","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_proxy","internalType":"address"},{"type":"address","name":"_implementation","internalType":"address"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeUpgradeTo","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_implementation","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeUpgradeToAndCall","inputs":[{"type":"address","name":"_target","internalType":"address"},{"type":"address","name":"_implementation","internalType":"address"},{"type":"bytes","name":"_data","internalType":"bytes"}]}]
              

Contract Creation Code

0x60806040523480156200001157600080fd5b5060405162002b8338038062002b8383398101604081905262000034916200005a565b600180546001600160a01b0319166001600160a01b03929092169190911790556200008c565b6000602082840312156200006d57600080fd5b81516001600160a01b03811681146200008557600080fd5b9392505050565b612ae7806200009c6000396000f3fe608060405234801561001057600080fd5b50600436106101ad5760003560e01c806377e96d21116100ee578063a71ac5f011610097578063adf43efb11610071578063adf43efb14610372578063bcf612fc14610385578063d19bf98b14610398578063dc797ce3146103ab57600080fd5b8063a71ac5f014610339578063a9ed9d161461034c578063aa9f79431461035f57600080fd5b806382887e02116100c857806382887e02146103005780639f492e7c14610313578063a2ac8d861461032657600080fd5b806377e96d21146102c757806378a4f076146102da5780637f1f1990146102ed57600080fd5b8063224468a81161015b57806339acf6951161013557806339acf6951461027b57806339f2b6511461028e578063656fe066146102a15780636a5c9358146102b457600080fd5b8063224468a8146102425780632ef754af1461025557806338cd4d091461026857600080fd5b8063173a06f91161018c578063173a06f9146102095780631a6ca6da1461021c5780631de8a0161461022f57600080fd5b8062395f11146101b25780630de54802146101c757806312d43a51146101da575b600080fd5b6101c56101c03660046122c4565b6103be565b005b6101c56101d53660046122f0565b6104d4565b6000546101ed906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b6101c5610217366004612375565b6105e7565b6101c561022a3660046122f0565b610710565b6101c561023d3660046123f8565b610823565b6101c56102503660046122f0565b610952565b6101c5610263366004612457565b610a65565b6101c56102763660046122c4565b610c32565b6101c56102893660046124e8565b610d3e565b6101c561029c3660046122c4565b610e62565b6101c56102af36600461254d565b610f6e565b6101c56102c23660046122c4565b611111565b6101c56102d5366004612592565b61121d565b6101c56102e83660046125c2565b61133b565b6101c56102fb3660046125f0565b611497565b6101c561030e366004612624565b6116b5565b6101c56103213660046125c2565b6117c9565b6101c5610334366004612657565b611925565b6101c561034736600461267b565b611a22565b6101c561035a366004612657565b611b3a565b6101c561036d3660046123f8565b611c27565b6101c56103803660046125c2565b611d4b565b6101c56103933660046122f0565b611ea7565b6101c56103a6366004612592565b611fba565b6101c56103b9366004612592565b61218e565b60408051602480820184905282518083039091018152604490910182526020810180516001600160e01b0316631a20325760e01b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd4802749061042f903390889087908790600401612710565b602060405180830381600087803b15801561044957600080fd5b505af115801561045d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104819190612790565b604080518281526001600160a01b03871660208201529081018590529091507f170cfbd4ca14e4c07750912ad957e666499c81fdfef63021cde154c6ffaac2d7906060015b60405180910390a150505050565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b0316631a1c1b9560e21b179052600080549351633f52009d60e21b81529293909291169063fd48027490610548903390889087908790600401612710565b602060405180830381600087803b15801561056257600080fd5b505af1158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a9190612790565b604080518281526001600160a01b0380881660208301528616918101919091529091507f0440d8b8371306b54b33893631962ccab8e82436d91eb4a2c481454cc2ed4781906060016104c6565b600063a7bdf45a60e01b858585856040516024016106089493929190612841565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd480274906106729033908b9087908790600401612710565b602060405180830381600087803b15801561068c57600080fd5b505af11580156106a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c49190612790565b90507f4c42642dbb775b1ef06ad1492581510de04ccfb5ad078338d6ae369b56f356a08188888888886040516106ff96959493929190612873565b60405180910390a150505050505050565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b0316631b2ce7f360e11b179052600080549351633f52009d60e21b81529293909291169063fd48027490610784903390889087908790600401612710565b602060405180830381600087803b15801561079e57600080fd5b505af11580156107b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d69190612790565b604080518281526001600160a01b0380881660208301528616918101919091529091507f322efec8297181586148e7711ed39e230b706795edf152fd4e3a3a8fc009d33b906060016104c6565b604080516001600160a01b03848116602483015283811660448084019190915283518084039091018152606490920183526020820180516001600160e01b0316633f7f93af60e11b179052600080549351633f52009d60e21b81529293909291169063fd4802749061089f903390899087908790600401612710565b602060405180830381600087803b1580156108b957600080fd5b505af11580156108cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f19190612790565b604080518281526001600160a01b0380891660208301528088169282019290925290851660608201529091507f892ed68a932643ffae382937ae40947f858726f5014c80e6612255d981508090906080015b60405180910390a15050505050565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b0316634ffc800d60e11b179052600080549351633f52009d60e21b81529293909291169063fd480274906109c6903390889087908790600401612710565b602060405180830381600087803b1580156109e057600080fd5b505af11580156109f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a189190612790565b604080518281526001600160a01b0380881660208301528616918101919091529091507f0691c48365957fae1547e6922078da4127a4ec5beedd4aca7b80a5c793722556906060016104c6565b600080846002811115610a7a57610a7a6126e6565b1415610a8e5750632d3633b760e21b610b2b565b6001846002811115610aa257610aa26126e6565b1415610ab65750633cfe6c7760e11b610b2b565b6002846002811115610aca57610aca6126e6565b1415610ade575063057425d760e21b610b2b565b60405162461bcd60e51b815260206004820152600e60248201527f696e76616c696420616374696f6e00000000000000000000000000000000000060448201526064015b60405180910390fd5b604080516001600160a01b038581166024830152604480830186905283518084039091018152606490920183526020820180516001600160e01b03166001600160e01b03198616179052600080549351633f52009d60e21b81529293909291169063fd48027490610ba79033908b908790600190600401612710565b602060405180830381600087803b158015610bc157600080fd5b505af1158015610bd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf99190612790565b90507f68a1245119792f0c0b4396c9d85ed7e432c53279527235d14c64bc4e801d2bb081888888886040516106ff9594939291906128cc565b60408051602480820184905282518083039091018152604490910182526020810180516001600160e01b0316634586f33160e01b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd48027490610ca3903390889087908790600401612710565b602060405180830381600087803b158015610cbd57600080fd5b505af1158015610cd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf59190612790565b604080518281526001600160a01b03871660208201529081018590529091507fa140c5e7d56a62eaaaa3aeb3b9d49c5fc85004d8d25920be0bce5e08a0b7ec9b906060016104c6565b6000634f1ef28660e01b848484604051602401610d5d9392919061292e565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd48027490610dc79033908a9087908790600401612710565b602060405180830381600087803b158015610de157600080fd5b505af1158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190612790565b90507f7936bef0e4e9424795215dbcddd145b5f6ccbe6d35ed9ceacc3c9cec1b1a1ed18187878787604051610e52959493929190612951565b60405180910390a1505050505050565b60408051602480820184905282518083039091018152604490910182526020810180516001600160e01b0316637906491560e11b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd48027490610ed3903390889087908790600401612710565b602060405180830381600087803b158015610eed57600080fd5b505af1158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f259190612790565b604080518281526001600160a01b03871660208201529081018590529091507f27cc981a956034897b297d307eaa4e907654717913a238daf3e32a5bd0e18aea906060016104c6565b600080836001811115610f8357610f836126e6565b1415610f97575063e2c1ed2560e01b611007565b6001836001811115610fab57610fab6126e6565b1415610fbf575063036145eb60e11b611007565b60405162461bcd60e51b815260206004820152601060248201527f696e76616c6964206665652074797065000000000000000000000000000000006044820152606401610b22565b6000818360405160240161101d91815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd480274906110889033908a908790600190600401612710565b602060405180830381600087803b1580156110a257600080fd5b505af11580156110b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110da9190612790565b90507f924ed1dc9162d297ef826f4eb457b22796e62033fea2fb6f201c13661d04c64181878787604051610e529493929190612984565b60408051602480820184905282518083039091018152604490910182526020810180516001600160e01b031663f2fde38b60e01b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd48027490611182903390889087908790600401612710565b602060405180830381600087803b15801561119c57600080fd5b505af11580156111b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d49190612790565b604080518281526001600160a01b03871660208201529081018590529091507f2e7f126e99465c6c540098e0eca13d2fc8d71908debbf31d908bee17e2866d0c906060016104c6565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663cd04611960e01b179052600080549351633f52009d60e21b81529293909291169063fd48027490611295903390899087908790600401612710565b602060405180830381600087803b1580156112af57600080fd5b505af11580156112c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e79190612790565b604080518281526001600160a01b038089166020830152871691810191909152606081018590529091507fbbf294b7b2aadbd73c0198ccea847bbc640871eb1ad2a0b01ac080d077f088e790608001610943565b60006001836002811115611351576113516126e6565b141561136557506320b707b160e21b611389565b6002836002811115611379576113796126e6565b1415610ade5750636b2c0f5560e01b5b6040516001600160a01b0383166024820152600090829060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd4802749061140e9033908a908790600190600401612710565b602060405180830381600087803b15801561142857600080fd5b505af115801561143c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114609190612790565b90507f9fe02e73a05d9dc9d3f3cb9423f6531a055a6083c43978dc2b64d6e505e4366581878787604051610e5294939291906129bc565b6000808360048111156114ac576114ac6126e6565b14156114c0575063588be02b60e01b6115a8565b60018360048111156114d4576114d46126e6565b14156114e857506301e5ff3360e11b6115a8565b60028360048111156114fc576114fc6126e6565b14156115105750639b05a77560e01b6115a8565b6003836004811115611524576115246126e6565b14156115385750634177ea8160e11b6115a8565b600483600481111561154c5761154c6126e6565b1415611560575063f83b0fb960e01b6115a8565b60405162461bcd60e51b815260206004820152601360248201527f696e76616c6964206272696467652074797065000000000000000000000000006044820152606401610b22565b6040516001600160a01b0383166024820152600090829060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd4802749061162c9033908a9087908790600401612710565b602060405180830381600087803b15801561164657600080fd5b505af115801561165a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167e9190612790565b90507f1605f3e8c96ab34dc0790b6937e2f0c59bb340db6e689a77bc500789d32314f881878787604051610e5294939291906129f3565b6040805182151560248083019190915282518083039091018152604490910182526020810180516001600160e01b0316630296cf3f60e11b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd4802749061172a903390889087908790600401612710565b602060405180830381600087803b15801561174457600080fd5b505af1158015611758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177c9190612790565b604080518281526001600160a01b0387166020820152851515918101919091529091507fb415e98e9740cf326dbeb0b43f0fa7d742ab13c6c2fc4e0042b6289cca074526906060016104c6565b600060018360028111156117df576117df6126e6565b14156117f357506310154bad60e01b611817565b6002836002811115611807576118076126e6565b1415610ade575063291d954960e01b5b6040516001600160a01b0383166024820152600090829060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd4802749061189c9033908a908790600190600401612710565b602060405180830381600087803b1580156118b657600080fd5b505af11580156118ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ee9190612790565b90507f4336c9be2e5abfad187a39a7f7346158c644f54824688bb5a5b335f9306fb9bb81878787604051610e5294939291906129bc565b6040805160048082526024820183526020820180516001600160e01b03166325c38b9f60e01b179052600080549351633f52009d60e21b8152929390926001600160a01b039091169163fd480274916119879133918891889160019101612710565b602060405180830381600087803b1580156119a157600080fd5b505af11580156119b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119d99190612790565b604080518281526001600160a01b03861660208201529192507f149a32d950b4bc0cb34725d5a842addc6f3e428807357a578301e078cc644357910160405180910390a1505050565b6000639623609d60e01b85858585604051602401611a439493929190612a33565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd48027490611aad9033908b9087908790600401612710565b602060405180830381600087803b158015611ac757600080fd5b505af1158015611adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aff9190612790565b90507ff6b46465ce70c6b53ccde6e33cdd45c1906ded1e8553ff64ebdadf97d3ac29518188888888886040516106ff96959493929190612a6a565b6001546001600160a01b03163314611b945760405162461bcd60e51b815260206004820152601960248201527f6f6e6c7920696e697469616c697a65722063616e20696e6974000000000000006044820152606401610b22565b6000546001600160a01b031615611bed5760405162461bcd60e51b815260206004820152601460248201527f676f76206164647220616c7265616479207365740000000000000000000000006044820152606401610b22565b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b604080516001600160a01b03848116602483015283811660448084019190915283518084039091018152606490920183526020820180516001600160e01b031663266a23b160e21b179052600080549351633f52009d60e21b81529293909291169063fd48027490611ca3903390899087908790600401612710565b602060405180830381600087803b158015611cbd57600080fd5b505af1158015611cd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf59190612790565b604080518281526001600160a01b0380891660208301528088169282019290925290851660608201529091507fc1dead51ac2e9fa286784eeefebacaf915332934c6d6fd290ec2c8de51c7863290608001610943565b60006001836002811115611d6157611d616126e6565b1415611d7557506303c4a25d60e41b611d99565b6002836002811115611d8957611d896126e6565b1415610ade5750631dd9b59160e31b5b6040516001600160a01b0383166024820152600090829060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd48027490611e1e9033908a908790600190600401612710565b602060405180830381600087803b158015611e3857600080fd5b505af1158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e709190612790565b90507f725ab9c9498b34fa1336448b0dc8dfb419461e03707ace510d44e8bb63d8485181878787604051610e5294939291906129bc565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b03166328a8478560e11b179052600080549351633f52009d60e21b81529293909291169063fd48027490611f1b903390889087908790600401612710565b602060405180830381600087803b158015611f3557600080fd5b505af1158015611f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6d9190612790565b604080518281526001600160a01b0380881660208301528616918101919091529091507f8aaee1ae0ee9b8019d672115e172cd8fd03686f0f117ce65aa0ed224ca6d12b3906060016104c6565b60606001600160a01b0383166120385750604080518082018252601281527f647261696e546f6b656e2875696e74323536000000000000000000000000000060209182015281516024808201859052835180830390910181526044909101909252810180516001600160e01b031663a76cd1bb60e01b1790526120b1565b50604080518082018252601a81527f647261696e546f6b656e28616464726573732c75696e7432353600000000000060209182015281516001600160a01b03851660248201526044808201859052835180830390910181526064909101909252810180516001600160e01b0316634dd256db60e11b1790525b60008054604051633f52009d60e21b81526001600160a01b039091169063fd480274906120e8903390899087908790600401612710565b602060405180830381600087803b15801561210257600080fd5b505af1158015612116573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213a9190612790565b604080518281526001600160a01b038089166020830152871691810191909152606081018590529091507f07315b20d3a4862680a34cedf6a8b62bd45bdf98fa602f664417d8a84d47c1bc90608001610943565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03166326717b8d60e11b179052600080549351633f52009d60e21b81529293909291169063fd48027490612206903390899087908790600401612710565b602060405180830381600087803b15801561222057600080fd5b505af1158015612234573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122589190612790565b604080518281526001600160a01b038089166020830152871691810191909152606081018590529091507fdf93094bf7ed4f11758b798f8463ab250ae3db9edc392c26b92443f3cf73100490608001610943565b6001600160a01b03811681146122c157600080fd5b50565b600080604083850312156122d757600080fd5b82356122e2816122ac565b946020939093013593505050565b6000806040838503121561230357600080fd5b823561230e816122ac565b9150602083013561231e816122ac565b809150509250929050565b60008083601f84011261233b57600080fd5b50813567ffffffffffffffff81111561235357600080fd5b6020830191508360208260051b850101111561236e57600080fd5b9250929050565b60008060008060006060868803121561238d57600080fd5b8535612398816122ac565b9450602086013567ffffffffffffffff808211156123b557600080fd5b6123c189838a01612329565b909650945060408801359150808211156123da57600080fd5b506123e788828901612329565b969995985093965092949392505050565b60008060006060848603121561240d57600080fd5b8335612418816122ac565b92506020840135612428816122ac565b91506040840135612438816122ac565b809150509250925092565b80356003811061245257600080fd5b919050565b6000806000806080858703121561246d57600080fd5b8435612478816122ac565b935061248660208601612443565b92506040850135612496816122ac565b9396929550929360600135925050565b60008083601f8401126124b857600080fd5b50813567ffffffffffffffff8111156124d057600080fd5b60208301915083602082850101111561236e57600080fd5b600080600080606085870312156124fe57600080fd5b8435612509816122ac565b93506020850135612519816122ac565b9250604085013567ffffffffffffffff81111561253557600080fd5b612541878288016124a6565b95989497509550505050565b60008060006060848603121561256257600080fd5b833561256d816122ac565b925060208401356002811061258157600080fd5b929592945050506040919091013590565b6000806000606084860312156125a757600080fd5b83356125b2816122ac565b92506020840135612581816122ac565b6000806000606084860312156125d757600080fd5b83356125e2816122ac565b925061242860208501612443565b60008060006060848603121561260557600080fd5b8335612610816122ac565b925060208401356005811061242857600080fd5b6000806040838503121561263757600080fd5b8235612642816122ac565b91506020830135801515811461231e57600080fd5b60006020828403121561266957600080fd5b8135612674816122ac565b9392505050565b60008060008060006080868803121561269357600080fd5b853561269e816122ac565b945060208601356126ae816122ac565b935060408601356126be816122ac565b9250606086013567ffffffffffffffff8111156126da57600080fd5b6123e7888289016124a6565b634e487b7160e01b600052602160045260246000fd5b6006811061270c5761270c6126e6565b9052565b60006001600160a01b038087168352602081871681850152608060408501528551915081608085015260005b828110156127585786810182015185820160a00152810161273c565b8281111561276a57600060a084870101525b5050601f01601f1916820160a001905061278760608301846126fc565b95945050505050565b6000602082840312156127a257600080fd5b5051919050565b8183526000602080850194508260005b858110156127e75781356127cc816122ac565b6001600160a01b0316875295820195908201906001016127b9565b509495945050505050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561282457600080fd5b8260051b8083602087013760009401602001938452509192915050565b6040815260006128556040830186886127a9565b82810360208401526128688185876127f2565b979650505050505050565b8681526001600160a01b038616602082015260806040820152600061289c6080830186886127a9565b82810360608401526128af8185876127f2565b9998505050505050505050565b6003811061270c5761270c6126e6565b8581526001600160a01b03858116602083015260a08201906128f160408401876128bc565b939093166060820152608001529392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0384168152604060208201526000612787604083018486612905565b85815260006001600160a01b03808716602084015280861660408401525060806060830152612868608083018486612905565b8481526001600160a01b038416602082015260808101600284106129aa576129aa6126e6565b60408201939093526060015292915050565b8481526001600160a01b03848116602083015260808201906129e160408401866128bc565b80841660608401525095945050505050565b8481526001600160a01b038481166020830152608082019060058510612a1b57612a1b6126e6565b84604084015280841660608401525095945050505050565b60006001600160a01b03808716835280861660208401525060606040830152612a60606083018486612905565b9695505050505050565b86815260006001600160a01b038088166020840152808716604084015280861660608401525060a06080830152612aa560a083018486612905565b9897505050505050505056fea2646970667358221220cd73b65b509940334bb91e620ef353f932d88894ac4721bdf2c9427782c3ed2664736f6c634300080900330000000000000000000000001b9dfc56e38b0f92448659c114e2347bd803911c

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101ad5760003560e01c806377e96d21116100ee578063a71ac5f011610097578063adf43efb11610071578063adf43efb14610372578063bcf612fc14610385578063d19bf98b14610398578063dc797ce3146103ab57600080fd5b8063a71ac5f014610339578063a9ed9d161461034c578063aa9f79431461035f57600080fd5b806382887e02116100c857806382887e02146103005780639f492e7c14610313578063a2ac8d861461032657600080fd5b806377e96d21146102c757806378a4f076146102da5780637f1f1990146102ed57600080fd5b8063224468a81161015b57806339acf6951161013557806339acf6951461027b57806339f2b6511461028e578063656fe066146102a15780636a5c9358146102b457600080fd5b8063224468a8146102425780632ef754af1461025557806338cd4d091461026857600080fd5b8063173a06f91161018c578063173a06f9146102095780631a6ca6da1461021c5780631de8a0161461022f57600080fd5b8062395f11146101b25780630de54802146101c757806312d43a51146101da575b600080fd5b6101c56101c03660046122c4565b6103be565b005b6101c56101d53660046122f0565b6104d4565b6000546101ed906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b6101c5610217366004612375565b6105e7565b6101c561022a3660046122f0565b610710565b6101c561023d3660046123f8565b610823565b6101c56102503660046122f0565b610952565b6101c5610263366004612457565b610a65565b6101c56102763660046122c4565b610c32565b6101c56102893660046124e8565b610d3e565b6101c561029c3660046122c4565b610e62565b6101c56102af36600461254d565b610f6e565b6101c56102c23660046122c4565b611111565b6101c56102d5366004612592565b61121d565b6101c56102e83660046125c2565b61133b565b6101c56102fb3660046125f0565b611497565b6101c561030e366004612624565b6116b5565b6101c56103213660046125c2565b6117c9565b6101c5610334366004612657565b611925565b6101c561034736600461267b565b611a22565b6101c561035a366004612657565b611b3a565b6101c561036d3660046123f8565b611c27565b6101c56103803660046125c2565b611d4b565b6101c56103933660046122f0565b611ea7565b6101c56103a6366004612592565b611fba565b6101c56103b9366004612592565b61218e565b60408051602480820184905282518083039091018152604490910182526020810180516001600160e01b0316631a20325760e01b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd4802749061042f903390889087908790600401612710565b602060405180830381600087803b15801561044957600080fd5b505af115801561045d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104819190612790565b604080518281526001600160a01b03871660208201529081018590529091507f170cfbd4ca14e4c07750912ad957e666499c81fdfef63021cde154c6ffaac2d7906060015b60405180910390a150505050565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b0316631a1c1b9560e21b179052600080549351633f52009d60e21b81529293909291169063fd48027490610548903390889087908790600401612710565b602060405180830381600087803b15801561056257600080fd5b505af1158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a9190612790565b604080518281526001600160a01b0380881660208301528616918101919091529091507f0440d8b8371306b54b33893631962ccab8e82436d91eb4a2c481454cc2ed4781906060016104c6565b600063a7bdf45a60e01b858585856040516024016106089493929190612841565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd480274906106729033908b9087908790600401612710565b602060405180830381600087803b15801561068c57600080fd5b505af11580156106a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c49190612790565b90507f4c42642dbb775b1ef06ad1492581510de04ccfb5ad078338d6ae369b56f356a08188888888886040516106ff96959493929190612873565b60405180910390a150505050505050565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b0316631b2ce7f360e11b179052600080549351633f52009d60e21b81529293909291169063fd48027490610784903390889087908790600401612710565b602060405180830381600087803b15801561079e57600080fd5b505af11580156107b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d69190612790565b604080518281526001600160a01b0380881660208301528616918101919091529091507f322efec8297181586148e7711ed39e230b706795edf152fd4e3a3a8fc009d33b906060016104c6565b604080516001600160a01b03848116602483015283811660448084019190915283518084039091018152606490920183526020820180516001600160e01b0316633f7f93af60e11b179052600080549351633f52009d60e21b81529293909291169063fd4802749061089f903390899087908790600401612710565b602060405180830381600087803b1580156108b957600080fd5b505af11580156108cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f19190612790565b604080518281526001600160a01b0380891660208301528088169282019290925290851660608201529091507f892ed68a932643ffae382937ae40947f858726f5014c80e6612255d981508090906080015b60405180910390a15050505050565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b0316634ffc800d60e11b179052600080549351633f52009d60e21b81529293909291169063fd480274906109c6903390889087908790600401612710565b602060405180830381600087803b1580156109e057600080fd5b505af11580156109f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a189190612790565b604080518281526001600160a01b0380881660208301528616918101919091529091507f0691c48365957fae1547e6922078da4127a4ec5beedd4aca7b80a5c793722556906060016104c6565b600080846002811115610a7a57610a7a6126e6565b1415610a8e5750632d3633b760e21b610b2b565b6001846002811115610aa257610aa26126e6565b1415610ab65750633cfe6c7760e11b610b2b565b6002846002811115610aca57610aca6126e6565b1415610ade575063057425d760e21b610b2b565b60405162461bcd60e51b815260206004820152600e60248201527f696e76616c696420616374696f6e00000000000000000000000000000000000060448201526064015b60405180910390fd5b604080516001600160a01b038581166024830152604480830186905283518084039091018152606490920183526020820180516001600160e01b03166001600160e01b03198616179052600080549351633f52009d60e21b81529293909291169063fd48027490610ba79033908b908790600190600401612710565b602060405180830381600087803b158015610bc157600080fd5b505af1158015610bd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf99190612790565b90507f68a1245119792f0c0b4396c9d85ed7e432c53279527235d14c64bc4e801d2bb081888888886040516106ff9594939291906128cc565b60408051602480820184905282518083039091018152604490910182526020810180516001600160e01b0316634586f33160e01b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd48027490610ca3903390889087908790600401612710565b602060405180830381600087803b158015610cbd57600080fd5b505af1158015610cd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf59190612790565b604080518281526001600160a01b03871660208201529081018590529091507fa140c5e7d56a62eaaaa3aeb3b9d49c5fc85004d8d25920be0bce5e08a0b7ec9b906060016104c6565b6000634f1ef28660e01b848484604051602401610d5d9392919061292e565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd48027490610dc79033908a9087908790600401612710565b602060405180830381600087803b158015610de157600080fd5b505af1158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190612790565b90507f7936bef0e4e9424795215dbcddd145b5f6ccbe6d35ed9ceacc3c9cec1b1a1ed18187878787604051610e52959493929190612951565b60405180910390a1505050505050565b60408051602480820184905282518083039091018152604490910182526020810180516001600160e01b0316637906491560e11b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd48027490610ed3903390889087908790600401612710565b602060405180830381600087803b158015610eed57600080fd5b505af1158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f259190612790565b604080518281526001600160a01b03871660208201529081018590529091507f27cc981a956034897b297d307eaa4e907654717913a238daf3e32a5bd0e18aea906060016104c6565b600080836001811115610f8357610f836126e6565b1415610f97575063e2c1ed2560e01b611007565b6001836001811115610fab57610fab6126e6565b1415610fbf575063036145eb60e11b611007565b60405162461bcd60e51b815260206004820152601060248201527f696e76616c6964206665652074797065000000000000000000000000000000006044820152606401610b22565b6000818360405160240161101d91815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd480274906110889033908a908790600190600401612710565b602060405180830381600087803b1580156110a257600080fd5b505af11580156110b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110da9190612790565b90507f924ed1dc9162d297ef826f4eb457b22796e62033fea2fb6f201c13661d04c64181878787604051610e529493929190612984565b60408051602480820184905282518083039091018152604490910182526020810180516001600160e01b031663f2fde38b60e01b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd48027490611182903390889087908790600401612710565b602060405180830381600087803b15801561119c57600080fd5b505af11580156111b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d49190612790565b604080518281526001600160a01b03871660208201529081018590529091507f2e7f126e99465c6c540098e0eca13d2fc8d71908debbf31d908bee17e2866d0c906060016104c6565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663cd04611960e01b179052600080549351633f52009d60e21b81529293909291169063fd48027490611295903390899087908790600401612710565b602060405180830381600087803b1580156112af57600080fd5b505af11580156112c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e79190612790565b604080518281526001600160a01b038089166020830152871691810191909152606081018590529091507fbbf294b7b2aadbd73c0198ccea847bbc640871eb1ad2a0b01ac080d077f088e790608001610943565b60006001836002811115611351576113516126e6565b141561136557506320b707b160e21b611389565b6002836002811115611379576113796126e6565b1415610ade5750636b2c0f5560e01b5b6040516001600160a01b0383166024820152600090829060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd4802749061140e9033908a908790600190600401612710565b602060405180830381600087803b15801561142857600080fd5b505af115801561143c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114609190612790565b90507f9fe02e73a05d9dc9d3f3cb9423f6531a055a6083c43978dc2b64d6e505e4366581878787604051610e5294939291906129bc565b6000808360048111156114ac576114ac6126e6565b14156114c0575063588be02b60e01b6115a8565b60018360048111156114d4576114d46126e6565b14156114e857506301e5ff3360e11b6115a8565b60028360048111156114fc576114fc6126e6565b14156115105750639b05a77560e01b6115a8565b6003836004811115611524576115246126e6565b14156115385750634177ea8160e11b6115a8565b600483600481111561154c5761154c6126e6565b1415611560575063f83b0fb960e01b6115a8565b60405162461bcd60e51b815260206004820152601360248201527f696e76616c6964206272696467652074797065000000000000000000000000006044820152606401610b22565b6040516001600160a01b0383166024820152600090829060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd4802749061162c9033908a9087908790600401612710565b602060405180830381600087803b15801561164657600080fd5b505af115801561165a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167e9190612790565b90507f1605f3e8c96ab34dc0790b6937e2f0c59bb340db6e689a77bc500789d32314f881878787604051610e5294939291906129f3565b6040805182151560248083019190915282518083039091018152604490910182526020810180516001600160e01b0316630296cf3f60e11b179052600080549251633f52009d60e21b8152919290916001600160a01b039091169063fd4802749061172a903390889087908790600401612710565b602060405180830381600087803b15801561174457600080fd5b505af1158015611758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177c9190612790565b604080518281526001600160a01b0387166020820152851515918101919091529091507fb415e98e9740cf326dbeb0b43f0fa7d742ab13c6c2fc4e0042b6289cca074526906060016104c6565b600060018360028111156117df576117df6126e6565b14156117f357506310154bad60e01b611817565b6002836002811115611807576118076126e6565b1415610ade575063291d954960e01b5b6040516001600160a01b0383166024820152600090829060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd4802749061189c9033908a908790600190600401612710565b602060405180830381600087803b1580156118b657600080fd5b505af11580156118ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ee9190612790565b90507f4336c9be2e5abfad187a39a7f7346158c644f54824688bb5a5b335f9306fb9bb81878787604051610e5294939291906129bc565b6040805160048082526024820183526020820180516001600160e01b03166325c38b9f60e01b179052600080549351633f52009d60e21b8152929390926001600160a01b039091169163fd480274916119879133918891889160019101612710565b602060405180830381600087803b1580156119a157600080fd5b505af11580156119b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119d99190612790565b604080518281526001600160a01b03861660208201529192507f149a32d950b4bc0cb34725d5a842addc6f3e428807357a578301e078cc644357910160405180910390a1505050565b6000639623609d60e01b85858585604051602401611a439493929190612a33565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd48027490611aad9033908b9087908790600401612710565b602060405180830381600087803b158015611ac757600080fd5b505af1158015611adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aff9190612790565b90507ff6b46465ce70c6b53ccde6e33cdd45c1906ded1e8553ff64ebdadf97d3ac29518188888888886040516106ff96959493929190612a6a565b6001546001600160a01b03163314611b945760405162461bcd60e51b815260206004820152601960248201527f6f6e6c7920696e697469616c697a65722063616e20696e6974000000000000006044820152606401610b22565b6000546001600160a01b031615611bed5760405162461bcd60e51b815260206004820152601460248201527f676f76206164647220616c7265616479207365740000000000000000000000006044820152606401610b22565b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b604080516001600160a01b03848116602483015283811660448084019190915283518084039091018152606490920183526020820180516001600160e01b031663266a23b160e21b179052600080549351633f52009d60e21b81529293909291169063fd48027490611ca3903390899087908790600401612710565b602060405180830381600087803b158015611cbd57600080fd5b505af1158015611cd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf59190612790565b604080518281526001600160a01b0380891660208301528088169282019290925290851660608201529091507fc1dead51ac2e9fa286784eeefebacaf915332934c6d6fd290ec2c8de51c7863290608001610943565b60006001836002811115611d6157611d616126e6565b1415611d7557506303c4a25d60e41b611d99565b6002836002811115611d8957611d896126e6565b1415610ade5750631dd9b59160e31b5b6040516001600160a01b0383166024820152600090829060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600080549251633f52009d60e21b8152919350916001600160a01b03169063fd48027490611e1e9033908a908790600190600401612710565b602060405180830381600087803b158015611e3857600080fd5b505af1158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e709190612790565b90507f725ab9c9498b34fa1336448b0dc8dfb419461e03707ace510d44e8bb63d8485181878787604051610e5294939291906129bc565b604080516001600160a01b0383811660248084019190915283518084039091018152604490920183526020820180516001600160e01b03166328a8478560e11b179052600080549351633f52009d60e21b81529293909291169063fd48027490611f1b903390889087908790600401612710565b602060405180830381600087803b158015611f3557600080fd5b505af1158015611f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6d9190612790565b604080518281526001600160a01b0380881660208301528616918101919091529091507f8aaee1ae0ee9b8019d672115e172cd8fd03686f0f117ce65aa0ed224ca6d12b3906060016104c6565b60606001600160a01b0383166120385750604080518082018252601281527f647261696e546f6b656e2875696e74323536000000000000000000000000000060209182015281516024808201859052835180830390910181526044909101909252810180516001600160e01b031663a76cd1bb60e01b1790526120b1565b50604080518082018252601a81527f647261696e546f6b656e28616464726573732c75696e7432353600000000000060209182015281516001600160a01b03851660248201526044808201859052835180830390910181526064909101909252810180516001600160e01b0316634dd256db60e11b1790525b60008054604051633f52009d60e21b81526001600160a01b039091169063fd480274906120e8903390899087908790600401612710565b602060405180830381600087803b15801561210257600080fd5b505af1158015612116573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213a9190612790565b604080518281526001600160a01b038089166020830152871691810191909152606081018590529091507f07315b20d3a4862680a34cedf6a8b62bd45bdf98fa602f664417d8a84d47c1bc90608001610943565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03166326717b8d60e11b179052600080549351633f52009d60e21b81529293909291169063fd48027490612206903390899087908790600401612710565b602060405180830381600087803b15801561222057600080fd5b505af1158015612234573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122589190612790565b604080518281526001600160a01b038089166020830152871691810191909152606081018590529091507fdf93094bf7ed4f11758b798f8463ab250ae3db9edc392c26b92443f3cf73100490608001610943565b6001600160a01b03811681146122c157600080fd5b50565b600080604083850312156122d757600080fd5b82356122e2816122ac565b946020939093013593505050565b6000806040838503121561230357600080fd5b823561230e816122ac565b9150602083013561231e816122ac565b809150509250929050565b60008083601f84011261233b57600080fd5b50813567ffffffffffffffff81111561235357600080fd5b6020830191508360208260051b850101111561236e57600080fd5b9250929050565b60008060008060006060868803121561238d57600080fd5b8535612398816122ac565b9450602086013567ffffffffffffffff808211156123b557600080fd5b6123c189838a01612329565b909650945060408801359150808211156123da57600080fd5b506123e788828901612329565b969995985093965092949392505050565b60008060006060848603121561240d57600080fd5b8335612418816122ac565b92506020840135612428816122ac565b91506040840135612438816122ac565b809150509250925092565b80356003811061245257600080fd5b919050565b6000806000806080858703121561246d57600080fd5b8435612478816122ac565b935061248660208601612443565b92506040850135612496816122ac565b9396929550929360600135925050565b60008083601f8401126124b857600080fd5b50813567ffffffffffffffff8111156124d057600080fd5b60208301915083602082850101111561236e57600080fd5b600080600080606085870312156124fe57600080fd5b8435612509816122ac565b93506020850135612519816122ac565b9250604085013567ffffffffffffffff81111561253557600080fd5b612541878288016124a6565b95989497509550505050565b60008060006060848603121561256257600080fd5b833561256d816122ac565b925060208401356002811061258157600080fd5b929592945050506040919091013590565b6000806000606084860312156125a757600080fd5b83356125b2816122ac565b92506020840135612581816122ac565b6000806000606084860312156125d757600080fd5b83356125e2816122ac565b925061242860208501612443565b60008060006060848603121561260557600080fd5b8335612610816122ac565b925060208401356005811061242857600080fd5b6000806040838503121561263757600080fd5b8235612642816122ac565b91506020830135801515811461231e57600080fd5b60006020828403121561266957600080fd5b8135612674816122ac565b9392505050565b60008060008060006080868803121561269357600080fd5b853561269e816122ac565b945060208601356126ae816122ac565b935060408601356126be816122ac565b9250606086013567ffffffffffffffff8111156126da57600080fd5b6123e7888289016124a6565b634e487b7160e01b600052602160045260246000fd5b6006811061270c5761270c6126e6565b9052565b60006001600160a01b038087168352602081871681850152608060408501528551915081608085015260005b828110156127585786810182015185820160a00152810161273c565b8281111561276a57600060a084870101525b5050601f01601f1916820160a001905061278760608301846126fc565b95945050505050565b6000602082840312156127a257600080fd5b5051919050565b8183526000602080850194508260005b858110156127e75781356127cc816122ac565b6001600160a01b0316875295820195908201906001016127b9565b509495945050505050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561282457600080fd5b8260051b8083602087013760009401602001938452509192915050565b6040815260006128556040830186886127a9565b82810360208401526128688185876127f2565b979650505050505050565b8681526001600160a01b038616602082015260806040820152600061289c6080830186886127a9565b82810360608401526128af8185876127f2565b9998505050505050505050565b6003811061270c5761270c6126e6565b8581526001600160a01b03858116602083015260a08201906128f160408401876128bc565b939093166060820152608001529392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0384168152604060208201526000612787604083018486612905565b85815260006001600160a01b03808716602084015280861660408401525060806060830152612868608083018486612905565b8481526001600160a01b038416602082015260808101600284106129aa576129aa6126e6565b60408201939093526060015292915050565b8481526001600160a01b03848116602083015260808201906129e160408401866128bc565b80841660608401525095945050505050565b8481526001600160a01b038481166020830152608082019060058510612a1b57612a1b6126e6565b84604084015280841660608401525095945050505050565b60006001600160a01b03808716835280861660208401525060606040830152612a60606083018486612905565b9695505050505050565b86815260006001600160a01b038088166020840152808716604084015280861660608401525060a06080830152612aa560a083018486612905565b9897505050505050505056fea2646970667358221220cd73b65b509940334bb91e620ef353f932d88894ac4721bdf2c9427782c3ed2664736f6c63430008090033