ETH Price: $2,639.85 (+0.04%)

Contract

0xBCB25d7582D0738a77508096B05488d49181b255
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Execute210472022024-10-26 3:46:47106 days ago1729914407IN
0xBCB25d75...49181b255
0 ETH0.000653844.15299512
Execute209332252024-10-10 5:49:59122 days ago1728539399IN
0xBCB25d75...49181b255
0 ETH0.001410778.96291641
Execute209332202024-10-10 5:48:59122 days ago1728539339IN
0xBCB25d75...49181b255
0 ETH0.001426629.06361905
Add Transaction208403542024-09-27 7:05:59135 days ago1727420759IN
0xBCB25d75...49181b255
0 ETH0.0024909111.62990149
Execute205714602024-08-20 17:55:59173 days ago1724176559IN
0xBCB25d75...49181b255
0 ETH0.000265521.94652382
Add Transaction204886822024-08-09 4:34:23184 days ago1723178063IN
0xBCB25d75...49181b255
0 ETH0.000224161.06250681
Add Transaction204886682024-08-09 4:31:35184 days ago1723177895IN
0xBCB25d75...49181b255
0 ETH0.000224391.06359284
Add Transaction204886482024-08-09 4:27:23184 days ago1723177643IN
0xBCB25d75...49181b255
0 ETH0.000243331.14613768
Execute197205792024-04-23 20:48:59292 days ago1713905339IN
0xBCB25d75...49181b255
0 ETH0.0024798518.19901614
Execute197155482024-04-23 3:55:59292 days ago1713844559IN
0xBCB25d75...49181b255
0 ETH0.0013851410.16431945
Cast Vote196937462024-04-20 2:48:11295 days ago1713581291IN
0xBCB25d75...49181b255
0 ETH0.000533446.15470785
Cast Vote196937462024-04-20 2:48:11295 days ago1713581291IN
0xBCB25d75...49181b255
0 ETH0.000700686.15706686
Cast Vote196937092024-04-20 2:40:47295 days ago1713580847IN
0xBCB25d75...49181b255
0 ETH0.000709836.23747236
Cast Vote196922622024-04-19 21:48:59295 days ago1713563339IN
0xBCB25d75...49181b255
0 ETH0.000957138.03526274
Cast Vote196922592024-04-19 21:48:23295 days ago1713563303IN
0xBCB25d75...49181b255
0 ETH0.001068748.97222651
Cast Vote196892022024-04-19 11:31:35296 days ago1713526295IN
0xBCB25d75...49181b255
0 ETH0.00113649.73612307
Cast Vote196892012024-04-19 11:31:23296 days ago1713526283IN
0xBCB25d75...49181b255
0 ETH0.001043388.93923657
Cast Vote196890172024-04-19 10:54:11296 days ago1713524051IN
0xBCB25d75...49181b255
0 ETH0.000997598.37058394
Cast Vote196890082024-04-19 10:52:23296 days ago1713523943IN
0xBCB25d75...49181b255
0 ETH0.001105119.27271609
Cast Vote196881472024-04-19 7:58:23296 days ago1713513503IN
0xBCB25d75...49181b255
0 ETH0.0013640910.41087053
Cast Vote196881422024-04-19 7:57:23296 days ago1713513443IN
0xBCB25d75...49181b255
0 ETH0.0013983410.6723001
Add Transaction196878242024-04-19 6:52:59296 days ago1713509579IN
0xBCB25d75...49181b255
0 ETH0.0038201317.99309551
Add Transaction196878102024-04-19 6:50:11296 days ago1713509411IN
0xBCB25d75...49181b255
0 ETH0.003662217.20589213
Execute195877672024-04-05 6:30:11310 days ago1712298611IN
0xBCB25d75...49181b255
0 ETH0.0028077217.83055398
Execute195709512024-04-02 22:03:11312 days ago1712095391IN
0xBCB25d75...49181b255
0 ETH0.0055716235.31082376
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FraxGovernorOmega

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
shanghai EvmVersion
File 1 of 37 : FraxGovernorOmega.sol
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;

// ====================================================================
// |     ______                   _______                             |
// |    / _____________ __  __   / ____(_____  ____ _____  ________   |
// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \/ __ `/ __ \/ ___/ _ \  |
// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |
// | /_/   /_/   \__,_/_/|_|  /_/   /_/_/ /_/\__,_/_/ /_/\___/\___/   |
// |                                                                  |
// ====================================================================
// ========================= FraxGovernorOmega ========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance

// Primary Author(s)
// Jon Walch: https://github.com/jonwalch

// Contributors
// Jamie Turley: https://github.com/jyturley

// Reviewers
// Drake Evans: https://github.com/DrakeEvans
// Dennis: https://github.com/denett
// Sam Kazemian: https://github.com/samkazemian

// ====================================================================

import { FraxGovernorBase, ConstructorParams as FraxGovernorBaseParams } from "./FraxGovernorBase.sol";
import { IFraxGovernorOmega } from "./interfaces/IFraxGovernorOmega.sol";
import { Enum, ISafe } from "./interfaces/ISafe.sol";

struct ConstructorParams {
    string name;
    address veFxs;
    address veFxsVotingDelegation;
    address[] safeAllowlist;
    address[] delegateCallAllowlist;
    address payable timelockController;
    uint256 initialVotingDelay;
    uint256 initialVotingPeriod;
    uint256 initialProposalThreshold;
    uint256 quorumNumeratorValue;
    uint256 initialVotingDelayBlocks;
    uint256 initialShortCircuitNumerator;
}

/// @title FraxGovernorOmega
/// @author Jon Walch (Frax Finance) https://github.com/jonwalch
/// @notice A Governance contract with intended use as a Gnosis Safe signer. The only Safe interaction this contract does is calling GnosisSafe::approveHash().
/// @notice Supports optimistic proposals for Gnosis Safe transactions, that default to ```ProposalState.Succeeded```, through ```addTransaction()```.
contract FraxGovernorOmega is FraxGovernorBase {
    /// @notice The address of the TimelockController contract
    address public immutable TIMELOCK_CONTROLLER;

    uint256 public lastSnapshotTime;

    /// @notice Configuration and allowlist for Gnosis Safes approved for use with FraxGovernorOmega
    mapping(address safe => uint256 status) public $safeAllowlist;

    /// @notice Allowlist for external contracts allowed for use with Gnosis Safe delegatecall
    mapping(address contractAddress => uint256 status) public $delegateCallAllowlist;

    /// @notice Configuration for voting periods configured per safe. If 0, uses Omega default votingPeriod().
    mapping(address safe => uint256 votingPeriod) public $safeVotingPeriod;

    /// @notice Lookup from Gnosis Safe to nonce to corresponding transaction hash
    mapping(address safe => mapping(uint256 safeNonce => bytes32 txHash)) public $gnosisSafeToNonceToTxHash;

    /// @notice The ```AddToSafeAllowlist``` event is emitted when governance adds a safe to the allowlist
    /// @param safe The address of the Gnosis Safe added
    event AddToSafeAllowlist(address indexed safe);

    /// @notice The ```RemoveFromSafeAllowlist``` event is emitted when governance removes a safe from the allowlist
    /// @param safe The address of the Gnosis Safe removed
    event RemoveFromSafeAllowlist(address indexed safe);

    /// @notice The ```AddToDelegateCallAllowlist``` event is emitted when governance adds a contract to the allowlist
    /// @param contractAddress The address of the contract added
    event AddToDelegateCallAllowlist(address contractAddress);

    /// @notice The ```RemoveFromDelegateCallAllowlist``` event is emitted when governance removes a contract from the allowlist
    /// @param contractAddress The address of the contract removed
    event RemoveFromDelegateCallAllowlist(address contractAddress);

    /// @notice The ```SafeVotingPeriodSet``` event is emitted when governance changes the voting period for a specific safe
    /// @param safe The address of the Gnosis Safe removed
    /// @param oldSafeVotingPeriod The old value for the safe's voting period
    /// @param newSafeVotingPeriod The new value for the safe's voting period
    event SafeVotingPeriodSet(address safe, uint256 oldSafeVotingPeriod, uint256 newSafeVotingPeriod);

    /// @notice The ```TransactionProposed``` event is emitted when a Frax Team optimistic proposal is put up for voting
    /// @param safe The address of the Gnosis Safe
    /// @param nonce The nonce corresponding to the safe for this proposal
    /// @param txHash The hash of the Gnosis Safe transaction
    /// @param proposalId The proposal id in FraxGovernorOmega
    event TransactionProposed(address indexed safe, uint256 nonce, bytes32 indexed txHash, uint256 indexed proposalId);

    /// @notice The ```constructor``` function is called on deployment
    /// @param params ConstructorParams struct
    constructor(
        ConstructorParams memory params
    )
        FraxGovernorBase(
            FraxGovernorBaseParams({
                veFxs: params.veFxs,
                veFxsVotingDelegation: params.veFxsVotingDelegation,
                _name: params.name,
                initialVotingDelay: params.initialVotingDelay,
                initialVotingPeriod: params.initialVotingPeriod,
                initialProposalThreshold: params.initialProposalThreshold,
                quorumNumeratorValue: params.quorumNumeratorValue,
                initialVotingDelayBlocks: params.initialVotingDelayBlocks,
                initialShortCircuitNumerator: params.initialShortCircuitNumerator
            })
        )
    {
        TIMELOCK_CONTROLLER = params.timelockController;

        // Assume safes at deploy time are properly configured for frxGov
        _addToSafeAllowlist(params.safeAllowlist);

        _addToDelegateCallAllowlist(params.delegateCallAllowlist);
    }

    /// @notice The ```_requireOnlyTimelockController``` function checks if the caller is FraxGovernorAlpha's TimelockController
    function _requireOnlyTimelockController() internal view {
        if (msg.sender != TIMELOCK_CONTROLLER) revert IFraxGovernorOmega.NotTimelockController();
    }

    /// @notice The ```_requireSafeAllowlist``` function checks if the safe is on the allowlist
    /// @param safe The address of the Gnosis Safe
    function _requireSafeAllowlist(address safe) internal view {
        if ($safeAllowlist[safe] == 0) revert Unauthorized();
    }

    /// @notice The ```_requireNotOmegaSignature``` function checks if the provided signatures are not Omega approvehash signatures
    /// @dev Disallow the ```v == 1``` cases of ```safe.checkNSignatures()``` for Omega. This ensures that the signatures passed
    /// @dev in are from other owners and disallows the implicit signing from Omega with the ```msg.sender == currentOwner``` case.
    /// @param signatures 1 or more packed signature data ({bytes32 r}{bytes32 s}{uint8 v})
    /// @param requiredSignatures The expected amount of EOA signatures
    function _requireNotOmegaSignature(bytes memory signatures, uint256 requiredSignatures) internal view {
        uint8 v;
        bytes32 r;
        uint256 i;

        for (i = 0; i < requiredSignatures; ++i) {
            // Taken from Gnosis Safe SignatureDecoder
            // The signature format is a compact form of:
            //   {bytes32 r}{bytes32 s}{uint8 v}
            // Compact means, uint8 is not padded to 32 bytes.
            /// @solidity memory-safe-assembly
            assembly {
                let signaturePos := mul(0x41, i)
                r := mload(add(signatures, add(signaturePos, 0x20)))
                // Here we are loading the last 32 bytes, including 31 bytes
                // of 's'. There is no 'mload8' to do this.
                //
                // 'byte' is not working due to the Solidity parser, so lets
                // use the second best option, 'and'
                v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)
            }
            // If v is 1 then it is the approved hash safe.checkNSignatures() flow which automatically approves the msg.sender
            // We restrict this because we don't want omega to count as a signature, since it is the msg.sender in the later call to safe.checkNSignatures()
            if (v == 1) {
                address approver = address(uint160(uint256(r)));
                if (approver == address(this)) {
                    revert IFraxGovernorOmega.WrongSafeSignatureType();
                }
            }
        }
    }

    /// @dev Internal helper function for optimistic proposals
    function _optimisticProposalArgs(
        address safe,
        bytes32 txHash
    ) internal pure returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) {
        targets = new address[](1);
        values = new uint256[](1);
        calldatas = new bytes[](1);

        targets[0] = safe;
        values[0] = 0;
        calldatas[0] = abi.encodeWithSelector(ISafe.approveHash.selector, txHash);
    }

    /// @dev Exists solely to avoid stack too deep errors in ```addTransaction()```
    /// @return txHash Gnosis Safe transaction hash
    function _safeGetTransactionHash(
        ISafe safe,
        IFraxGovernorOmega.TxHashArgs memory args
    ) internal view returns (bytes32 txHash) {
        txHash = safe.getTransactionHash({
            to: args.to,
            value: args.value,
            data: args.data,
            operation: args.operation,
            safeTxGas: args.safeTxGas,
            baseGas: args.baseGas,
            gasPrice: args.gasPrice,
            gasToken: args.gasToken,
            refundReceiver: args.refundReceiver,
            _nonce: args._nonce
        });
    }

    /// @notice The ```propose``` function reverts when called
    /// @dev Gnosis Safe owners should sign a Gnosis Transaction and then it can be proposed using ```addTransaction()```
    /// @dev Cannot recover assets accidentally sent to this contract
    function propose(
        address[] memory, // targets
        uint256[] memory, // values
        bytes[] memory, // calldatas
        string memory // description
    ) public pure override returns (uint256) {
        revert IFraxGovernorOmega.CannotPropose();
    }

    /// @notice The ```cancel``` function reverts when called
    /// @dev Optimistic proposals can be cancelled by Frax Team using ```abortTransaction()```
    function cancel(
        address[] memory, // targets
        uint256[] memory, // values
        bytes[] memory, // calldatas
        bytes32 // descriptionHash
    ) public pure override returns (uint256) {
        revert IFraxGovernorOmega.CannotCancelOptimisticTransaction();
    }

    /// @notice The ```relay``` function reverts when called
    /// @dev This function has no use in Omega
    function relay(
        address, // target
        uint256, // value
        bytes calldata // data
    ) external payable override {
        revert IFraxGovernorOmega.CannotRelay();
    }

    /// @notice The ```addTransaction``` function creates optimistic proposals that correspond to a Gnosis Safe transaction that was initiated by the Frax Team
    /// @dev The nonce takes care of hashing a unique proposalId, so we don't need to pass a description.
    /// @param teamSafe Address of allowlisted Gnosis Safe
    /// @param args TxHashArgs of the Gnosis Safe transaction
    /// @param signatures EOA signatures for the Gnosis Safe transaction
    /// @return optimisticProposalId Proposal ID of optimistic proposal created
    function addTransaction(
        address teamSafe,
        IFraxGovernorOmega.TxHashArgs calldata args,
        bytes calldata signatures
    ) public returns (uint256 optimisticProposalId) {
        _requireSafeAllowlist(teamSafe);

        // Disallow Safe delegatecalls to contracts not on allowlist
        if (args.operation == Enum.Operation.DelegateCall && $delegateCallAllowlist[args.to] != 1) {
            revert IFraxGovernorOmega.DelegateCallNotAllowed(args.to);
        }

        ISafe safe = ISafe(teamSafe);
        // Assuming proper configuration, safe has threshold of n, where n is the number of EOA signers.
        uint256 requiredSignatures = safe.getThreshold();

        _requireNotOmegaSignature({ signatures: signatures, requiredSignatures: requiredSignatures });

        if ($gnosisSafeToNonceToTxHash[teamSafe][args._nonce] != 0) revert IFraxGovernorOmega.NonceReserved();
        if (args._nonce < safe.nonce()) revert IFraxGovernorOmega.WrongNonce();

        bytes32 txHash = _safeGetTransactionHash({ safe: safe, args: args });

        safe.checkNSignatures({
            dataHash: txHash,
            data: args.data,
            signatures: signatures,
            requiredSignatures: requiredSignatures
        });

        (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = _optimisticProposalArgs({
            safe: teamSafe,
            txHash: txHash
        });

        optimisticProposalId = _propose({
            targets: targets,
            values: values,
            calldatas: calldatas,
            description: "",
            teamSafe: teamSafe
        });

        $gnosisSafeToNonceToTxHash[teamSafe][args._nonce] = txHash;


        emit TransactionProposed({
            safe: teamSafe,
            nonce: args._nonce,
            txHash: txHash,
            proposalId: optimisticProposalId
        });
    }

    /// @notice The ```batchAddTransaction``` function is a batch version of ```addTransaction()```
    /// @param teamSafes Address of each allowlisted Gnosis Safe
    /// @param args TxHashArgs of each Gnosis Safe transaction
    /// @param signatures EOA signatures for each Gnosis Safe transaction
    /// @return optimisticProposalIds Array of optimistic Proposal IDs
    function batchAddTransaction(
        address[] calldata teamSafes,
        IFraxGovernorOmega.TxHashArgs[] calldata args,
        bytes[] calldata signatures
    ) external returns (uint256[] memory optimisticProposalIds) {
        if (teamSafes.length != args.length || teamSafes.length != signatures.length) {
            revert IFraxGovernorOmega.BadBatchArgs();
        }

        optimisticProposalIds = new uint256[](teamSafes.length);

        for (uint256 i = 0; i < teamSafes.length; ++i) {
            optimisticProposalIds[i] = addTransaction({
                teamSafe: teamSafes[i],
                args: args[i],
                signatures: signatures[i]
            });
        }
    }

    /// @notice The ```rejectTransaction``` function is called when an optimistic proposal is Defeated. It calls ```safe.approveHash()``` for a 0 eth transfer with the provided ```nonce```
    /// @param teamSafe Address of allowlisted Gnosis Safe
    /// @param nonce Gnosis Safe nonce corresponding to an optimistic proposal
    function rejectTransaction(address teamSafe, uint256 nonce) external {
        bytes32 originalTxHash = $gnosisSafeToNonceToTxHash[teamSafe][nonce];

        (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = _optimisticProposalArgs({
            safe: teamSafe,
            txHash: originalTxHash
        });
        if (
            state(
                hashProposal({
                    targets: targets,
                    values: values,
                    calldatas: calldatas,
                    descriptionHash: keccak256(bytes(""))
                })
            ) != ProposalState.Defeated
        ) {
            revert IFraxGovernorOmega.WrongProposalState();
        }

        ISafe safe = ISafe(teamSafe);
        bytes32 rejectTxHash = _safeGetTransactionHash({
            safe: safe,
            args: IFraxGovernorOmega.TxHashArgs({
                to: teamSafe,
                value: 0,
                data: "",
                operation: Enum.Operation.Call,
                safeTxGas: 0,
                baseGas: 0,
                gasPrice: 0,
                gasToken: address(0),
                refundReceiver: payable(address(0)),
                _nonce: nonce
            })
        });

        if (safe.approvedHashes({ signer: address(this), txHash: rejectTxHash }) == 1) {
            revert IFraxGovernorOmega.TransactionAlreadyApproved(rejectTxHash);
        }

        // Omega approves 0 eth transfer
        safe.approveHash(rejectTxHash);
    }

    /// @notice The ```abortTransaction``` function is called when the Frax Team no longer wants to execute a transaction they created in the Gnosis Safe UI
    /// @notice This can be before or after the transaction is added using ```addTransaction()```. It signs a 0 eth transfer for the current nonce
    /// @notice as long as the 0 eth transfer has the configured required amount of EOA signatures.
    /// @dev Only works when the transaction to abort is the first in the Gnosis Safe queue (current nonce)
    /// @dev Only way to cancel an optimistic proposal
    /// @param teamSafe Address of allowlisted Gnosis Safe
    /// @param signatures EOA signatures for a 0 ether transfer Gnosis Safe transaction with the current nonce
    function abortTransaction(address teamSafe, bytes calldata signatures) external {
        _requireSafeAllowlist(teamSafe);
        ISafe safe = ISafe(teamSafe);
        // Assuming proper configuration, safe has threshold of n, where n is the number of EOA signers.
        uint256 requiredSignatures = safe.getThreshold();

        _requireNotOmegaSignature({ signatures: signatures, requiredSignatures: requiredSignatures });

        uint256 nonce = safe.nonce();

        bytes32 rejectTxHash = safe.getTransactionHash({
            to: teamSafe,
            value: 0,
            data: "",
            operation: Enum.Operation.Call,
            safeTxGas: 0,
            baseGas: 0,
            gasPrice: 0,
            gasToken: address(0),
            refundReceiver: payable(address(0)),
            _nonce: nonce
        });

        // Check validity of provided 3 signatures for generated txHash
        safe.checkNSignatures({
            dataHash: rejectTxHash,
            data: "",
            signatures: signatures,
            requiredSignatures: requiredSignatures
        });

        bytes32 originalTxHash = $gnosisSafeToNonceToTxHash[teamSafe][nonce];
        uint256 abortedProposalId;

        // If safe/nonce tuple already had addTransaction() called for it
        if (originalTxHash != 0) {
            (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = _optimisticProposalArgs({
                safe: teamSafe,
                txHash: originalTxHash
            });

            abortedProposalId = hashProposal({
                targets: targets,
                values: values,
                calldatas: calldatas,
                descriptionHash: keccak256(bytes(""))
            });
            ProposalState proposalState = state(abortedProposalId);

            if (proposalState == ProposalState.Canceled) {
                revert IFraxGovernorOmega.ProposalAlreadyCanceled();
            }

            proposals[abortedProposalId].canceled = true;
            emit ProposalCanceled(abortedProposalId);
        }

        // Omega approves 0 eth transfer
        safe.approveHash(rejectTxHash);
    }

    /// @notice The ```setVotingDelay``` function is called by Alpha governance to change the amount of time before the voting snapshot
    /// @dev Only callable by FraxGovernorAlpha governance
    /// @param newVotingDelay New voting delay in seconds
    function setVotingDelay(uint256 newVotingDelay) public override {
        _requireOnlyTimelockController();
        _setVotingDelay(newVotingDelay);
    }

    /// @notice The ```setVotingDelayBlocks``` function is called by Alpha governance to change the amount of blocks before the voting snapshot
    /// @dev Only callable by FraxGovernorAlpha governance
    /// @param newVotingDelayBlocks New voting delay in blocks
    function setVotingDelayBlocks(uint256 newVotingDelayBlocks) external {
        _requireOnlyTimelockController();
        _setVotingDelayBlocks(newVotingDelayBlocks);
    }

    /// @notice The ```setVotingPeriod``` function is called by Alpha governance to change the amount of time a proposal can be voted on
    /// @dev Only callable by FraxGovernorAlpha governance
    /// @param newVotingPeriod New voting period in seconds
    function setVotingPeriod(uint256 newVotingPeriod) public override {
        _requireOnlyTimelockController();
        _setVotingPeriod(newVotingPeriod);
    }

    /// @notice The ```setProposalThreshold``` function is called by Alpha governance to change the amount of veFXS a proposer needs to call propose()
    /// @notice proposalThreshold calculation includes all weight delegated to the proposer
    /// @dev Only callable by FraxGovernorAlpha governance
    /// @param newProposalThreshold New voting period in amount of veFXS
    function setProposalThreshold(uint256 newProposalThreshold) public override {
        _requireOnlyTimelockController();
        _setProposalThreshold(newProposalThreshold);
    }

    /// @notice The ```updateQuorumNumerator``` function is called by Alpha governance to change the numerator / 100 needed for quorum
    /// @dev Only callable by FraxGovernorAlpha governance
    /// @param newQuorumNumerator Number expressed as x/100 (percentage)
    function updateQuorumNumerator(uint256 newQuorumNumerator) external override {
        _requireOnlyTimelockController();
        _updateQuorumNumerator(newQuorumNumerator);
    }

    /// @notice The ```setVeFxsVotingDelegation``` function is called by Alpha governance to change the voting weight ```IERC5805``` contract
    /// @dev Only callable by FraxGovernorAlpha governance
    /// @param veFxsVotingDelegation New ```IERC5805``` veFxsVotingDelegation contract address
    function setVeFxsVotingDelegation(address veFxsVotingDelegation) external {
        _requireOnlyTimelockController();
        _setVeFxsVotingDelegation(veFxsVotingDelegation);
    }

    /// @notice The ```updateShortCircuitNumerator``` function is called by Alpha governance to change the short circuit numerator
    /// @dev Only callable by FraxGovernorAlpha governance
    /// @param newShortCircuitNumerator Number expressed as x/100 (percentage)
    function updateShortCircuitNumerator(uint256 newShortCircuitNumerator) external {
        _requireOnlyTimelockController();
        _updateShortCircuitNumerator(newShortCircuitNumerator);
    }

    function _addToSafeAllowlist(address[] memory safes) internal {
        for (uint256 i = 0; i < safes.length; ++i) {
            if ($safeAllowlist[safes[i]] == 1) revert IFraxGovernorOmega.AlreadyOnSafeAllowlist(safes[i]);
            $safeAllowlist[safes[i]] = 1;
            emit AddToSafeAllowlist(safes[i]);
        }
    }

    /// @notice The ```addToSafeAllowlist``` function is called by Alpha governance to allowlist safes for addTransaction()
    /// @notice Safes are expected to be properly configured before calling this function
    /// @notice Proper configuration entails having: the FraxGuard set, FraxGovernorOmega set as a signer and FraxGovernorAlpha's TimelockController as a Module
    /// @param safes Array of safe addresses to allowlist
    function addToSafeAllowlist(address[] calldata safes) external {
        _requireOnlyTimelockController();
        _addToSafeAllowlist(safes);
    }

    /// @notice The ```removeSafesFromAllowlist``` function is called by Alpha governance to remove safes from the allowlist
    /// @dev See TestFraxGovernorUpgrade.t.sol for upgrade path
    /// @param safes Array of safe addresses to remove from allowlist
    function removeFromSafeAllowlist(address[] calldata safes) external {
        _requireOnlyTimelockController();

        for (uint256 i = 0; i < safes.length; ++i) {
            if ($safeAllowlist[safes[i]] == 0) revert IFraxGovernorOmega.NotOnSafeAllowlist(safes[i]);
            delete $safeAllowlist[safes[i]];
            emit RemoveFromSafeAllowlist(safes[i]);
        }
    }

    function _addToDelegateCallAllowlist(address[] memory contracts) internal {
        for (uint256 i = 0; i < contracts.length; ++i) {
            if ($delegateCallAllowlist[contracts[i]] == 1) {
                revert IFraxGovernorOmega.AlreadyOnDelegateCallAllowlist(contracts[i]);
            }
            $delegateCallAllowlist[contracts[i]] = 1;
            emit AddToDelegateCallAllowlist(contracts[i]);
        }
    }

    /// @notice The ```addToDelegateCallAllowlist``` function is called by Alpha governance to allowlist contracts for delegatecall with addTransaction()
    /// @param contracts Array of contract addresses to allowlist
    function addToDelegateCallAllowlist(address[] calldata contracts) external {
        _requireOnlyTimelockController();
        _addToDelegateCallAllowlist(contracts);
    }

    /// @notice The ```removeFromDelegateCallAllowlist``` function is called by Alpha governance to remove contracts from the allowlist
    /// @dev See TestFraxGovernorUpgrade.t.sol for upgrade path
    /// @param contracts Array of contract addresses to remove from allowlist
    function removeFromDelegateCallAllowlist(address[] calldata contracts) external {
        _requireOnlyTimelockController();

        for (uint256 i = 0; i < contracts.length; ++i) {
            if ($delegateCallAllowlist[contracts[i]] == 0) {
                revert IFraxGovernorOmega.NotOnDelegateCallAllowlist(contracts[i]);
            }
            delete $delegateCallAllowlist[contracts[i]];
            emit RemoveFromDelegateCallAllowlist(contracts[i]);
        }
    }

    /// @notice The ```setSafeVotingPeriod``` function is called by Alpha governance to change the short circuit numerator
    /// @dev Only callable by FraxGovernorAlpha governance
    /// @param safe The Gnosis safe to configure
    /// @param newSafeVotingPeriod The voting period specific to safe, set to 0 to go back to Omega's default voting period
    function setSafeVotingPeriod(address safe, uint256 newSafeVotingPeriod) external {
        _requireOnlyTimelockController();

        uint256 safeVotingPeriod = $safeVotingPeriod[safe];
        if (safeVotingPeriod == newSafeVotingPeriod) revert IFraxGovernorOmega.SameSafeVotingPeriod();
        $safeVotingPeriod[safe] = newSafeVotingPeriod;
        emit SafeVotingPeriodSet({
            safe: safe,
            oldSafeVotingPeriod: safeVotingPeriod,
            newSafeVotingPeriod: newSafeVotingPeriod
        });
    }

    /// @notice The ```_optimisticVoteDefeated``` function is called by state() to check if an optimistic proposal was defeated
    /// @param proposalId Proposal ID
    /// @return Whether the optimistic proposal was defeated or not
    function _optimisticVoteDefeated(uint256 proposalId) internal view returns (bool) {
        (uint256 againstVoteWeight, uint256 forVoteWeight, ) = proposalVotes(proposalId);
        if (againstVoteWeight == 0 && forVoteWeight == 0) {
            return false;
        } else {
            return forVoteWeight <= againstVoteWeight;
        }
    }

    /// @notice The ```_propose``` function is similar to OpenZeppelin's propose() with minor changes.
    /// @dev Changes include: Removal of proposal threshold check, ProposalCore struct packing, setting $snapshotToTotalVeFxsSupply, and configurable voting periods per safe
    /// @return proposalId Proposal ID
    function _propose(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        string memory description,
        address teamSafe
    ) internal returns (uint256 proposalId) {
        proposalId = hashProposal({
            targets: targets,
            values: values,
            calldatas: calldatas,
            descriptionHash: keccak256(bytes(description))
        });

        require(targets.length == values.length, "Governor: invalid proposal length");
        require(targets.length == calldatas.length, "Governor: invalid proposal length");
        require(targets.length > 0, "Governor: empty proposal");
        require(proposals[proposalId].voteStart == 0, "Governor: proposal already exists");

        address proposer = msg.sender;
        uint256 snapshot = clock() + votingDelay();
        uint256 deadline;

        try VE_FXS.newSnapshotTime(snapshot) {} catch {}
        
        lastSnapshotTime = snapshot;

        {
            uint256 safeVotingPeriod = $safeVotingPeriod[teamSafe];
            // If configured, use safe's voting period. Otherwise use default Omega value.
            uint256 votingPeriod = safeVotingPeriod != 0 ? safeVotingPeriod : votingPeriod();
            deadline = snapshot + votingPeriod;
        }

        proposals[proposalId] = ProposalCore({
            proposer: proposer,
            voteStart: uint40(snapshot),
            voteEnd: uint40(deadline),
            executed: false,
            canceled: false
        });

        // Save the block number of the snapshot, so it can be later used to fetch the total outstanding supply
        // of veFXS. We did this so we can still support quorum(timestamp), without breaking the OZ standard.
        // The underlying issue is that VE_FXS.totalSupply(timestamp) doesn't work for historical values, so we must
        // use VE_FXS.totalSupply(), or VE_FXS.totalSupplyAt(blockNumber).
        $snapshotTimestampToSnapshotBlockNumber[snapshot] = block.number + $votingDelayBlocks;

        emit ProposalCreated(
            proposalId,
            proposer,
            targets,
            values,
            new string[](targets.length),
            calldatas,
            snapshot,
            deadline,
            description
        );
    }

    /// @notice The ```state``` function is similar to OpenZeppelin's propose() with minor changes
    /// @dev Changes include: support for early success or failure using short circuit and optimistic proposals
    /// @param proposalId Proposal ID
    /// @return proposalState ProposalState enum
    function state(uint256 proposalId) public view override returns (ProposalState proposalState) {
        ProposalCore storage $proposal = proposals[proposalId];

        if ($proposal.executed) {
            return ProposalState.Executed;
        }

        if ($proposal.canceled) {
            return ProposalState.Canceled;
        }

        uint256 snapshot = proposalSnapshot(proposalId);

        if (snapshot == 0) {
            revert("Governor: unknown proposal id");
        }

        uint256 currentTimepoint = clock();
        if (snapshot >= currentTimepoint || $snapshotTimestampToSnapshotBlockNumber[snapshot] >= block.number) {
            return ProposalState.Pending;
        }

        // Allow early execution when overwhelming majority
        if (_shortCircuitFor(proposalId)) {
            return ProposalState.Succeeded;
        } else if (_shortCircuitAgainst(proposalId)) {
            return ProposalState.Defeated;
        }

        uint256 deadline = proposalDeadline(proposalId);

        if (deadline >= currentTimepoint) {
            return ProposalState.Active;
        }

        // Optimistic proposal with addTransaction()
        if (_quorumReached(proposalId) && _optimisticVoteDefeated(proposalId)) {
            return ProposalState.Defeated;
        } else {
            return ProposalState.Succeeded;
        }
    }
}

File 2 of 37 : FraxGovernorBase.sol
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;

// ====================================================================
// |     ______                   _______                             |
// |    / _____________ __  __   / ____(_____  ____ _____  ________   |
// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \/ __ `/ __ \/ ___/ _ \  |
// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |
// | /_/   /_/   \__,_/_/|_|  /_/   /_/_/ /_/\__,_/_/ /_/\___/\___/   |
// |                                                                  |
// ====================================================================
// ========================= FraxGovernorBase =========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance

// Primary Author(s)
// Jon Walch: https://github.com/jonwalch

// Reviewers
// Drake Evans: https://github.com/DrakeEvans
// Dennis: https://github.com/denett
// Sam Kazemian: https://github.com/samkazemian

// ====================================================================

import { Checkpoints } from "@openzeppelin/contracts/utils/Checkpoints.sol";
import { IERC5805 } from "@openzeppelin/contracts/interfaces/IERC5805.sol";
import { Governor, IGovernor } from "./governor/Governor.sol";
import { GovernorCountingFractional, SafeCast } from "./governor/GovernorCountingFractional.sol";
import { GovernorSettings } from "./governor/GovernorSettings.sol";
import { GovernorVotes, IVotes } from "./governor/GovernorVotesQuorumFraction.sol";
import { GovernorVotesQuorumFraction } from "./governor/GovernorVotesQuorumFraction.sol";
import { IVeFxs } from "./interfaces/IVeFxs.sol";

struct ConstructorParams {
    address veFxs;
    address veFxsVotingDelegation;
    string _name;
    uint256 initialVotingDelay;
    uint256 initialVotingPeriod;
    uint256 initialProposalThreshold;
    uint256 quorumNumeratorValue;
    uint256 initialVotingDelayBlocks;
    uint256 initialShortCircuitNumerator;
}

/// @title FraxGovernorBase
/// @author Jon Walch (Frax Finance) https://github.com/jonwalch
/// @notice An abstract contract which contains the shared core logic and storage for FraxGovernorAlpha and FraxGovernorOmega
abstract contract FraxGovernorBase is GovernorSettings, GovernorVotesQuorumFraction, GovernorCountingFractional {
    using SafeCast for *;
    using Checkpoints for Checkpoints.Trace224;

    /// @notice Voting delay in number of blocks
    /// @dev only used to look up total veFXS supply on the VE_FXS contract
    uint256 public $votingDelayBlocks;

    /// @notice Address of the veFXS contract
    IVeFxs public immutable VE_FXS;

    /// @notice Checkpoints for short circuit numerator mirroring _quorumNumeratorHistory from GovernorVotesQuorumFraction.sol
    Checkpoints.Trace224 private _$shortCircuitNumeratorHistory;

    /// @notice Lookup from snapshot timestamp to corresponding snapshot block number, used for quorum
    mapping(uint256 snapshot => uint256 blockNumber) public $snapshotTimestampToSnapshotBlockNumber;

    /// @notice The ```ShortCircuitNumeratorUpdated``` event is emitted when governance changes the short circuit numerator
    /// @param oldShortCircuitNumerator The old short circuit numerator
    /// @param newShortCircuitNumerator The new contract address
    event ShortCircuitNumeratorUpdated(uint256 oldShortCircuitNumerator, uint256 newShortCircuitNumerator);

    /// @notice The ```VeFxsVotingDelegationSet``` event is emitted when governance changes the voting weight IERC5805 contract
    /// @param oldVotingDelegation The old contract address
    /// @param newVotingDelegation The new contract address
    event VeFxsVotingDelegationSet(address oldVotingDelegation, address newVotingDelegation);

    /// @notice The ```VotingDelayBlocksSet``` event is emitted when governance changes the voting delay in blocks
    /// @param oldVotingDelayBlocks The old short circuit numerator
    /// @param newVotingDelayBlocks The new contract address
    event VotingDelayBlocksSet(uint256 oldVotingDelayBlocks, uint256 newVotingDelayBlocks);

    /// @notice The ```constructor``` function is called on deployment
    /// @param params ConstructorParams struct
    constructor(
        ConstructorParams memory params
    )
        Governor(params._name)
        GovernorSettings(params.initialVotingDelay, params.initialVotingPeriod, params.initialProposalThreshold)
        GovernorVotes(IVotes(params.veFxsVotingDelegation))
        GovernorVotesQuorumFraction(params.quorumNumeratorValue)
    {
        VE_FXS = IVeFxs(params.veFxs);
        _updateShortCircuitNumerator(params.initialShortCircuitNumerator);
        _setVotingDelayBlocks(params.initialVotingDelayBlocks);

        // Emit manually because initial setting of `token` is in GovernorVotes' constructor
        emit VeFxsVotingDelegationSet({
            oldVotingDelegation: address(0),
            newVotingDelegation: params.veFxsVotingDelegation
        });
    }

    /// @notice The ```_requireSenderAboveProposalThreshold``` function checks if the proposer has sufficient voting weight
    function _requireSenderAboveProposalThreshold() internal view {
        if (_getVotes(msg.sender, block.timestamp - 1, "") < proposalThreshold()) {
            revert SenderVotingWeightBelowProposalThreshold();
        }
    }

    /// @notice The ```_setVotingDelayBlocks``` function is called by governance to change the voting delay in blocks
    /// @notice This must be changed in tandem with ```votingDelay``` to properly set quorum values
    /// @param votingDelayBlocks New voting delay in blocks value
    function _setVotingDelayBlocks(uint256 votingDelayBlocks) internal {
        uint256 oldVotingDelayBlocks = $votingDelayBlocks;
        $votingDelayBlocks = votingDelayBlocks;
        emit VotingDelayBlocksSet({
            oldVotingDelayBlocks: oldVotingDelayBlocks,
            newVotingDelayBlocks: votingDelayBlocks
        });
    }

    /// @notice The ```_setVeFxsVotingDelegation``` function is called by governance to change the voting weight IERC5805 contract
    /// @param veFxsVotingDelegation new IERC5805 VeFxsVotingDelegation contract address
    function _setVeFxsVotingDelegation(address veFxsVotingDelegation) internal {
        address oldVeFxsVotingDelegation = address(token);
        token = IERC5805(veFxsVotingDelegation);
        emit VeFxsVotingDelegationSet({
            oldVotingDelegation: oldVeFxsVotingDelegation,
            newVotingDelegation: veFxsVotingDelegation
        });
    }

    /// @notice The ```_quorumReached``` function is called by state() to check for early proposal success
    /// @param proposalId Proposal ID
    /// @return isQuorum Represents if quorum was reached or not
    function _quorumReached(
        uint256 proposalId
    ) internal view override(Governor, GovernorCountingFractional) returns (bool isQuorum) {
        (uint256 againstVoteWeight, uint256 forVoteWeight, uint256 abstainVoteWeight) = proposalVotes(proposalId);
        uint256 larger = againstVoteWeight > forVoteWeight ? againstVoteWeight : forVoteWeight;

        uint256 proposalVoteStart = proposalSnapshot(proposalId);
        isQuorum = quorum(proposalVoteStart) <= larger + abstainVoteWeight;
    }

    /// @notice The ```_shortCircuitFor``` function is called by state() to check for early proposal success
    /// @param proposalId Proposal ID
    /// @return isShortCircuitFor Represents if short circuit threshold for votes were reached or not
    function _shortCircuitFor(uint256 proposalId) internal view returns (bool isShortCircuitFor) {
        (, uint256 forVoteWeight, ) = proposalVotes(proposalId);

        uint256 proposalVoteStart = proposalSnapshot(proposalId);
        isShortCircuitFor = forVoteWeight > shortCircuitThreshold(proposalVoteStart);
    }

    /// @notice The ```_shortCircuitAgainst``` function is called by state() to check for early proposal failure
    /// @param proposalId Proposal ID
    /// @return isShortCircuitAgainst Represents if short circuit threshold against votes were reached or not
    function _shortCircuitAgainst(uint256 proposalId) internal view returns (bool isShortCircuitAgainst) {
        (uint256 againstVoteWeight, , ) = proposalVotes(proposalId);

        uint256 proposalVoteStart = proposalSnapshot(proposalId);
        isShortCircuitAgainst = againstVoteWeight > shortCircuitThreshold(proposalVoteStart);
    }

    /// @notice The ```_updateShortCircuitNumerator``` function is called by governance to change the short circuit numerator
    /// @dev Mirrors ```GovernorVotesQuorumFraction::_updateQuorumNumerator(uint256 newQuorumNumerator)```
    /// @param newShortCircuitNumerator New short circuit numerator value
    function _updateShortCircuitNumerator(uint256 newShortCircuitNumerator) internal {
        // Numerator must be less than or equal to denominator
        if (newShortCircuitNumerator > quorumDenominator()) {
            revert ShortCircuitNumeratorGreaterThanQuorumDenominator();
        }

        uint256 oldShortCircuitNumerator = shortCircuitNumerator();

        // Set new quorum for future proposals
        _$shortCircuitNumeratorHistory.push(SafeCast.toUint32(clock()), SafeCast.toUint224(newShortCircuitNumerator));

        emit ShortCircuitNumeratorUpdated({
            oldShortCircuitNumerator: oldShortCircuitNumerator,
            newShortCircuitNumerator: newShortCircuitNumerator
        });
    }

    function COUNTING_MODE() public pure override(IGovernor, GovernorCountingFractional) returns (string memory) {
        return "support=bravo&quorum=against,abstain&quorum=for,abstain&params=fractional";
    }

    /// @notice The ```shortCircuitNumerator``` function returns the latest short circuit numerator
    /// @dev Mirrors ```GovernorVotesQuorumFraction::quorumNumerator()```
    /// @return latestShortCircuitNumerator The short circuit numerator
    function shortCircuitNumerator() public view returns (uint256 latestShortCircuitNumerator) {
        latestShortCircuitNumerator = _$shortCircuitNumeratorHistory.latest();
    }

    /// @notice The ```shortCircuitNumerator``` function returns the short circuit numerator at ```timepoint```
    /// @dev Mirrors ```GovernorVotesQuorumFraction::quorumNumerator(uint256 timepoint)```
    /// @param timepoint A block.timestamp
    /// @return shortCircuitNumeratorAtTimepoint Short circuit numerator
    function shortCircuitNumerator(uint256 timepoint) public view returns (uint256 shortCircuitNumeratorAtTimepoint) {
        // If history is empty, fallback to old storage
        uint256 length = _$shortCircuitNumeratorHistory._checkpoints.length;

        // Optimistic search, check the latest checkpoint
        Checkpoints.Checkpoint224 memory latest = _$shortCircuitNumeratorHistory._checkpoints[length - 1];
        if (latest._key <= timepoint) {
            shortCircuitNumeratorAtTimepoint = latest._value;
            return shortCircuitNumeratorAtTimepoint;
        }

        // Otherwise, do the binary search
        shortCircuitNumeratorAtTimepoint = _$shortCircuitNumeratorHistory.upperLookupRecent(
            SafeCast.toUint32(timepoint)
        );
    }

    /// @notice The ```shortCircuitThreshold``` function returns the latest short circuit numerator
    /// @dev Only supports historical quorum values for proposals that actually exist at ```timepoint```
    /// @param timepoint A block.timestamp corresponding to a proposal snapshot
    /// @return shortCircuitThresholdAtTimepoint Total voting weight needed for short circuit to succeed
    function shortCircuitThreshold(uint256 timepoint) public view returns (uint256 shortCircuitThresholdAtTimepoint) {
        // uint256 snapshotBlockNumber = $snapshotTimestampToSnapshotBlockNumber[timepoint];
        if (timepoint == 0 || timepoint >= block.timestamp) revert InvalidTimepoint();

        shortCircuitThresholdAtTimepoint =
            (VE_FXS.totalSupplyAt(timepoint) * shortCircuitNumerator(timepoint)) /
            quorumDenominator();
    }

    /// @notice The ```quorum``` function returns the quorum value at ```timepoint```
    /// @dev Only supports historical quorum values for proposals that actually exist at ```timepoint```
    /// @param timepoint A block.timestamp corresponding to a proposal snapshot
    /// @return quorumAtTimepoint Quorum value at ```timepoint```
    function quorum(
        uint256 timepoint
    ) public view override(IGovernor, GovernorVotesQuorumFraction) returns (uint256 quorumAtTimepoint) {
        // uint256 snapshotBlockNumber = $snapshotTimestampToSnapshotBlockNumber[timepoint];
        if (timepoint == 0 || timepoint >= block.timestamp) revert InvalidTimepoint();

        quorumAtTimepoint =
            (VE_FXS.totalSupplyAt(timepoint) * quorumNumerator(timepoint)) /
            quorumDenominator();
    }

    /// @notice The ```bulkCastVote``` function allows the caller to vote on many proposals at once
    /// @param proposalId An array of proposalId
    /// @param support An array of support
    function bulkCastVote(uint256[] calldata proposalId, uint8[] calldata support) external {
        uint256 proposalIdsLength = proposalId.length;
        if (proposalIdsLength != support.length) {
            revert ParamLengthsNotEqual();
        }

        for (uint256 i = 0; i < proposalIdsLength; ++i) {
            castVote({ proposalId: proposalId[i], support: support[i] });
        }
    }

    /// Boilerplate overrides

    /**
     * @notice Cast a vote with a reason and additional encoded parameters using
     * the user's cryptographic signature.
     *
     * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length
     * of params.
     *
     * @dev If casting a fractional vote via `params`, the voter's current nonce
     * must be appended to the `params` as the last 16 bytes and included in the
     * signature. I.e., the params used when constructing the signature would be:
     *
     *   abi.encodePacked(againstVotes, forVotes, abstainVotes, nonce)
     *
     * See {fractionalVoteNonce} and {_castVote} for more information.
     */
    function castVoteWithReasonAndParamsBySig(
        uint256 proposalId,
        uint8 support,
        string calldata reason,
        bytes memory params,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override(Governor, GovernorCountingFractional) returns (uint256) {
        return
            GovernorCountingFractional.castVoteWithReasonAndParamsBySig({
                proposalId: proposalId,
                support: support,
                reason: reason,
                params: params,
                v: v,
                r: r,
                s: s
            });
    }

    /**
     * @dev See {Governor-proposalThreshold}.
     */
    function proposalThreshold() public view virtual override(Governor, GovernorSettings) returns (uint256) {
        return GovernorSettings.proposalThreshold();
    }

    error InvalidTimepoint();
    error ParamLengthsNotEqual();
    error SenderVotingWeightBelowProposalThreshold();
    error ShortCircuitNumeratorGreaterThanQuorumDenominator();
    error Unauthorized();
}

File 3 of 37 : IFraxGovernorOmega.sol
// SPDX-License-Identifier: ISC
pragma solidity >=0.8.19;

import { Enum } from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";

interface IFraxGovernorOmega {
    struct TxHashArgs {
        address to;
        uint256 value;
        bytes data;
        Enum.Operation operation;
        uint256 safeTxGas;
        uint256 baseGas;
        uint256 gasPrice;
        address gasToken;
        address refundReceiver;
        uint256 _nonce;
    }

    function $delegateCallAllowlist(address contractAddress) external view returns (uint256 status);

    function $gnosisSafeToNonceToTxHash(address safe, uint256 safeNonce) external view returns (bytes32 txHash);

    function $safeAllowlist(address safe) external view returns (uint256 status);

    function $safeVotingPeriod(address safe) external view returns (uint256 votingPeriod);

    function $snapshotTimestampToSnapshotBlockNumber(uint256 snapshot) external view returns (uint256 blockNumber);

    function $votingDelayBlocks() external view returns (uint256);

    function BALLOT_TYPEHASH() external view returns (bytes32);

    function CLOCK_MODE() external view returns (string memory);

    function COUNTING_MODE() external pure returns (string memory);

    function EXTENDED_BALLOT_TYPEHASH() external view returns (bytes32);

    function TIMELOCK_CONTROLLER() external view returns (address);

    function VE_FXS() external view returns (address);

    function abortTransaction(address teamSafe, bytes memory signatures) external;

    function addToDelegateCallAllowlist(address[] memory contracts) external;

    function addToSafeAllowlist(address[] memory safes) external;

    function addTransaction(
        address teamSafe,
        TxHashArgs memory args,
        bytes memory signatures
    ) external returns (uint256 optimisticProposalId);

    function batchAddTransaction(
        address[] memory teamSafes,
        TxHashArgs[] memory args,
        bytes[] memory signatures
    ) external returns (uint256[] memory optimisticProposalIds);

    function bulkCastVote(uint256[] memory proposalId, uint8[] memory support) external;

    function cancel(address[] memory, uint256[] memory, bytes[] memory, bytes32) external pure returns (uint256);

    function castVote(uint256 proposalId, uint8 support) external returns (uint256);

    function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external returns (uint256);

    function castVoteWithReason(uint256 proposalId, uint8 support, string memory reason) external returns (uint256);

    function castVoteWithReasonAndParams(
        uint256 proposalId,
        uint8 support,
        string memory reason,
        bytes memory params
    ) external returns (uint256);

    function castVoteWithReasonAndParamsBySig(
        uint256 proposalId,
        uint8 support,
        string memory reason,
        bytes memory params,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256);

    function clock() external view returns (uint48);

    function eip712Domain()
        external
        view
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        );

    function execute(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) external payable returns (uint256);

    function fractionalVoteNonce(address) external view returns (uint128);

    function getVotes(address account, uint256 timepoint) external view returns (uint256);

    function getVotesWithParams(
        address account,
        uint256 timepoint,
        bytes memory params
    ) external view returns (uint256);

    function hasVoted(uint256 proposalId, address account) external view returns (bool);

    function hashProposal(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) external pure returns (uint256);

    function name() external view returns (string memory);

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) external returns (bytes4);

    function onERC1155Received(address, address, uint256, uint256, bytes memory) external returns (bytes4);

    function onERC721Received(address, address, uint256, bytes memory) external returns (bytes4);

    function proposalDeadline(uint256 proposalId) external view returns (uint256);

    function proposalProposer(uint256 proposalId) external view returns (address);

    function proposalSnapshot(uint256 proposalId) external view returns (uint256);

    function proposalThreshold() external view returns (uint256);

    function proposalVotes(
        uint256 proposalId
    ) external view returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes);

    function proposals(
        uint256
    ) external view returns (address proposer, uint40 voteStart, uint40 voteEnd, bool executed, bool canceled);

    function propose(address[] memory, uint256[] memory, bytes[] memory, string memory) external pure returns (uint256);

    function quorum(uint256 timepoint) external view returns (uint256 quorumAtTimepoint);

    function quorumDenominator() external view returns (uint256);

    function quorumNumerator(uint256 timepoint) external view returns (uint256);

    function quorumNumerator() external view returns (uint256);

    function rejectTransaction(address teamSafe, uint256 nonce) external;

    function relay(address, uint256, bytes memory) external payable;

    function removeFromDelegateCallAllowlist(address[] memory contracts) external;

    function removeFromSafeAllowlist(address[] memory safes) external;

    function setProposalThreshold(uint256 newProposalThreshold) external;

    function setSafeVotingPeriod(address safe, uint256 newSafeVotingPeriod) external;

    function setVeFxsVotingDelegation(address veFxsVotingDelegation) external;

    function setVotingDelay(uint256 newVotingDelay) external;

    function setVotingDelayBlocks(uint256 newVotingDelayBlocks) external;

    function setVotingPeriod(uint256 newVotingPeriod) external;

    function shortCircuitNumerator() external view returns (uint256 latestShortCircuitNumerator);

    function shortCircuitNumerator(uint256 timepoint) external view returns (uint256 shortCircuitNumeratorAtTimepoint);

    function shortCircuitThreshold(uint256 timepoint) external view returns (uint256 shortCircuitThresholdAtTimepoint);

    function state(uint256 proposalId) external view returns (uint8 proposalState);

    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    function token() external view returns (address);

    function updateQuorumNumerator(uint256 newQuorumNumerator) external;

    function updateShortCircuitNumerator(uint256 newShortCircuitNumerator) external;

    function version() external view returns (string memory);

    function voteWeightCast(uint256 proposalId, address account) external view returns (uint128);

    function votingDelay() external view returns (uint256);

    function votingPeriod() external view returns (uint256);

    function lastSnapshotTime() external view returns (uint256);
    
    error AlreadyOnDelegateCallAllowlist(address contractAddress);
    error AlreadyOnSafeAllowlist(address safe);
    error BadBatchArgs();
    error CannotCancelOptimisticTransaction();
    error CannotPropose();
    error CannotRelay();
    error DelegateCallNotAllowed(address to);
    error DisallowedTarget(address target);
    error NonceReserved();
    error NotOnDelegateCallAllowlist(address contractAddress);
    error NotOnSafeAllowlist(address safe);
    error NotTimelockController();
    error ProposalAlreadyCanceled();
    error SameSafeVotingPeriod();
    error TransactionAlreadyApproved(bytes32 txHash);
    error WrongNonce();
    error WrongProposalState();
    error WrongSafeSignatureType();
}

File 4 of 37 : ISafe.sol
// SPDX-License-Identifier: ISC
pragma solidity >=0.8.19;

import { Enum } from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";

interface ISafe {
    // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners
    function approvedHashes(address signer, bytes32 txHash) external returns (uint256);

    function nonce() external returns (uint256);

    /**
     * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.
     * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.
     */
    function approveHash(bytes32 hashToApprove) external;

    function isOwner(address) external returns (bool);

    function getThreshold() external view returns (uint256);

    /// @dev Returns hash to be signed by owners.
    /// @param to Destination address.
    /// @param value Ether value.
    /// @param data Data payload.
    /// @param operation Operation type.
    /// @param safeTxGas Fas that should be used for the safe transaction.
    /// @param baseGas Gas costs for data used to trigger the safe transaction.
    /// @param gasPrice Maximum gas price that should be used for this transaction.
    /// @param gasToken Token address (or 0 if ETH) that is used for the payment.
    /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).
    /// @param _nonce Transaction nonce.
    /// @return Transaction hash.
    function getTransactionHash(
        address to,
        uint256 value,
        bytes calldata data,
        Enum.Operation operation,
        uint256 safeTxGas,
        uint256 baseGas,
        uint256 gasPrice,
        address gasToken,
        address refundReceiver,
        uint256 _nonce
    ) external view returns (bytes32);

    /// @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.
    /// @param dataHash Hash of the data (could be either a message hash or transaction hash)
    /// @param data That should be signed (this is passed to an external validator contract)
    /// @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.
    /// @param requiredSignatures Amount of required valid signatures.
    function checkNSignatures(
        bytes32 dataHash,
        bytes memory data,
        bytes memory signatures,
        uint256 requiredSignatures
    ) external view;
}

File 5 of 37 : Checkpoints.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Checkpoints.sol)
// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.

pragma solidity ^0.8.0;

import "./math/Math.sol";
import "./math/SafeCast.sol";

/**
 * @dev This library defines the `History` struct, for checkpointing values as they change at different points in
 * time, and later looking up past values by block number. See {Votes} as an example.
 *
 * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new
 * checkpoint for the current transaction block using the {push} function.
 *
 * _Available since v4.5._
 */
library Checkpoints {
    struct History {
        Checkpoint[] _checkpoints;
    }

    struct Checkpoint {
        uint32 _blockNumber;
        uint224 _value;
    }

    /**
     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
     * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the
     * block, the requested block number must be in the past, excluding the current block.
     */
    function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
        require(blockNumber < block.number, "Checkpoints: block not yet mined");
        uint32 key = SafeCast.toUint32(blockNumber);

        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
     * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched
     * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of
     * checkpoints.
     */
    function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
        require(blockNumber < block.number, "Checkpoints: block not yet mined");
        uint32 key = SafeCast.toUint32(blockNumber);

        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block.
     *
     * Returns previous value and new value.
     */
    function push(History storage self, uint256 value) internal returns (uint256, uint256) {
        return _insert(self._checkpoints, SafeCast.toUint32(block.number), SafeCast.toUint224(value));
    }

    /**
     * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will
     * be set to `op(latest, delta)`.
     *
     * Returns previous value and new value.
     */
    function push(
        History storage self,
        function(uint256, uint256) view returns (uint256) op,
        uint256 delta
    ) internal returns (uint256, uint256) {
        return push(self, op(latest(self), delta));
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(History storage self) internal view returns (uint224) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(
        History storage self
    ) internal view returns (bool exists, uint32 _blockNumber, uint224 _value) {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._blockNumber, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(History storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(Checkpoint[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint memory last = _unsafeAccess(self, pos - 1);

            // Checkpoint keys must be non-decreasing.
            require(last._blockNumber <= key, "Checkpoint: decreasing keys");

            // Update or push new checkpoint
            if (last._blockNumber == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint({_blockNumber: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint({_blockNumber: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._blockNumber > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._blockNumber < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace224 {
        Checkpoint224[] _checkpoints;
    }

    struct Checkpoint224 {
        uint32 _key;
        uint224 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     */
    function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.
     */
    function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
     */
    function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
     *
     * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys).
     */
    function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace224 storage self) internal view returns (uint224) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace224 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint224 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoint keys must be non-decreasing.
            require(last._key <= key, "Checkpoint: decreasing keys");

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint224({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint224({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(
        Checkpoint224[] storage self,
        uint256 pos
    ) private pure returns (Checkpoint224 storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace160 {
        Checkpoint160[] _checkpoints;
    }

    struct Checkpoint160 {
        uint96 _key;
        uint160 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     */
    function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.
     */
    function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
     */
    function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
     *
     * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys).
     */
    function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace160 storage self) internal view returns (uint160) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace160 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint160 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoint keys must be non-decreasing.
            require(last._key <= key, "Checkpoint: decreasing keys");

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint160({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint160({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(
        Checkpoint160[] storage self,
        uint256 pos
    ) private pure returns (Checkpoint160 storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }
}

File 6 of 37 : IERC5805.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5805.sol)

pragma solidity ^0.8.0;

import "../governance/utils/IVotes.sol";
import "./IERC6372.sol";

interface IERC5805 is IERC6372, IVotes {}

File 7 of 37 : Governor.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/Governor.sol)

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/math/SafeCast.sol";
import "@openzeppelin/contracts/utils/structs/DoubleEndedQueue.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/governance/IGovernor.sol";

/**
 * @dev Core of the governance system, designed to be extended though various modules.
 *
 * This contract is abstract and requires several functions to be implemented in various modules:
 *
 * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote}
 * - A voting module must implement {_getVotes}
 * - Additionally, {votingPeriod} must also be implemented
 *
 * _Available since v4.3._
 */
abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver {
    using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque;

    bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)");
    bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)");

    struct ProposalCore {
        address proposer;
        uint40 voteStart;
        uint40 voteEnd;
        bool executed;
        bool canceled;
    }

    string private _name;

    /// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore)
    mapping(uint256 => ProposalCore) public proposals;

    // This queue keeps track of the governor operating on itself. Calls to functions protected by the
    // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute},
    // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the
    // execution of {onlyGovernance} protected calls can only be achieved through successful proposals.
    DoubleEndedQueue.Bytes32Deque private _governanceCall;

    /**
     * @dev Restricts a function so it can only be executed through governance proposals. For example, governance
     * parameter setters in {GovernorSettings} are protected using this modifier.
     *
     * The governance executing address may be different from the Governor's own address, for example it could be a
     * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these
     * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus,
     * for example, additional timelock proposers are not able to change governance parameters without going through the
     * governance protocol (since v4.6).
     */
    modifier onlyGovernance() {
        require(_msgSender() == _executor(), "Governor: onlyGovernance");
        if (_executor() != address(this)) {
            bytes32 msgDataHash = keccak256(_msgData());
            // loop until popping the expected operation - throw if deque is empty (operation not authorized)
            while (_governanceCall.popFront() != msgDataHash) { }
        }
        _;
    }

    /**
     * @dev Sets the value for {name} and {version}
     */
    constructor(string memory name_) EIP712(name_, version()) {
        _name = name_;
    }

    /**
     * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract)
     */
    receive() external payable virtual {
        require(_executor() == address(this), "Governor: must send to executor");
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
        bytes4 governorCancelId = this.cancel.selector ^ this.proposalProposer.selector;

        bytes4 governorParamsId = this.castVoteWithReasonAndParams.selector ^ this.castVoteWithReasonAndParamsBySig.selector ^ this.getVotesWithParams.selector;

        // The original interface id in v4.3.
        bytes4 governor43Id = type(IGovernor).interfaceId ^ type(IERC6372).interfaceId ^ governorCancelId ^ governorParamsId;

        // An updated interface id in v4.6, with params added.
        bytes4 governor46Id = type(IGovernor).interfaceId ^ type(IERC6372).interfaceId ^ governorCancelId;

        // For the updated interface id in v4.9, we use governorCancelId directly.

        return interfaceId == governor43Id || interfaceId == governor46Id || interfaceId == governorCancelId || interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IGovernor-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IGovernor-version}.
     */
    function version() public view virtual override returns (string memory) {
        return "1";
    }

    /**
     * @dev See {IGovernor-hashProposal}.
     *
     * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array
     * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id
     * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in
     * advance, before the proposal is submitted.
     *
     * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the
     * same proposal (with same operation and same description) will have the same id if submitted on multiple governors
     * across multiple networks. This also means that in order to execute the same operation twice (on the same
     * governor) the proposer will have to change the description in order to avoid proposal id conflicts.
     */
    function hashProposal(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public pure virtual override returns (uint256) {
        return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash)));
    }

    /**
     * @dev See {IGovernor-state}.
     */
    function state(uint256 proposalId) public view virtual override returns (ProposalState) {
        ProposalCore storage proposal = proposals[proposalId];

        if (proposal.executed) {
            return ProposalState.Executed;
        }

        if (proposal.canceled) {
            return ProposalState.Canceled;
        }

        uint256 snapshot = proposalSnapshot(proposalId);

        if (snapshot == 0) {
            revert("Governor: unknown proposal id");
        }

        uint256 currentTimepoint = clock();

        if (snapshot >= currentTimepoint) {
            return ProposalState.Pending;
        }

        uint256 deadline = proposalDeadline(proposalId);

        if (deadline >= currentTimepoint) {
            return ProposalState.Active;
        }

        if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) {
            return ProposalState.Succeeded;
        } else {
            return ProposalState.Defeated;
        }
    }

    /**
     * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_.
     */
    function proposalThreshold() public view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev See {IGovernor-proposalSnapshot}.
     */
    function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) {
        return proposals[proposalId].voteStart;
    }

    /**
     * @dev See {IGovernor-proposalDeadline}.
     */
    function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) {
        return proposals[proposalId].voteEnd;
    }

    /**
     * @dev Returns the account that created a given proposal.
     */
    function proposalProposer(uint256 proposalId) public view virtual override returns (address) {
        return proposals[proposalId].proposer;
    }

    /**
     * @dev Amount of votes already cast passes the threshold limit.
     */
    function _quorumReached(uint256 proposalId) internal view virtual returns (bool);

    /**
     * @dev Is the proposal successful or not.
     */
    function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool);

    /**
     * @dev Get the voting weight of `account` at a specific `timepoint`, for a vote as described by `params`.
     */
    function _getVotes(address account, uint256 timepoint, bytes memory params) internal view virtual returns (uint256);

    /**
     * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`.
     *
     * Note: Support is generic and can represent various things depending on the voting system used.
     */
    function _countVote(uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory params) internal virtual;

    /**
     * @dev Default additional encoded parameters used by castVote methods that don't include them
     *
     * Note: Should be overridden by specific implementations to use an appropriate value, the
     * meaning of the additional params, in the context of that implementation
     */
    function _defaultParams() internal view virtual returns (bytes memory) {
        return "";
    }

    /**
     * @dev See {IGovernor-propose}.
     */
    function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description) public virtual override returns (uint256) {
        address proposer = _msgSender();
        uint256 currentTimepoint = clock();

        require(getVotes(proposer, currentTimepoint - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold");

        uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));

        require(targets.length == values.length, "Governor: invalid proposal length");
        require(targets.length == calldatas.length, "Governor: invalid proposal length");
        require(targets.length > 0, "Governor: empty proposal");
        require(proposals[proposalId].voteStart == 0, "Governor: proposal already exists");

        uint256 snapshot = currentTimepoint + votingDelay();
        uint256 deadline = snapshot + votingPeriod();

        proposals[proposalId] = ProposalCore({ proposer: proposer, voteStart: SafeCast.toUint40(snapshot), voteEnd: SafeCast.toUint40(deadline), executed: false, canceled: false });

        emit ProposalCreated(proposalId, proposer, targets, values, new string[](targets.length), calldatas, snapshot, deadline, description);

        return proposalId;
    }

    /**
     * @dev See {IGovernor-execute}.
     */
    function execute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public payable virtual override returns (uint256) {
        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);

        ProposalState currentState = state(proposalId);
        require(currentState == ProposalState.Succeeded || currentState == ProposalState.Queued, "Governor: proposal not successful");
        proposals[proposalId].executed = true;

        emit ProposalExecuted(proposalId);

        _beforeExecute(proposalId, targets, values, calldatas, descriptionHash);
        _execute(proposalId, targets, values, calldatas, descriptionHash);
        _afterExecute(proposalId, targets, values, calldatas, descriptionHash);

        return proposalId;
    }

    /**
     * @dev See {IGovernor-cancel}.
     */
    function cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public virtual override returns (uint256) {
        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
        require(state(proposalId) == ProposalState.Pending, "Governor: too late to cancel");
        require(_msgSender() == proposals[proposalId].proposer, "Governor: only proposer can cancel");
        return _cancel(targets, values, calldatas, descriptionHash);
    }

    /**
     * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism
     */
    function _execute(uint256, /* proposalId */ address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual {
        string memory errorMessage = "Governor: call reverted without message";
        for (uint256 i = 0; i < targets.length; ++i) {
            (bool success, bytes memory returndata) = targets[i].call{ value: values[i] }(calldatas[i]);
            Address.verifyCallResult(success, returndata, errorMessage);
        }
    }

    /**
     * @dev Hook before execution is triggered.
     */
    function _beforeExecute(uint256, /* proposalId */ address[] memory targets, uint256[] memory, /* values */ bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual {
        if (_executor() != address(this)) {
            for (uint256 i = 0; i < targets.length; ++i) {
                if (targets[i] == address(this)) {
                    _governanceCall.pushBack(keccak256(calldatas[i]));
                }
            }
        }
    }

    /**
     * @dev Hook after execution is triggered.
     */
    function _afterExecute(uint256, /* proposalId */ address[] memory, /* targets */ uint256[] memory, /* values */ bytes[] memory, /* calldatas */ bytes32 /*descriptionHash*/ ) internal virtual {
        if (_executor() != address(this)) {
            if (!_governanceCall.empty()) {
                _governanceCall.clear();
            }
        }
    }

    /**
     * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as
     * canceled to allow distinguishing it from executed proposals.
     *
     * Emits a {IGovernor-ProposalCanceled} event.
     */
    function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) internal virtual returns (uint256) {
        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);

        ProposalState currentState = state(proposalId);

        require(currentState != ProposalState.Canceled && currentState != ProposalState.Expired && currentState != ProposalState.Executed, "Governor: proposal not active");
        proposals[proposalId].canceled = true;

        emit ProposalCanceled(proposalId);

        return proposalId;
    }

    /**
     * @dev See {IGovernor-getVotes}.
     */
    function getVotes(address account, uint256 timepoint) public view virtual override returns (uint256) {
        return _getVotes(account, timepoint, _defaultParams());
    }

    /**
     * @dev See {IGovernor-getVotesWithParams}.
     */
    function getVotesWithParams(address account, uint256 timepoint, bytes memory params) public view virtual override returns (uint256) {
        return _getVotes(account, timepoint, params);
    }

    /**
     * @dev See {IGovernor-castVote}.
     */
    function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) {
        address voter = _msgSender();
        return _castVote(proposalId, voter, support, "");
    }

    /**
     * @dev See {IGovernor-castVoteWithReason}.
     */
    function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) public virtual override returns (uint256) {
        address voter = _msgSender();
        return _castVote(proposalId, voter, support, reason);
    }

    /**
     * @dev See {IGovernor-castVoteWithReasonAndParams}.
     */
    function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params) public virtual override returns (uint256) {
        address voter = _msgSender();
        return _castVote(proposalId, voter, support, reason, params);
    }

    /**
     * @dev See {IGovernor-castVoteBySig}.
     */
    function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) public virtual override returns (uint256) {
        address voter = ECDSA.recover(_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), v, r, s);
        return _castVote(proposalId, voter, support, "");
    }

    /**
     * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}.
     */
    function castVoteWithReasonAndParamsBySig(uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s) public virtual override returns (uint256) {
        address voter = ECDSA.recover(_hashTypedDataV4(keccak256(abi.encode(EXTENDED_BALLOT_TYPEHASH, proposalId, support, keccak256(bytes(reason)), keccak256(params)))), v, r, s);

        return _castVote(proposalId, voter, support, reason, params);
    }

    /**
     * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve
     * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams().
     *
     * Emits a {IGovernor-VoteCast} event.
     */
    function _castVote(uint256 proposalId, address account, uint8 support, string memory reason) internal virtual returns (uint256) {
        return _castVote(proposalId, account, support, reason, _defaultParams());
    }

    /**
     * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve
     * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function.
     *
     * Emits a {IGovernor-VoteCast} event.
     */
    function _castVote(uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params) internal virtual returns (uint256) {
        ProposalCore storage proposal = proposals[proposalId];
        require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active");

        uint256 weight = _getVotes(account, proposal.voteStart, params);
        _countVote(proposalId, account, support, weight, params);

        if (params.length == 0) {
            emit VoteCast(account, proposalId, support, weight, reason);
        } else {
            emit VoteCastWithParams(account, proposalId, support, weight, reason, params);
        }

        return weight;
    }

    /**
     * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor
     * is some contract other than the governor itself, like when using a timelock, this function can be invoked
     * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake.
     * Note that if the executor is simply the governor itself, use of `relay` is redundant.
     */
    function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance {
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        Address.verifyCallResult(success, returndata, "Governor: relay reverted without message");
    }

    /**
     * @dev Address through which the governor executes action. Will be overloaded by module that execute actions
     * through another contract such as a timelock.
     */
    function _executor() internal view virtual returns (address) {
        return address(this);
    }

    /**
     * @dev See {IERC721Receiver-onERC721Received}.
     */
    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }

    /**
     * @dev See {IERC1155Receiver-onERC1155Received}.
     */
    function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    /**
     * @dev See {IERC1155Receiver-onERC1155BatchReceived}.
     */
    function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {
        return this.onERC1155BatchReceived.selector;
    }
}

File 8 of 37 : GovernorCountingFractional.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.X.X (governance/extensions/GovernorCountingFractional.sol)

pragma solidity ^0.8.0;

import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { Governor } from "./Governor.sol";
import {
    GovernorCompatibilityBravo
} from "@openzeppelin/contracts/governance/compatibility/GovernorCompatibilityBravo.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";

/**
 * @notice Extension of {Governor} for 3 option fractional vote counting. When
 * voting, a delegate may split their vote weight between Against/For/Abstain.
 * This is most useful when the delegate is itself a contract, implementing its
 * own rules for voting. By allowing a contract-delegate to split its vote
 * weight, the voting preferences of many disparate token holders can be rolled
 * up into a single vote to the Governor itself. Some example use cases include
 * voting with tokens that are held by a DeFi pool, voting from L2 with tokens
 * held by a bridge, or voting privately from a shielded pool using zero
 * knowledge proofs.
 */
abstract contract GovernorCountingFractional is Governor {
    struct ProposalVote {
        uint128 againstVotes;
        uint128 forVotes;
        uint128 abstainVotes;
    }

    /**
     * @dev Mapping from proposal ID to vote tallies for that proposal.
     */
    mapping(uint256 => ProposalVote) private _proposalVotes;

    /**
     * @dev Mapping from proposal ID and address to the weight the address
     * has cast on that proposal, e.g. _proposalVotersWeightCast[42][0xBEEF]
     * would tell you the number of votes that 0xBEEF has cast on proposal 42.
     */
    mapping(uint256 => mapping(address => uint128)) private _proposalVotersWeightCast;

    /**
     * @dev Mapping from voter address to signature-based vote nonce. The
     * voter's nonce increments each time a signature-based vote is cast with
     * fractional voting params and must be included in the `params` as the last
     * 16 bytes when signing for a fractional vote.
     */
    mapping(address => uint128) public fractionalVoteNonce;

    /**
     * @dev See {IGovernor-COUNTING_MODE}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function COUNTING_MODE() public pure virtual override returns (string memory) {
        return "support=bravo&quorum=for,abstain&params=fractional";
    }

    /**
     * @dev See {IGovernor-hasVoted}.
     */
    function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {
        return _proposalVotersWeightCast[proposalId][account] > 0;
    }

    /**
     * @dev Get the number of votes cast thus far on proposal `proposalId` by
     * account `account`. Useful for integrations that allow delegates to cast
     * rolling, partial votes.
     */
    function voteWeightCast(uint256 proposalId, address account) public view returns (uint128) {
        return _proposalVotersWeightCast[proposalId][account];
    }

    /**
     * @dev Accessor to the internal vote counts.
     */
    function proposalVotes(
        uint256 proposalId
    ) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) {
        ProposalVote storage proposalVote = _proposalVotes[proposalId];
        return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes);
    }

    /**
     * @dev See {Governor-_quorumReached}.
     */
    function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {
        ProposalVote storage proposalVote = _proposalVotes[proposalId];

        return quorum(proposalSnapshot(proposalId)) <= proposalVote.forVotes + proposalVote.abstainVotes;
    }

    /**
     * @dev See {Governor-_voteSucceeded}. In this module, forVotes must be > againstVotes.
     */
    function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
        ProposalVote storage proposalVote = _proposalVotes[proposalId];

        return proposalVote.forVotes > proposalVote.againstVotes;
    }

    /**
     * @notice See {Governor-_countVote}.
     *
     * @dev Function that records the delegate's votes.
     *
     * If the `voteData` bytes parameter is empty, then this module behaves
     * identically to GovernorBravo. That is, it assigns the full weight of the
     * delegate to the `support` parameter, which follows the `VoteType` enum
     * from Governor Bravo.
     *
     * If the `voteData` bytes parameter is not zero, then it _must_ be three
     * packed uint128s, totaling 48 bytes, representing the weight the delegate
     * assigns to Against, For, and Abstain respectively, i.e.
     * `abi.encodePacked(againstVotes, forVotes, abstainVotes)`. The sum total of
     * the three decoded vote weights _must_ be less than or equal to the
     * delegate's remaining weight on the proposal, i.e. their checkpointed
     * total weight minus votes already cast on the proposal.
     *
     * See `_countVoteNominal` and `_countVoteFractional` for more details.
     */
    function _countVote(
        uint256 proposalId,
        address account,
        uint8 support,
        uint256 totalWeight,
        bytes memory voteData
    ) internal virtual override {
        require(totalWeight > 0, "GovernorCountingFractional: no weight");
        if (_proposalVotersWeightCast[proposalId][account] >= totalWeight) {
            revert("GovernorCountingFractional: all weight cast");
        }

        uint128 safeTotalWeight = SafeCast.toUint128(totalWeight);

        if (voteData.length == 0) {
            _countVoteNominal(proposalId, account, safeTotalWeight, support);
        } else {
            _countVoteFractional(proposalId, account, safeTotalWeight, voteData);
        }
    }

    /**
     * @dev Record votes with full weight cast for `support`.
     *
     * Because this function votes with the delegate's full weight, it can only
     * be called once per proposal. It will revert if combined with a fractional
     * vote before or after.
     */
    function _countVoteNominal(uint256 proposalId, address account, uint128 totalWeight, uint8 support) internal {
        require(
            _proposalVotersWeightCast[proposalId][account] == 0,
            "GovernorCountingFractional: vote would exceed weight"
        );

        _proposalVotersWeightCast[proposalId][account] = totalWeight;

        if (support == uint8(GovernorCompatibilityBravo.VoteType.Against)) {
            _proposalVotes[proposalId].againstVotes += totalWeight;
        } else if (support == uint8(GovernorCompatibilityBravo.VoteType.For)) {
            _proposalVotes[proposalId].forVotes += totalWeight;
        } else if (support == uint8(GovernorCompatibilityBravo.VoteType.Abstain)) {
            _proposalVotes[proposalId].abstainVotes += totalWeight;
        } else {
            revert("GovernorCountingFractional: invalid support value, must be included in VoteType enum");
        }
    }

    /**
     * @dev Count votes with fractional weight.
     *
     * `voteData` is expected to be three packed uint128s, i.e.
     * `abi.encodePacked(againstVotes, forVotes, abstainVotes)`.
     *
     * This function can be called multiple times for the same account and
     * proposal, i.e. partial/rolling votes are allowed. For example, an account
     * with total weight of 10 could call this function three times with the
     * following vote data:
     *   - against: 1, for: 0, abstain: 2
     *   - against: 3, for: 1, abstain: 0
     *   - against: 1, for: 1, abstain: 1
     * The result of these three calls would be that the account casts 5 votes
     * AGAINST, 2 votes FOR, and 3 votes ABSTAIN on the proposal. Though
     * partial, votes are still final once cast and cannot be changed or
     * overridden. Subsequent partial votes simply increment existing totals.
     *
     * Note that if partial votes are cast, all remaining weight must be cast
     * with _countVoteFractional: _countVoteNominal will revert.
     */
    function _countVoteFractional(
        uint256 proposalId,
        address account,
        uint128 totalWeight,
        bytes memory voteData
    ) internal {
        require(voteData.length == 48, "GovernorCountingFractional: invalid voteData");

        (uint128 _againstVotes, uint128 _forVotes, uint128 _abstainVotes) = _decodePackedVotes(voteData);

        uint128 _existingWeight = _proposalVotersWeightCast[proposalId][account];
        uint256 _newWeight = uint256(_againstVotes) + _forVotes + _abstainVotes + _existingWeight;

        require(_newWeight <= totalWeight, "GovernorCountingFractional: vote would exceed weight");

        // It's safe to downcast here because we've just confirmed that
        // _newWeight <= totalWeight, and totalWeight is a uint128.
        _proposalVotersWeightCast[proposalId][account] = uint128(_newWeight);

        ProposalVote memory _proposalVote = _proposalVotes[proposalId];
        _proposalVote = ProposalVote(
            _proposalVote.againstVotes + _againstVotes,
            _proposalVote.forVotes + _forVotes,
            _proposalVote.abstainVotes + _abstainVotes
        );

        _proposalVotes[proposalId] = _proposalVote;
    }

    uint256 internal constant _MASK_HALF_WORD_RIGHT = 0xffffffffffffffffffffffffffffffff; // 128 bits of 0's, 128 bits of 1's

    /**
     * @dev Decodes three packed uint128's. Uses assembly because of a Solidity
     * language limitation which prevents slicing bytes stored in memory, rather
     * than calldata.
     */
    function _decodePackedVotes(
        bytes memory voteData
    ) internal pure returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) {
        assembly {
            againstVotes := shr(128, mload(add(voteData, 0x20)))
            forVotes := and(_MASK_HALF_WORD_RIGHT, mload(add(voteData, 0x20)))
            abstainVotes := shr(128, mload(add(voteData, 0x40)))
        }
    }

    /**
     * @notice Cast a vote with a reason and additional encoded parameters using
     * the user's cryptographic signature.
     *
     * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length
     * of params.
     *
     * @dev If casting a fractional vote via `params`, the voter's current nonce
     * must be appended to the `params` as the last 16 bytes and included in the
     * signature. I.e., the params used when constructing the signature would be:
     *
     *   abi.encodePacked(againstVotes, forVotes, abstainVotes, nonce)
     *
     * See {fractionalVoteNonce} and {_castVote} for more information.
     */
    function castVoteWithReasonAndParamsBySig(
        uint256 proposalId,
        uint8 support,
        string calldata reason,
        bytes memory params,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override returns (uint256) {
        // Signature-based fractional voting requires `params` be two full words
        // in length:
        //   16 bytes for againstVotes.
        //   16 bytes for forVotes.
        //   16 bytes for abstainVotes.
        //   16 bytes for the signature nonce.
        // Signature-based nominal voting requires `params` be 0 bytes.
        require(
            params.length == 64 || params.length == 0,
            "GovernorCountingFractional: invalid params for signature-based vote"
        );

        address voter = ECDSA.recover(
            _hashTypedDataV4(
                keccak256(
                    abi.encode(
                        EXTENDED_BALLOT_TYPEHASH,
                        proposalId,
                        support,
                        keccak256(bytes(reason)),
                        keccak256(params)
                    )
                )
            ),
            v,
            r,
            s
        );

        // If params are zero-length all of the voter's weight will be cast so
        // we don't have to worry about checking/incrementing a nonce.
        if (params.length == 64) {
            // Get the nonce out of the params. It is the last half-word.
            uint128 nonce;
            assembly {
                nonce := and(
                    // Perform bitwise AND operation on the data in the second word of
                    // `params` with a mask of 128 zeros followed by 128 ones, i.e. take
                    // the last 128 bits of `params`.
                    _MASK_HALF_WORD_RIGHT,
                    // Load the data from memory at the returned address.
                    mload(
                        // Skip the first 64 bytes (0x40):
                        //   32 bytes encoding the length of the bytes array.
                        //   32 bytes for the first word in the params
                        // Return the memory address for the last word in params.
                        add(params, 0x40)
                    )
                )
            }

            require(fractionalVoteNonce[voter] == nonce, "GovernorCountingFractional: signature has already been used");

            fractionalVoteNonce[voter]++;

            // Trim params in place to keep only the first 48 bytes (which are
            // the voting params) and save gas.
            assembly {
                mstore(params, 0x30)
            }
        }

        return _castVote(proposalId, voter, support, reason, params);
    }
}

File 9 of 37 : GovernorSettings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorSettings.sol)

pragma solidity ^0.8.0;

import { Governor } from "./Governor.sol";

/**
 * @dev Extension of {Governor} for settings updatable through governance.
 *
 * _Available since v4.4._
 */
abstract contract GovernorSettings is Governor {
    uint256 private _votingDelay;
    uint256 private _votingPeriod;
    uint256 private _proposalThreshold;

    event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);
    event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);
    event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);

    /**
     * @dev Initialize the governance parameters.
     */
    constructor(uint256 initialVotingDelay, uint256 initialVotingPeriod, uint256 initialProposalThreshold) {
        _setVotingDelay(initialVotingDelay);
        _setVotingPeriod(initialVotingPeriod);
        _setProposalThreshold(initialProposalThreshold);
    }

    /**
     * @dev See {IGovernor-votingDelay}.
     */
    function votingDelay() public view virtual override returns (uint256) {
        return _votingDelay;
    }

    /**
     * @dev See {IGovernor-votingPeriod}.
     */
    function votingPeriod() public view virtual override returns (uint256) {
        return _votingPeriod;
    }

    /**
     * @dev See {Governor-proposalThreshold}.
     */
    function proposalThreshold() public view virtual override returns (uint256) {
        return _proposalThreshold;
    }

    /**
     * @dev Update the voting delay. This operation can only be performed through a governance proposal.
     *
     * Emits a {VotingDelaySet} event.
     */
    function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance {
        _setVotingDelay(newVotingDelay);
    }

    /**
     * @dev Update the voting period. This operation can only be performed through a governance proposal.
     *
     * Emits a {VotingPeriodSet} event.
     */
    function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance {
        _setVotingPeriod(newVotingPeriod);
    }

    /**
     * @dev Update the proposal threshold. This operation can only be performed through a governance proposal.
     *
     * Emits a {ProposalThresholdSet} event.
     */
    function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance {
        _setProposalThreshold(newProposalThreshold);
    }

    /**
     * @dev Internal setter for the voting delay.
     *
     * Emits a {VotingDelaySet} event.
     */
    function _setVotingDelay(uint256 newVotingDelay) internal virtual {
        emit VotingDelaySet(_votingDelay, newVotingDelay);
        _votingDelay = newVotingDelay;
    }

    /**
     * @dev Internal setter for the voting period.
     *
     * Emits a {VotingPeriodSet} event.
     */
    function _setVotingPeriod(uint256 newVotingPeriod) internal virtual {
        // voting period must be at least one block long
        require(newVotingPeriod > 0, "GovernorSettings: voting period too low");
        emit VotingPeriodSet(_votingPeriod, newVotingPeriod);
        _votingPeriod = newVotingPeriod;
    }

    /**
     * @dev Internal setter for the proposal threshold.
     *
     * Emits a {ProposalThresholdSet} event.
     */
    function _setProposalThreshold(uint256 newProposalThreshold) internal virtual {
        emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold);
        _proposalThreshold = newProposalThreshold;
    }
}

File 10 of 37 : GovernorVotesQuorumFraction.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorVotesQuorumFraction.sol)

pragma solidity ^0.8.0;

import "./GovernorVotes.sol";
import "@openzeppelin/contracts/utils/Checkpoints.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";

/**
 * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a
 * fraction of the total supply.
 *
 * _Available since v4.3._
 */
abstract contract GovernorVotesQuorumFraction is GovernorVotes {
    using Checkpoints for Checkpoints.Trace224;

    /// @custom:oz-retyped-from Checkpoints.History
    Checkpoints.Trace224 private _quorumNumeratorHistory;

    event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);

    /**
     * @dev Initialize quorum as a fraction of the token's total supply.
     *
     * The fraction is specified as `numerator / denominator`. By default the denominator is 100, so quorum is
     * specified as a percent: a numerator of 10 corresponds to quorum being 10% of total supply. The denominator can be
     * customized by overriding {quorumDenominator}.
     */
    constructor(uint256 quorumNumeratorValue) {
        _updateQuorumNumerator(quorumNumeratorValue);
    }

    /**
     * @dev Returns the current quorum numerator. See {quorumDenominator}.
     */
    function quorumNumerator() public view virtual returns (uint256) {
        return _quorumNumeratorHistory.latest();
    }

    /**
     * @dev Returns the quorum numerator at a specific timepoint. See {quorumDenominator}.
     */
    function quorumNumerator(uint256 timepoint) public view virtual returns (uint256) {
        // If history is empty, fallback to old storage
        uint256 length = _quorumNumeratorHistory._checkpoints.length;

        // Optimistic search, check the latest checkpoint
        Checkpoints.Checkpoint224 memory latest = _quorumNumeratorHistory._checkpoints[length - 1];
        if (latest._key <= timepoint) {
            return latest._value;
        }

        // Otherwise, do the binary search
        return _quorumNumeratorHistory.upperLookupRecent(SafeCast.toUint32(timepoint));
    }

    /**
     * @dev Returns the quorum denominator. Defaults to 100, but may be overridden.
     */
    function quorumDenominator() public view virtual returns (uint256) {
        return 100;
    }

    /**
     * @dev Returns the quorum for a timepoint, in terms of number of votes: `supply * numerator / denominator`.
     */
    function quorum(uint256 timepoint) public view virtual override returns (uint256) {
        return (token.getPastTotalSupply(timepoint) * quorumNumerator(timepoint)) / quorumDenominator();
    }

    /**
     * @dev Changes the quorum numerator.
     *
     * Emits a {QuorumNumeratorUpdated} event.
     *
     * Requirements:
     *
     * - Must be called through a governance proposal.
     * - New numerator must be smaller or equal to the denominator.
     */
    function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance {
        _updateQuorumNumerator(newQuorumNumerator);
    }

    /**
     * @dev Changes the quorum numerator.
     *
     * Emits a {QuorumNumeratorUpdated} event.
     *
     * Requirements:
     *
     * - New numerator must be smaller or equal to the denominator.
     */
    function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual {
        require(
            newQuorumNumerator <= quorumDenominator(),
            "GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator"
        );

        uint256 oldQuorumNumerator = quorumNumerator();

        // Set new quorum for future proposals
        _quorumNumeratorHistory.push(SafeCast.toUint32(clock()), SafeCast.toUint224(newQuorumNumerator));

        emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator);
    }
}

File 11 of 37 : IVeFxs.sol
// SPDX-License-Identifier: ISC
pragma solidity >=0.6.11;
pragma abicoder v2;

interface IVeFxs {
    struct LockedBalance {
        int128 amount;
        uint256 end;
    }

    function commit_transfer_ownership(address addr) external;

    function apply_transfer_ownership() external;

    function commit_smart_wallet_checker(address addr) external;

    function apply_smart_wallet_checker() external;

    function toggleEmergencyUnlock() external;

    function recoverERC20(address token_addr, uint256 amount) external;

    function get_last_user_slope(address addr) external view returns (int128);

    function user_point_history__ts(address _addr, uint256 _idx) external view returns (uint256);

    function locked__end(address _addr) external view returns (uint256);

    function checkpoint() external;

    function deposit_for(address _addr, uint256 _value) external;

    function create_lock(uint256 _value, uint256 _unlock_time) external;

    function increase_amount(uint256 _value) external;

    function increase_unlock_time(uint256 _unlock_time) external;

    function withdraw() external;

    function balanceOf(address addr) external view returns (uint256);

    function balanceOf(address addr, uint256 _t) external view returns (uint256);

    function balanceOfAt(address addr, uint256 _block) external view returns (uint256);

    function totalSupply() external view returns (uint256);

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

    function totalSupplyAt(uint256 _block) external view returns (uint256);

    function totalFXSSupply() external view returns (uint256);

    function totalFXSSupplyAt(uint256 _block) external view returns (uint256);

    function changeController(address _newController) external;

    function token() external view returns (address);

    function supply() external view returns (uint256);

    function locked(address addr) external view returns (LockedBalance memory);

    function epoch() external view returns (uint256);

    function point_history(
        uint256 arg0
    ) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fxs_amt);

    function user_point_history(
        address _addr,
        uint256 _idx
    ) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fxs_amt);

    function user_point_epoch(address arg0) external view returns (uint256);

    function slope_changes(uint256 arg0) external view returns (int128);

    function controller() external view returns (address);

    function transfersEnabled() external view returns (bool);

    function emergencyUnlockActive() external view returns (bool);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function version() external view returns (string memory);

    function decimals() external view returns (uint256);

    function future_smart_wallet_checker() external view returns (address);

    function smart_wallet_checker() external view returns (address);

    function admin() external view returns (address);

    function future_admin() external view returns (address);

    function newSnapshotTime(uint256 snapshot) external;

}

File 12 of 37 : Enum.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

/// @title Enum - Collection of enums
/// @author Richard Meissner - <[email protected]>
contract Enum {
    enum Operation {Call, DelegateCall}
}

File 13 of 37 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

File 14 of 37 : SafeCast.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint248 from uint256, reverting on
     * overflow (when the input is greater than largest uint248).
     *
     * Counterpart to Solidity's `uint248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
        return uint248(value);
    }

    /**
     * @dev Returns the downcasted uint240 from uint256, reverting on
     * overflow (when the input is greater than largest uint240).
     *
     * Counterpart to Solidity's `uint240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
        return uint240(value);
    }

    /**
     * @dev Returns the downcasted uint232 from uint256, reverting on
     * overflow (when the input is greater than largest uint232).
     *
     * Counterpart to Solidity's `uint232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
        return uint232(value);
    }

    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.2._
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint216 from uint256, reverting on
     * overflow (when the input is greater than largest uint216).
     *
     * Counterpart to Solidity's `uint216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
        return uint216(value);
    }

    /**
     * @dev Returns the downcasted uint208 from uint256, reverting on
     * overflow (when the input is greater than largest uint208).
     *
     * Counterpart to Solidity's `uint208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
        return uint208(value);
    }

    /**
     * @dev Returns the downcasted uint200 from uint256, reverting on
     * overflow (when the input is greater than largest uint200).
     *
     * Counterpart to Solidity's `uint200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
        return uint200(value);
    }

    /**
     * @dev Returns the downcasted uint192 from uint256, reverting on
     * overflow (when the input is greater than largest uint192).
     *
     * Counterpart to Solidity's `uint192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
        return uint192(value);
    }

    /**
     * @dev Returns the downcasted uint184 from uint256, reverting on
     * overflow (when the input is greater than largest uint184).
     *
     * Counterpart to Solidity's `uint184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
        return uint184(value);
    }

    /**
     * @dev Returns the downcasted uint176 from uint256, reverting on
     * overflow (when the input is greater than largest uint176).
     *
     * Counterpart to Solidity's `uint176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
        return uint176(value);
    }

    /**
     * @dev Returns the downcasted uint168 from uint256, reverting on
     * overflow (when the input is greater than largest uint168).
     *
     * Counterpart to Solidity's `uint168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
        return uint168(value);
    }

    /**
     * @dev Returns the downcasted uint160 from uint256, reverting on
     * overflow (when the input is greater than largest uint160).
     *
     * Counterpart to Solidity's `uint160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
        return uint160(value);
    }

    /**
     * @dev Returns the downcasted uint152 from uint256, reverting on
     * overflow (when the input is greater than largest uint152).
     *
     * Counterpart to Solidity's `uint152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
        return uint152(value);
    }

    /**
     * @dev Returns the downcasted uint144 from uint256, reverting on
     * overflow (when the input is greater than largest uint144).
     *
     * Counterpart to Solidity's `uint144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
        return uint144(value);
    }

    /**
     * @dev Returns the downcasted uint136 from uint256, reverting on
     * overflow (when the input is greater than largest uint136).
     *
     * Counterpart to Solidity's `uint136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
        return uint136(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v2.5._
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint120 from uint256, reverting on
     * overflow (when the input is greater than largest uint120).
     *
     * Counterpart to Solidity's `uint120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
        return uint120(value);
    }

    /**
     * @dev Returns the downcasted uint112 from uint256, reverting on
     * overflow (when the input is greater than largest uint112).
     *
     * Counterpart to Solidity's `uint112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
        return uint112(value);
    }

    /**
     * @dev Returns the downcasted uint104 from uint256, reverting on
     * overflow (when the input is greater than largest uint104).
     *
     * Counterpart to Solidity's `uint104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
        return uint104(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.2._
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint88 from uint256, reverting on
     * overflow (when the input is greater than largest uint88).
     *
     * Counterpart to Solidity's `uint88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
        return uint88(value);
    }

    /**
     * @dev Returns the downcasted uint80 from uint256, reverting on
     * overflow (when the input is greater than largest uint80).
     *
     * Counterpart to Solidity's `uint80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
        return uint80(value);
    }

    /**
     * @dev Returns the downcasted uint72 from uint256, reverting on
     * overflow (when the input is greater than largest uint72).
     *
     * Counterpart to Solidity's `uint72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
        return uint72(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v2.5._
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint56 from uint256, reverting on
     * overflow (when the input is greater than largest uint56).
     *
     * Counterpart to Solidity's `uint56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
        return uint56(value);
    }

    /**
     * @dev Returns the downcasted uint48 from uint256, reverting on
     * overflow (when the input is greater than largest uint48).
     *
     * Counterpart to Solidity's `uint48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
        return uint48(value);
    }

    /**
     * @dev Returns the downcasted uint40 from uint256, reverting on
     * overflow (when the input is greater than largest uint40).
     *
     * Counterpart to Solidity's `uint40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
        return uint40(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v2.5._
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint24 from uint256, reverting on
     * overflow (when the input is greater than largest uint24).
     *
     * Counterpart to Solidity's `uint24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
        return uint24(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v2.5._
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v2.5._
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     *
     * _Available since v3.0._
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int248 from int256, reverting on
     * overflow (when the input is less than smallest int248 or
     * greater than largest int248).
     *
     * Counterpart to Solidity's `int248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toInt248(int256 value) internal pure returns (int248 downcasted) {
        downcasted = int248(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
    }

    /**
     * @dev Returns the downcasted int240 from int256, reverting on
     * overflow (when the input is less than smallest int240 or
     * greater than largest int240).
     *
     * Counterpart to Solidity's `int240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toInt240(int256 value) internal pure returns (int240 downcasted) {
        downcasted = int240(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
    }

    /**
     * @dev Returns the downcasted int232 from int256, reverting on
     * overflow (when the input is less than smallest int232 or
     * greater than largest int232).
     *
     * Counterpart to Solidity's `int232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toInt232(int256 value) internal pure returns (int232 downcasted) {
        downcasted = int232(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
    }

    /**
     * @dev Returns the downcasted int224 from int256, reverting on
     * overflow (when the input is less than smallest int224 or
     * greater than largest int224).
     *
     * Counterpart to Solidity's `int224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.7._
     */
    function toInt224(int256 value) internal pure returns (int224 downcasted) {
        downcasted = int224(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
    }

    /**
     * @dev Returns the downcasted int216 from int256, reverting on
     * overflow (when the input is less than smallest int216 or
     * greater than largest int216).
     *
     * Counterpart to Solidity's `int216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toInt216(int256 value) internal pure returns (int216 downcasted) {
        downcasted = int216(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
    }

    /**
     * @dev Returns the downcasted int208 from int256, reverting on
     * overflow (when the input is less than smallest int208 or
     * greater than largest int208).
     *
     * Counterpart to Solidity's `int208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toInt208(int256 value) internal pure returns (int208 downcasted) {
        downcasted = int208(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
    }

    /**
     * @dev Returns the downcasted int200 from int256, reverting on
     * overflow (when the input is less than smallest int200 or
     * greater than largest int200).
     *
     * Counterpart to Solidity's `int200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toInt200(int256 value) internal pure returns (int200 downcasted) {
        downcasted = int200(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
    }

    /**
     * @dev Returns the downcasted int192 from int256, reverting on
     * overflow (when the input is less than smallest int192 or
     * greater than largest int192).
     *
     * Counterpart to Solidity's `int192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toInt192(int256 value) internal pure returns (int192 downcasted) {
        downcasted = int192(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
    }

    /**
     * @dev Returns the downcasted int184 from int256, reverting on
     * overflow (when the input is less than smallest int184 or
     * greater than largest int184).
     *
     * Counterpart to Solidity's `int184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toInt184(int256 value) internal pure returns (int184 downcasted) {
        downcasted = int184(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
    }

    /**
     * @dev Returns the downcasted int176 from int256, reverting on
     * overflow (when the input is less than smallest int176 or
     * greater than largest int176).
     *
     * Counterpart to Solidity's `int176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toInt176(int256 value) internal pure returns (int176 downcasted) {
        downcasted = int176(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
    }

    /**
     * @dev Returns the downcasted int168 from int256, reverting on
     * overflow (when the input is less than smallest int168 or
     * greater than largest int168).
     *
     * Counterpart to Solidity's `int168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toInt168(int256 value) internal pure returns (int168 downcasted) {
        downcasted = int168(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
    }

    /**
     * @dev Returns the downcasted int160 from int256, reverting on
     * overflow (when the input is less than smallest int160 or
     * greater than largest int160).
     *
     * Counterpart to Solidity's `int160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toInt160(int256 value) internal pure returns (int160 downcasted) {
        downcasted = int160(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
    }

    /**
     * @dev Returns the downcasted int152 from int256, reverting on
     * overflow (when the input is less than smallest int152 or
     * greater than largest int152).
     *
     * Counterpart to Solidity's `int152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toInt152(int256 value) internal pure returns (int152 downcasted) {
        downcasted = int152(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
    }

    /**
     * @dev Returns the downcasted int144 from int256, reverting on
     * overflow (when the input is less than smallest int144 or
     * greater than largest int144).
     *
     * Counterpart to Solidity's `int144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toInt144(int256 value) internal pure returns (int144 downcasted) {
        downcasted = int144(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
    }

    /**
     * @dev Returns the downcasted int136 from int256, reverting on
     * overflow (when the input is less than smallest int136 or
     * greater than largest int136).
     *
     * Counterpart to Solidity's `int136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toInt136(int256 value) internal pure returns (int136 downcasted) {
        downcasted = int136(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128 downcasted) {
        downcasted = int128(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
    }

    /**
     * @dev Returns the downcasted int120 from int256, reverting on
     * overflow (when the input is less than smallest int120 or
     * greater than largest int120).
     *
     * Counterpart to Solidity's `int120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toInt120(int256 value) internal pure returns (int120 downcasted) {
        downcasted = int120(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
    }

    /**
     * @dev Returns the downcasted int112 from int256, reverting on
     * overflow (when the input is less than smallest int112 or
     * greater than largest int112).
     *
     * Counterpart to Solidity's `int112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toInt112(int256 value) internal pure returns (int112 downcasted) {
        downcasted = int112(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
    }

    /**
     * @dev Returns the downcasted int104 from int256, reverting on
     * overflow (when the input is less than smallest int104 or
     * greater than largest int104).
     *
     * Counterpart to Solidity's `int104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toInt104(int256 value) internal pure returns (int104 downcasted) {
        downcasted = int104(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
    }

    /**
     * @dev Returns the downcasted int96 from int256, reverting on
     * overflow (when the input is less than smallest int96 or
     * greater than largest int96).
     *
     * Counterpart to Solidity's `int96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.7._
     */
    function toInt96(int256 value) internal pure returns (int96 downcasted) {
        downcasted = int96(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
    }

    /**
     * @dev Returns the downcasted int88 from int256, reverting on
     * overflow (when the input is less than smallest int88 or
     * greater than largest int88).
     *
     * Counterpart to Solidity's `int88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toInt88(int256 value) internal pure returns (int88 downcasted) {
        downcasted = int88(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
    }

    /**
     * @dev Returns the downcasted int80 from int256, reverting on
     * overflow (when the input is less than smallest int80 or
     * greater than largest int80).
     *
     * Counterpart to Solidity's `int80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toInt80(int256 value) internal pure returns (int80 downcasted) {
        downcasted = int80(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
    }

    /**
     * @dev Returns the downcasted int72 from int256, reverting on
     * overflow (when the input is less than smallest int72 or
     * greater than largest int72).
     *
     * Counterpart to Solidity's `int72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toInt72(int256 value) internal pure returns (int72 downcasted) {
        downcasted = int72(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64 downcasted) {
        downcasted = int64(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
    }

    /**
     * @dev Returns the downcasted int56 from int256, reverting on
     * overflow (when the input is less than smallest int56 or
     * greater than largest int56).
     *
     * Counterpart to Solidity's `int56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toInt56(int256 value) internal pure returns (int56 downcasted) {
        downcasted = int56(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
    }

    /**
     * @dev Returns the downcasted int48 from int256, reverting on
     * overflow (when the input is less than smallest int48 or
     * greater than largest int48).
     *
     * Counterpart to Solidity's `int48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toInt48(int256 value) internal pure returns (int48 downcasted) {
        downcasted = int48(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
    }

    /**
     * @dev Returns the downcasted int40 from int256, reverting on
     * overflow (when the input is less than smallest int40 or
     * greater than largest int40).
     *
     * Counterpart to Solidity's `int40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toInt40(int256 value) internal pure returns (int40 downcasted) {
        downcasted = int40(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32 downcasted) {
        downcasted = int32(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
    }

    /**
     * @dev Returns the downcasted int24 from int256, reverting on
     * overflow (when the input is less than smallest int24 or
     * greater than largest int24).
     *
     * Counterpart to Solidity's `int24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toInt24(int256 value) internal pure returns (int24 downcasted) {
        downcasted = int24(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16 downcasted) {
        downcasted = int16(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8 downcasted) {
        downcasted = int8(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     *
     * _Available since v3.0._
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

File 15 of 37 : IVotes.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/IVotes.sol)
pragma solidity ^0.8.0;

/**
 * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.
 *
 * _Available since v4.5._
 */
interface IVotes {
    /**
     * @dev Emitted when an account changes their delegate.
     */
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /**
     * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.
     */
    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

    /**
     * @dev Returns the current amount of votes that `account` has.
     */
    function getVotes(address account) external view returns (uint256);

    /**
     * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is
     * configured to use block numbers, this will return the value at the end of the corresponding block.
     */
    function getPastVotes(address account, uint256 timepoint) external view returns (uint256);

    /**
     * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is
     * configured to use block numbers, this will return the value at the end of the corresponding block.
     *
     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
     * Votes that have not been delegated are still part of total supply, even though they would not participate in a
     * vote.
     */
    function getPastTotalSupply(uint256 timepoint) external view returns (uint256);

    /**
     * @dev Returns the delegate that `account` has chosen.
     */
    function delegates(address account) external view returns (address);

    /**
     * @dev Delegates votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) external;

    /**
     * @dev Delegates votes from signer to `delegatee`.
     */
    function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;
}

File 16 of 37 : IERC6372.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC6372.sol)

pragma solidity ^0.8.0;

interface IERC6372 {
    /**
     * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).
     */
    function clock() external view returns (uint48);

    /**
     * @dev Description of the clock
     */
    // solhint-disable-next-line func-name-mixedcase
    function CLOCK_MODE() external view returns (string memory);
}

File 17 of 37 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 18 of 37 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 19 of 37 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\n32")
            mstore(0x1c, hash)
            message := keccak256(0x00, 0x3c)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, "\x19\x01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            data := keccak256(ptr, 0x42)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Data with intended validator, created from a
     * `validator` and `data` according to the version 0 of EIP-191.
     *
     * See {recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x00", validator, data));
    }
}

File 20 of 37 : EIP712.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)

pragma solidity ^0.8.8;

import "./ECDSA.sol";
import "../ShortStrings.sol";
import "../../interfaces/IERC5267.sol";

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
 * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the
 * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
 *
 * _Available since v3.4._
 *
 * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
 */
abstract contract EIP712 is IERC5267 {
    using ShortStrings for *;

    bytes32 private constant _TYPE_HASH =
        keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _cachedDomainSeparator;
    uint256 private immutable _cachedChainId;
    address private immutable _cachedThis;

    bytes32 private immutable _hashedName;
    bytes32 private immutable _hashedVersion;

    ShortString private immutable _name;
    ShortString private immutable _version;
    string private _nameFallback;
    string private _versionFallback;

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        _name = name.toShortStringWithFallback(_nameFallback);
        _version = version.toShortStringWithFallback(_versionFallback);
        _hashedName = keccak256(bytes(name));
        _hashedVersion = keccak256(bytes(version));

        _cachedChainId = block.chainid;
        _cachedDomainSeparator = _buildDomainSeparator();
        _cachedThis = address(this);
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _cachedThis && block.chainid == _cachedChainId) {
            return _cachedDomainSeparator;
        } else {
            return _buildDomainSeparator();
        }
    }

    function _buildDomainSeparator() private view returns (bytes32) {
        return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }

    /**
     * @dev See {EIP-5267}.
     *
     * _Available since v4.9._
     */
    function eip712Domain()
        public
        view
        virtual
        override
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        return (
            hex"0f", // 01111
            _name.toStringWithFallback(_nameFallback),
            _version.toStringWithFallback(_versionFallback),
            block.chainid,
            address(this),
            bytes32(0),
            new uint256[](0)
        );
    }
}

File 21 of 37 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 22 of 37 : DoubleEndedQueue.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/DoubleEndedQueue.sol)
pragma solidity ^0.8.4;

import "../math/SafeCast.sol";

/**
 * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of
 * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and
 * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that
 * the existing queue contents are left in storage.
 *
 * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be
 * used in storage, and not in memory.
 * ```solidity
 * DoubleEndedQueue.Bytes32Deque queue;
 * ```
 *
 * _Available since v4.6._
 */
library DoubleEndedQueue {
    /**
     * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.
     */
    error Empty();

    /**
     * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.
     */
    error OutOfBounds();

    /**
     * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end
     * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely
     * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.
     *
     * Struct members have an underscore prefix indicating that they are "private" and should not be read or written to
     * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and
     * lead to unexpected behavior.
     *
     * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at
     * data[end - 1].
     */
    struct Bytes32Deque {
        int128 _begin;
        int128 _end;
        mapping(int128 => bytes32) _data;
    }

    /**
     * @dev Inserts an item at the end of the queue.
     */
    function pushBack(Bytes32Deque storage deque, bytes32 value) internal {
        int128 backIndex = deque._end;
        deque._data[backIndex] = value;
        unchecked {
            deque._end = backIndex + 1;
        }
    }

    /**
     * @dev Removes the item at the end of the queue and returns it.
     *
     * Reverts with `Empty` if the queue is empty.
     */
    function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {
        if (empty(deque)) revert Empty();
        int128 backIndex;
        unchecked {
            backIndex = deque._end - 1;
        }
        value = deque._data[backIndex];
        delete deque._data[backIndex];
        deque._end = backIndex;
    }

    /**
     * @dev Inserts an item at the beginning of the queue.
     */
    function pushFront(Bytes32Deque storage deque, bytes32 value) internal {
        int128 frontIndex;
        unchecked {
            frontIndex = deque._begin - 1;
        }
        deque._data[frontIndex] = value;
        deque._begin = frontIndex;
    }

    /**
     * @dev Removes the item at the beginning of the queue and returns it.
     *
     * Reverts with `Empty` if the queue is empty.
     */
    function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {
        if (empty(deque)) revert Empty();
        int128 frontIndex = deque._begin;
        value = deque._data[frontIndex];
        delete deque._data[frontIndex];
        unchecked {
            deque._begin = frontIndex + 1;
        }
    }

    /**
     * @dev Returns the item at the beginning of the queue.
     *
     * Reverts with `Empty` if the queue is empty.
     */
    function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {
        if (empty(deque)) revert Empty();
        int128 frontIndex = deque._begin;
        return deque._data[frontIndex];
    }

    /**
     * @dev Returns the item at the end of the queue.
     *
     * Reverts with `Empty` if the queue is empty.
     */
    function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {
        if (empty(deque)) revert Empty();
        int128 backIndex;
        unchecked {
            backIndex = deque._end - 1;
        }
        return deque._data[backIndex];
    }

    /**
     * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at
     * `length(deque) - 1`.
     *
     * Reverts with `OutOfBounds` if the index is out of bounds.
     */
    function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {
        // int256(deque._begin) is a safe upcast
        int128 idx = SafeCast.toInt128(int256(deque._begin) + SafeCast.toInt256(index));
        if (idx >= deque._end) revert OutOfBounds();
        return deque._data[idx];
    }

    /**
     * @dev Resets the queue back to being empty.
     *
     * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses
     * out on potential gas refunds.
     */
    function clear(Bytes32Deque storage deque) internal {
        deque._begin = 0;
        deque._end = 0;
    }

    /**
     * @dev Returns the number of items in the queue.
     */
    function length(Bytes32Deque storage deque) internal view returns (uint256) {
        // The interface preserves the invariant that begin <= end so we assume this will not overflow.
        // We also assume there are at most int256.max items in the queue.
        unchecked {
            return uint256(int256(deque._end) - int256(deque._begin));
        }
    }

    /**
     * @dev Returns true if the queue is empty.
     */
    function empty(Bytes32Deque storage deque) internal view returns (bool) {
        return deque._end <= deque._begin;
    }
}

File 23 of 37 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 24 of 37 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 25 of 37 : IGovernor.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/IGovernor.sol)

pragma solidity ^0.8.0;

import "../interfaces/IERC165.sol";
import "../interfaces/IERC6372.sol";

/**
 * @dev Interface of the {Governor} core.
 *
 * _Available since v4.3._
 */
abstract contract IGovernor is IERC165, IERC6372 {
    enum ProposalState {
        Pending,
        Active,
        Canceled,
        Defeated,
        Succeeded,
        Queued,
        Expired,
        Executed
    }

    /**
     * @dev Emitted when a proposal is created.
     */
    event ProposalCreated(
        uint256 proposalId,
        address proposer,
        address[] targets,
        uint256[] values,
        string[] signatures,
        bytes[] calldatas,
        uint256 voteStart,
        uint256 voteEnd,
        string description
    );

    /**
     * @dev Emitted when a proposal is canceled.
     */
    event ProposalCanceled(uint256 proposalId);

    /**
     * @dev Emitted when a proposal is executed.
     */
    event ProposalExecuted(uint256 proposalId);

    /**
     * @dev Emitted when a vote is cast without params.
     *
     * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used.
     */
    event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);

    /**
     * @dev Emitted when a vote is cast with params.
     *
     * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used.
     * `params` are additional encoded parameters. Their interpepretation also depends on the voting module used.
     */
    event VoteCastWithParams(
        address indexed voter,
        uint256 proposalId,
        uint8 support,
        uint256 weight,
        string reason,
        bytes params
    );

    /**
     * @notice module:core
     * @dev Name of the governor instance (used in building the ERC712 domain separator).
     */
    function name() public view virtual returns (string memory);

    /**
     * @notice module:core
     * @dev Version of the governor instance (used in building the ERC712 domain separator). Default: "1"
     */
    function version() public view virtual returns (string memory);

    /**
     * @notice module:core
     * @dev See {IERC6372}
     */
    function clock() public view virtual override returns (uint48);

    /**
     * @notice module:core
     * @dev See EIP-6372.
     */
    // solhint-disable-next-line func-name-mixedcase
    function CLOCK_MODE() public view virtual override returns (string memory);

    /**
     * @notice module:voting
     * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to
     * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of
     * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`.
     *
     * There are 2 standard keys: `support` and `quorum`.
     *
     * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`.
     * - `quorum=bravo` means that only For votes are counted towards quorum.
     * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum.
     *
     * If a counting module makes use of encoded `params`, it should  include this under a `params` key with a unique
     * name that describes the behavior. For example:
     *
     * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain.
     * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote.
     *
     * NOTE: The string can be decoded by the standard
     * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`]
     * JavaScript class.
     */
    // solhint-disable-next-line func-name-mixedcase
    function COUNTING_MODE() public view virtual returns (string memory);

    /**
     * @notice module:core
     * @dev Hashing function used to (re)build the proposal id from the proposal details..
     */
    function hashProposal(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) public pure virtual returns (uint256);

    /**
     * @notice module:core
     * @dev Current state of a proposal, following Compound's convention
     */
    function state(uint256 proposalId) public view virtual returns (ProposalState);

    /**
     * @notice module:core
     * @dev Timepoint used to retrieve user's votes and quorum. If using block number (as per Compound's Comp), the
     * snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the
     * following block.
     */
    function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);

    /**
     * @notice module:core
     * @dev Timepoint at which votes close. If using block number, votes close at the end of this block, so it is
     * possible to cast a vote during this block.
     */
    function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);

    /**
     * @notice module:core
     * @dev The account that created a proposal.
     */
    function proposalProposer(uint256 proposalId) public view virtual returns (address);

    /**
     * @notice module:user-config
     * @dev Delay, between the proposal is created and the vote starts. The unit this duration is expressed in depends
     * on the clock (see EIP-6372) this contract uses.
     *
     * This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a
     * proposal starts.
     */
    function votingDelay() public view virtual returns (uint256);

    /**
     * @notice module:user-config
     * @dev Delay between the vote start and vote end. The unit this duration is expressed in depends on the clock
     * (see EIP-6372) this contract uses.
     *
     * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting
     * duration compared to the voting delay.
     */
    function votingPeriod() public view virtual returns (uint256);

    /**
     * @notice module:user-config
     * @dev Minimum number of cast voted required for a proposal to be successful.
     *
     * NOTE: The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows to scale the
     * quorum depending on values such as the totalSupply of a token at this timepoint (see {ERC20Votes}).
     */
    function quorum(uint256 timepoint) public view virtual returns (uint256);

    /**
     * @notice module:reputation
     * @dev Voting power of an `account` at a specific `timepoint`.
     *
     * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or
     * multiple), {ERC20Votes} tokens.
     */
    function getVotes(address account, uint256 timepoint) public view virtual returns (uint256);

    /**
     * @notice module:reputation
     * @dev Voting power of an `account` at a specific `timepoint` given additional encoded parameters.
     */
    function getVotesWithParams(
        address account,
        uint256 timepoint,
        bytes memory params
    ) public view virtual returns (uint256);

    /**
     * @notice module:voting
     * @dev Returns whether `account` has cast a vote on `proposalId`.
     */
    function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);

    /**
     * @dev Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a
     * duration specified by {IGovernor-votingPeriod}.
     *
     * Emits a {ProposalCreated} event.
     */
    function propose(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        string memory description
    ) public virtual returns (uint256 proposalId);

    /**
     * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the
     * deadline to be reached.
     *
     * Emits a {ProposalExecuted} event.
     *
     * Note: some module can modify the requirements for execution, for example by adding an additional timelock.
     */
    function execute(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) public payable virtual returns (uint256 proposalId);

    /**
     * @dev Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e.
     * before the vote starts.
     *
     * Emits a {ProposalCanceled} event.
     */
    function cancel(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) public virtual returns (uint256 proposalId);

    /**
     * @dev Cast a vote
     *
     * Emits a {VoteCast} event.
     */
    function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance);

    /**
     * @dev Cast a vote with a reason
     *
     * Emits a {VoteCast} event.
     */
    function castVoteWithReason(
        uint256 proposalId,
        uint8 support,
        string calldata reason
    ) public virtual returns (uint256 balance);

    /**
     * @dev Cast a vote with a reason and additional encoded parameters
     *
     * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params.
     */
    function castVoteWithReasonAndParams(
        uint256 proposalId,
        uint8 support,
        string calldata reason,
        bytes memory params
    ) public virtual returns (uint256 balance);

    /**
     * @dev Cast a vote using the user's cryptographic signature.
     *
     * Emits a {VoteCast} event.
     */
    function castVoteBySig(
        uint256 proposalId,
        uint8 support,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual returns (uint256 balance);

    /**
     * @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature.
     *
     * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params.
     */
    function castVoteWithReasonAndParamsBySig(
        uint256 proposalId,
        uint8 support,
        string calldata reason,
        bytes memory params,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual returns (uint256 balance);
}

File 26 of 37 : GovernorCompatibilityBravo.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/compatibility/GovernorCompatibilityBravo.sol)

pragma solidity ^0.8.0;

import "../../utils/math/SafeCast.sol";
import "../extensions/IGovernorTimelock.sol";
import "../Governor.sol";
import "./IGovernorCompatibilityBravo.sol";

/**
 * @dev Compatibility layer that implements GovernorBravo compatibility on top of {Governor}.
 *
 * This compatibility layer includes a voting system and requires a {IGovernorTimelock} compatible module to be added
 * through inheritance. It does not include token bindings, nor does it include any variable upgrade patterns.
 *
 * NOTE: When using this module, you may need to enable the Solidity optimizer to avoid hitting the contract size limit.
 *
 * _Available since v4.3._
 */
abstract contract GovernorCompatibilityBravo is IGovernorTimelock, IGovernorCompatibilityBravo, Governor {
    enum VoteType {
        Against,
        For,
        Abstain
    }

    struct ProposalDetails {
        address proposer;
        address[] targets;
        uint256[] values;
        string[] signatures;
        bytes[] calldatas;
        uint256 forVotes;
        uint256 againstVotes;
        uint256 abstainVotes;
        mapping(address => Receipt) receipts;
        bytes32 descriptionHash;
    }

    mapping(uint256 => ProposalDetails) private _proposalDetails;

    // solhint-disable-next-line func-name-mixedcase
    function COUNTING_MODE() public pure virtual override returns (string memory) {
        return "support=bravo&quorum=bravo";
    }

    // ============================================== Proposal lifecycle ==============================================
    /**
     * @dev See {IGovernor-propose}.
     */
    function propose(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        string memory description
    ) public virtual override(IGovernor, Governor) returns (uint256) {
        // Stores the proposal details (if not already present) and executes the propose logic from the core.
        _storeProposal(_msgSender(), targets, values, new string[](calldatas.length), calldatas, description);
        return super.propose(targets, values, calldatas, description);
    }

    /**
     * @dev See {IGovernorCompatibilityBravo-propose}.
     */
    function propose(
        address[] memory targets,
        uint256[] memory values,
        string[] memory signatures,
        bytes[] memory calldatas,
        string memory description
    ) public virtual override returns (uint256) {
        require(signatures.length == calldatas.length, "GovernorBravo: invalid signatures length");
        // Stores the full proposal and fallback to the public (possibly overridden) propose. The fallback is done
        // after the full proposal is stored, so the store operation included in the fallback will be skipped. Here we
        // call `propose` and not `super.propose` to make sure if a child contract override `propose`, whatever code
        // is added there is also executed when calling this alternative interface.
        _storeProposal(_msgSender(), targets, values, signatures, calldatas, description);
        return propose(targets, values, _encodeCalldata(signatures, calldatas), description);
    }

    /**
     * @dev See {IGovernorCompatibilityBravo-queue}.
     */
    function queue(uint256 proposalId) public virtual override {
        (
            address[] memory targets,
            uint256[] memory values,
            bytes[] memory calldatas,
            bytes32 descriptionHash
        ) = _getProposalParameters(proposalId);

        queue(targets, values, calldatas, descriptionHash);
    }

    /**
     * @dev See {IGovernorCompatibilityBravo-execute}.
     */
    function execute(uint256 proposalId) public payable virtual override {
        (
            address[] memory targets,
            uint256[] memory values,
            bytes[] memory calldatas,
            bytes32 descriptionHash
        ) = _getProposalParameters(proposalId);

        execute(targets, values, calldatas, descriptionHash);
    }

    /**
     * @dev Cancel a proposal with GovernorBravo logic.
     */
    function cancel(uint256 proposalId) public virtual override {
        (
            address[] memory targets,
            uint256[] memory values,
            bytes[] memory calldatas,
            bytes32 descriptionHash
        ) = _getProposalParameters(proposalId);

        cancel(targets, values, calldatas, descriptionHash);
    }

    /**
     * @dev Cancel a proposal with GovernorBravo logic. At any moment a proposal can be cancelled, either by the
     * proposer, or by third parties if the proposer's voting power has dropped below the proposal threshold.
     */
    function cancel(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) public virtual override(IGovernor, Governor) returns (uint256) {
        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
        address proposer = _proposalDetails[proposalId].proposer;

        require(
            _msgSender() == proposer || getVotes(proposer, clock() - 1) < proposalThreshold(),
            "GovernorBravo: proposer above threshold"
        );

        return _cancel(targets, values, calldatas, descriptionHash);
    }

    /**
     * @dev Encodes calldatas with optional function signature.
     */
    function _encodeCalldata(
        string[] memory signatures,
        bytes[] memory calldatas
    ) private pure returns (bytes[] memory) {
        bytes[] memory fullcalldatas = new bytes[](calldatas.length);
        for (uint256 i = 0; i < fullcalldatas.length; ++i) {
            fullcalldatas[i] = bytes(signatures[i]).length == 0
                ? calldatas[i]
                : abi.encodePacked(bytes4(keccak256(bytes(signatures[i]))), calldatas[i]);
        }

        return fullcalldatas;
    }

    /**
     * @dev Retrieve proposal parameters by id, with fully encoded calldatas.
     */
    function _getProposalParameters(
        uint256 proposalId
    )
        private
        view
        returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
    {
        ProposalDetails storage details = _proposalDetails[proposalId];
        return (
            details.targets,
            details.values,
            _encodeCalldata(details.signatures, details.calldatas),
            details.descriptionHash
        );
    }

    /**
     * @dev Store proposal metadata (if not already present) for later lookup.
     */
    function _storeProposal(
        address proposer,
        address[] memory targets,
        uint256[] memory values,
        string[] memory signatures,
        bytes[] memory calldatas,
        string memory description
    ) private {
        bytes32 descriptionHash = keccak256(bytes(description));
        uint256 proposalId = hashProposal(targets, values, _encodeCalldata(signatures, calldatas), descriptionHash);

        ProposalDetails storage details = _proposalDetails[proposalId];
        if (details.descriptionHash == bytes32(0)) {
            details.proposer = proposer;
            details.targets = targets;
            details.values = values;
            details.signatures = signatures;
            details.calldatas = calldatas;
            details.descriptionHash = descriptionHash;
        }
    }

    // ==================================================== Views =====================================================
    /**
     * @dev See {IGovernorCompatibilityBravo-proposals}.
     */
    function proposals(
        uint256 proposalId
    )
        public
        view
        virtual
        override
        returns (
            uint256 id,
            address proposer,
            uint256 eta,
            uint256 startBlock,
            uint256 endBlock,
            uint256 forVotes,
            uint256 againstVotes,
            uint256 abstainVotes,
            bool canceled,
            bool executed
        )
    {
        id = proposalId;
        eta = proposalEta(proposalId);
        startBlock = proposalSnapshot(proposalId);
        endBlock = proposalDeadline(proposalId);

        ProposalDetails storage details = _proposalDetails[proposalId];
        proposer = details.proposer;
        forVotes = details.forVotes;
        againstVotes = details.againstVotes;
        abstainVotes = details.abstainVotes;

        ProposalState currentState = state(proposalId);
        canceled = currentState == ProposalState.Canceled;
        executed = currentState == ProposalState.Executed;
    }

    /**
     * @dev See {IGovernorCompatibilityBravo-getActions}.
     */
    function getActions(
        uint256 proposalId
    )
        public
        view
        virtual
        override
        returns (
            address[] memory targets,
            uint256[] memory values,
            string[] memory signatures,
            bytes[] memory calldatas
        )
    {
        ProposalDetails storage details = _proposalDetails[proposalId];
        return (details.targets, details.values, details.signatures, details.calldatas);
    }

    /**
     * @dev See {IGovernorCompatibilityBravo-getReceipt}.
     */
    function getReceipt(uint256 proposalId, address voter) public view virtual override returns (Receipt memory) {
        return _proposalDetails[proposalId].receipts[voter];
    }

    /**
     * @dev See {IGovernorCompatibilityBravo-quorumVotes}.
     */
    function quorumVotes() public view virtual override returns (uint256) {
        return quorum(clock() - 1);
    }

    // ==================================================== Voting ====================================================
    /**
     * @dev See {IGovernor-hasVoted}.
     */
    function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {
        return _proposalDetails[proposalId].receipts[account].hasVoted;
    }

    /**
     * @dev See {Governor-_quorumReached}. In this module, only forVotes count toward the quorum.
     */
    function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {
        ProposalDetails storage details = _proposalDetails[proposalId];
        return quorum(proposalSnapshot(proposalId)) <= details.forVotes;
    }

    /**
     * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes.
     */
    function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
        ProposalDetails storage details = _proposalDetails[proposalId];
        return details.forVotes > details.againstVotes;
    }

    /**
     * @dev See {Governor-_countVote}. In this module, the support follows Governor Bravo.
     */
    function _countVote(
        uint256 proposalId,
        address account,
        uint8 support,
        uint256 weight,
        bytes memory // params
    ) internal virtual override {
        ProposalDetails storage details = _proposalDetails[proposalId];
        Receipt storage receipt = details.receipts[account];

        require(!receipt.hasVoted, "GovernorCompatibilityBravo: vote already cast");
        receipt.hasVoted = true;
        receipt.support = support;
        receipt.votes = SafeCast.toUint96(weight);

        if (support == uint8(VoteType.Against)) {
            details.againstVotes += weight;
        } else if (support == uint8(VoteType.For)) {
            details.forVotes += weight;
        } else if (support == uint8(VoteType.Abstain)) {
            details.abstainVotes += weight;
        } else {
            revert("GovernorCompatibilityBravo: invalid vote type");
        }
    }
}

File 27 of 37 : GovernorVotes.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorVotes.sol)

pragma solidity ^0.8.0;

import { Governor } from "./Governor.sol";
import { IERC5805, IVotes } from "@openzeppelin/contracts/interfaces/IERC5805.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";

/**
 * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token.
 *
 * _Available since v4.3._
 */
abstract contract GovernorVotes is Governor {
    IERC5805 public token;

    constructor(IVotes tokenAddress) {
        token = IERC5805(address(tokenAddress));
    }

    /**
     * @dev Clock (as specified in EIP-6372) is set to match the token's clock. Fallback to block numbers if the token
     * does not implement EIP-6372.
     */
    function clock() public view virtual override returns (uint48) {
        try token.clock() returns (uint48 timepoint) {
            return timepoint;
        } catch {
            return SafeCast.toUint48(block.number);
        }
    }

    /**
     * @dev Machine-readable description of the clock as specified in EIP-6372.
     */
    // solhint-disable-next-line func-name-mixedcase
    function CLOCK_MODE() public view virtual override returns (string memory) {
        try token.CLOCK_MODE() returns (string memory clockmode) {
            return clockmode;
        } catch {
            return "mode=blocknumber&from=default";
        }
    }

    /**
     * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}).
     */
    function _getVotes(
        address account,
        uint256 timepoint,
        bytes memory /*params*/
    ) internal view virtual override returns (uint256) {
        return token.getPastVotes(account, timepoint);
    }
}

File 28 of 37 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 29 of 37 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";
import "./math/SignedMath.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

File 30 of 37 : ShortStrings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol)

pragma solidity ^0.8.8;

import "./StorageSlot.sol";

// | string  | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA   |
// | length  | 0x                                                              BB |
type ShortString is bytes32;

/**
 * @dev This library provides functions to convert short memory strings
 * into a `ShortString` type that can be used as an immutable variable.
 *
 * Strings of arbitrary length can be optimized using this library if
 * they are short enough (up to 31 bytes) by packing them with their
 * length (1 byte) in a single EVM word (32 bytes). Additionally, a
 * fallback mechanism can be used for every other case.
 *
 * Usage example:
 *
 * ```solidity
 * contract Named {
 *     using ShortStrings for *;
 *
 *     ShortString private immutable _name;
 *     string private _nameFallback;
 *
 *     constructor(string memory contractName) {
 *         _name = contractName.toShortStringWithFallback(_nameFallback);
 *     }
 *
 *     function name() external view returns (string memory) {
 *         return _name.toStringWithFallback(_nameFallback);
 *     }
 * }
 * ```
 */
library ShortStrings {
    // Used as an identifier for strings longer than 31 bytes.
    bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;

    error StringTooLong(string str);
    error InvalidShortString();

    /**
     * @dev Encode a string of at most 31 chars into a `ShortString`.
     *
     * This will trigger a `StringTooLong` error is the input string is too long.
     */
    function toShortString(string memory str) internal pure returns (ShortString) {
        bytes memory bstr = bytes(str);
        if (bstr.length > 31) {
            revert StringTooLong(str);
        }
        return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));
    }

    /**
     * @dev Decode a `ShortString` back to a "normal" string.
     */
    function toString(ShortString sstr) internal pure returns (string memory) {
        uint256 len = byteLength(sstr);
        // using `new string(len)` would work locally but is not memory safe.
        string memory str = new string(32);
        /// @solidity memory-safe-assembly
        assembly {
            mstore(str, len)
            mstore(add(str, 0x20), sstr)
        }
        return str;
    }

    /**
     * @dev Return the length of a `ShortString`.
     */
    function byteLength(ShortString sstr) internal pure returns (uint256) {
        uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
        if (result > 31) {
            revert InvalidShortString();
        }
        return result;
    }

    /**
     * @dev Encode a string into a `ShortString`, or write it to storage if it is too long.
     */
    function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {
        if (bytes(value).length < 32) {
            return toShortString(value);
        } else {
            StorageSlot.getStringSlot(store).value = value;
            return ShortString.wrap(_FALLBACK_SENTINEL);
        }
    }

    /**
     * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     */
    function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return toString(value);
        } else {
            return store;
        }
    }

    /**
     * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     *
     * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of
     * actual characters as the UTF-8 encoding of a single character can span over multiple bytes.
     */
    function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return byteLength(value);
        } else {
            return bytes(store).length;
        }
    }
}

File 31 of 37 : IERC5267.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)

pragma solidity ^0.8.0;

interface IERC5267 {
    /**
     * @dev MAY be emitted to signal that the domain could have changed.
     */
    event EIP712DomainChanged();

    /**
     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
     * signature.
     */
    function eip712Domain()
        external
        view
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        );
}

File 32 of 37 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)

pragma solidity ^0.8.0;

import "../utils/introspection/IERC165.sol";

File 33 of 37 : IGovernorTimelock.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (governance/extensions/IGovernorTimelock.sol)

pragma solidity ^0.8.0;

import "../IGovernor.sol";

/**
 * @dev Extension of the {IGovernor} for timelock supporting modules.
 *
 * _Available since v4.3._
 */
abstract contract IGovernorTimelock is IGovernor {
    event ProposalQueued(uint256 proposalId, uint256 eta);

    function timelock() public view virtual returns (address);

    function proposalEta(uint256 proposalId) public view virtual returns (uint256);

    function queue(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) public virtual returns (uint256 proposalId);
}

File 34 of 37 : Governor.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.1) (governance/Governor.sol)

pragma solidity ^0.8.0;

import "../token/ERC721/IERC721Receiver.sol";
import "../token/ERC1155/IERC1155Receiver.sol";
import "../utils/cryptography/ECDSA.sol";
import "../utils/cryptography/EIP712.sol";
import "../utils/introspection/ERC165.sol";
import "../utils/math/SafeCast.sol";
import "../utils/structs/DoubleEndedQueue.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
import "./IGovernor.sol";

/**
 * @dev Core of the governance system, designed to be extended though various modules.
 *
 * This contract is abstract and requires several functions to be implemented in various modules:
 *
 * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote}
 * - A voting module must implement {_getVotes}
 * - Additionally, {votingPeriod} must also be implemented
 *
 * _Available since v4.3._
 */
abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver {
    using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque;

    bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)");
    bytes32 public constant EXTENDED_BALLOT_TYPEHASH =
        keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)");

    // solhint-disable var-name-mixedcase
    struct ProposalCore {
        // --- start retyped from Timers.BlockNumber at offset 0x00 ---
        uint64 voteStart;
        address proposer;
        bytes4 __gap_unused0;
        // --- start retyped from Timers.BlockNumber at offset 0x20 ---
        uint64 voteEnd;
        bytes24 __gap_unused1;
        // --- Remaining fields starting at offset 0x40 ---------------
        bool executed;
        bool canceled;
    }
    // solhint-enable var-name-mixedcase

    string private _name;

    /// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore)
    mapping(uint256 => ProposalCore) private _proposals;

    // This queue keeps track of the governor operating on itself. Calls to functions protected by the
    // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute},
    // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the
    // execution of {onlyGovernance} protected calls can only be achieved through successful proposals.
    DoubleEndedQueue.Bytes32Deque private _governanceCall;

    /**
     * @dev Restricts a function so it can only be executed through governance proposals. For example, governance
     * parameter setters in {GovernorSettings} are protected using this modifier.
     *
     * The governance executing address may be different from the Governor's own address, for example it could be a
     * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these
     * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus,
     * for example, additional timelock proposers are not able to change governance parameters without going through the
     * governance protocol (since v4.6).
     */
    modifier onlyGovernance() {
        require(_msgSender() == _executor(), "Governor: onlyGovernance");
        if (_executor() != address(this)) {
            bytes32 msgDataHash = keccak256(_msgData());
            // loop until popping the expected operation - throw if deque is empty (operation not authorized)
            while (_governanceCall.popFront() != msgDataHash) {}
        }
        _;
    }

    /**
     * @dev Sets the value for {name} and {version}
     */
    constructor(string memory name_) EIP712(name_, version()) {
        _name = name_;
    }

    /**
     * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract)
     */
    receive() external payable virtual {
        require(_executor() == address(this), "Governor: must send to executor");
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
        bytes4 governorCancelId = this.cancel.selector ^ this.proposalProposer.selector;

        bytes4 governorParamsId = this.castVoteWithReasonAndParams.selector ^
            this.castVoteWithReasonAndParamsBySig.selector ^
            this.getVotesWithParams.selector;

        // The original interface id in v4.3.
        bytes4 governor43Id = type(IGovernor).interfaceId ^
            type(IERC6372).interfaceId ^
            governorCancelId ^
            governorParamsId;

        // An updated interface id in v4.6, with params added.
        bytes4 governor46Id = type(IGovernor).interfaceId ^ type(IERC6372).interfaceId ^ governorCancelId;

        // For the updated interface id in v4.9, we use governorCancelId directly.

        return
            interfaceId == governor43Id ||
            interfaceId == governor46Id ||
            interfaceId == governorCancelId ||
            interfaceId == type(IERC1155Receiver).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IGovernor-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IGovernor-version}.
     */
    function version() public view virtual override returns (string memory) {
        return "1";
    }

    /**
     * @dev See {IGovernor-hashProposal}.
     *
     * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array
     * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id
     * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in
     * advance, before the proposal is submitted.
     *
     * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the
     * same proposal (with same operation and same description) will have the same id if submitted on multiple governors
     * across multiple networks. This also means that in order to execute the same operation twice (on the same
     * governor) the proposer will have to change the description in order to avoid proposal id conflicts.
     */
    function hashProposal(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) public pure virtual override returns (uint256) {
        return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash)));
    }

    /**
     * @dev See {IGovernor-state}.
     */
    function state(uint256 proposalId) public view virtual override returns (ProposalState) {
        ProposalCore storage proposal = _proposals[proposalId];

        if (proposal.executed) {
            return ProposalState.Executed;
        }

        if (proposal.canceled) {
            return ProposalState.Canceled;
        }

        uint256 snapshot = proposalSnapshot(proposalId);

        if (snapshot == 0) {
            revert("Governor: unknown proposal id");
        }

        uint256 currentTimepoint = clock();

        if (snapshot >= currentTimepoint) {
            return ProposalState.Pending;
        }

        uint256 deadline = proposalDeadline(proposalId);

        if (deadline >= currentTimepoint) {
            return ProposalState.Active;
        }

        if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) {
            return ProposalState.Succeeded;
        } else {
            return ProposalState.Defeated;
        }
    }

    /**
     * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_.
     */
    function proposalThreshold() public view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev See {IGovernor-proposalSnapshot}.
     */
    function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) {
        return _proposals[proposalId].voteStart;
    }

    /**
     * @dev See {IGovernor-proposalDeadline}.
     */
    function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) {
        return _proposals[proposalId].voteEnd;
    }

    /**
     * @dev Returns the account that created a given proposal.
     */
    function proposalProposer(uint256 proposalId) public view virtual override returns (address) {
        return _proposals[proposalId].proposer;
    }

    /**
     * @dev Amount of votes already cast passes the threshold limit.
     */
    function _quorumReached(uint256 proposalId) internal view virtual returns (bool);

    /**
     * @dev Is the proposal successful or not.
     */
    function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool);

    /**
     * @dev Get the voting weight of `account` at a specific `timepoint`, for a vote as described by `params`.
     */
    function _getVotes(address account, uint256 timepoint, bytes memory params) internal view virtual returns (uint256);

    /**
     * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`.
     *
     * Note: Support is generic and can represent various things depending on the voting system used.
     */
    function _countVote(
        uint256 proposalId,
        address account,
        uint8 support,
        uint256 weight,
        bytes memory params
    ) internal virtual;

    /**
     * @dev Default additional encoded parameters used by castVote methods that don't include them
     *
     * Note: Should be overridden by specific implementations to use an appropriate value, the
     * meaning of the additional params, in the context of that implementation
     */
    function _defaultParams() internal view virtual returns (bytes memory) {
        return "";
    }

    /**
     * @dev See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}.
     */
    function propose(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        string memory description
    ) public virtual override returns (uint256) {
        address proposer = _msgSender();
        require(_isValidDescriptionForProposer(proposer, description), "Governor: proposer restricted");

        uint256 currentTimepoint = clock();
        require(
            getVotes(proposer, currentTimepoint - 1) >= proposalThreshold(),
            "Governor: proposer votes below proposal threshold"
        );

        uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));

        require(targets.length == values.length, "Governor: invalid proposal length");
        require(targets.length == calldatas.length, "Governor: invalid proposal length");
        require(targets.length > 0, "Governor: empty proposal");
        require(_proposals[proposalId].voteStart == 0, "Governor: proposal already exists");

        uint256 snapshot = currentTimepoint + votingDelay();
        uint256 deadline = snapshot + votingPeriod();

        _proposals[proposalId] = ProposalCore({
            proposer: proposer,
            voteStart: SafeCast.toUint64(snapshot),
            voteEnd: SafeCast.toUint64(deadline),
            executed: false,
            canceled: false,
            __gap_unused0: 0,
            __gap_unused1: 0
        });

        emit ProposalCreated(
            proposalId,
            proposer,
            targets,
            values,
            new string[](targets.length),
            calldatas,
            snapshot,
            deadline,
            description
        );

        return proposalId;
    }

    /**
     * @dev See {IGovernor-execute}.
     */
    function execute(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) public payable virtual override returns (uint256) {
        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);

        ProposalState currentState = state(proposalId);
        require(
            currentState == ProposalState.Succeeded || currentState == ProposalState.Queued,
            "Governor: proposal not successful"
        );
        _proposals[proposalId].executed = true;

        emit ProposalExecuted(proposalId);

        _beforeExecute(proposalId, targets, values, calldatas, descriptionHash);
        _execute(proposalId, targets, values, calldatas, descriptionHash);
        _afterExecute(proposalId, targets, values, calldatas, descriptionHash);

        return proposalId;
    }

    /**
     * @dev See {IGovernor-cancel}.
     */
    function cancel(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) public virtual override returns (uint256) {
        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
        require(state(proposalId) == ProposalState.Pending, "Governor: too late to cancel");
        require(_msgSender() == _proposals[proposalId].proposer, "Governor: only proposer can cancel");
        return _cancel(targets, values, calldatas, descriptionHash);
    }

    /**
     * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism
     */
    function _execute(
        uint256 /* proposalId */,
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 /*descriptionHash*/
    ) internal virtual {
        string memory errorMessage = "Governor: call reverted without message";
        for (uint256 i = 0; i < targets.length; ++i) {
            (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]);
            Address.verifyCallResult(success, returndata, errorMessage);
        }
    }

    /**
     * @dev Hook before execution is triggered.
     */
    function _beforeExecute(
        uint256 /* proposalId */,
        address[] memory targets,
        uint256[] memory /* values */,
        bytes[] memory calldatas,
        bytes32 /*descriptionHash*/
    ) internal virtual {
        if (_executor() != address(this)) {
            for (uint256 i = 0; i < targets.length; ++i) {
                if (targets[i] == address(this)) {
                    _governanceCall.pushBack(keccak256(calldatas[i]));
                }
            }
        }
    }

    /**
     * @dev Hook after execution is triggered.
     */
    function _afterExecute(
        uint256 /* proposalId */,
        address[] memory /* targets */,
        uint256[] memory /* values */,
        bytes[] memory /* calldatas */,
        bytes32 /*descriptionHash*/
    ) internal virtual {
        if (_executor() != address(this)) {
            if (!_governanceCall.empty()) {
                _governanceCall.clear();
            }
        }
    }

    /**
     * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as
     * canceled to allow distinguishing it from executed proposals.
     *
     * Emits a {IGovernor-ProposalCanceled} event.
     */
    function _cancel(
        address[] memory targets,
        uint256[] memory values,
        bytes[] memory calldatas,
        bytes32 descriptionHash
    ) internal virtual returns (uint256) {
        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);

        ProposalState currentState = state(proposalId);

        require(
            currentState != ProposalState.Canceled &&
                currentState != ProposalState.Expired &&
                currentState != ProposalState.Executed,
            "Governor: proposal not active"
        );
        _proposals[proposalId].canceled = true;

        emit ProposalCanceled(proposalId);

        return proposalId;
    }

    /**
     * @dev See {IGovernor-getVotes}.
     */
    function getVotes(address account, uint256 timepoint) public view virtual override returns (uint256) {
        return _getVotes(account, timepoint, _defaultParams());
    }

    /**
     * @dev See {IGovernor-getVotesWithParams}.
     */
    function getVotesWithParams(
        address account,
        uint256 timepoint,
        bytes memory params
    ) public view virtual override returns (uint256) {
        return _getVotes(account, timepoint, params);
    }

    /**
     * @dev See {IGovernor-castVote}.
     */
    function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) {
        address voter = _msgSender();
        return _castVote(proposalId, voter, support, "");
    }

    /**
     * @dev See {IGovernor-castVoteWithReason}.
     */
    function castVoteWithReason(
        uint256 proposalId,
        uint8 support,
        string calldata reason
    ) public virtual override returns (uint256) {
        address voter = _msgSender();
        return _castVote(proposalId, voter, support, reason);
    }

    /**
     * @dev See {IGovernor-castVoteWithReasonAndParams}.
     */
    function castVoteWithReasonAndParams(
        uint256 proposalId,
        uint8 support,
        string calldata reason,
        bytes memory params
    ) public virtual override returns (uint256) {
        address voter = _msgSender();
        return _castVote(proposalId, voter, support, reason, params);
    }

    /**
     * @dev See {IGovernor-castVoteBySig}.
     */
    function castVoteBySig(
        uint256 proposalId,
        uint8 support,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override returns (uint256) {
        address voter = ECDSA.recover(
            _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))),
            v,
            r,
            s
        );
        return _castVote(proposalId, voter, support, "");
    }

    /**
     * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}.
     */
    function castVoteWithReasonAndParamsBySig(
        uint256 proposalId,
        uint8 support,
        string calldata reason,
        bytes memory params,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override returns (uint256) {
        address voter = ECDSA.recover(
            _hashTypedDataV4(
                keccak256(
                    abi.encode(
                        EXTENDED_BALLOT_TYPEHASH,
                        proposalId,
                        support,
                        keccak256(bytes(reason)),
                        keccak256(params)
                    )
                )
            ),
            v,
            r,
            s
        );

        return _castVote(proposalId, voter, support, reason, params);
    }

    /**
     * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve
     * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams().
     *
     * Emits a {IGovernor-VoteCast} event.
     */
    function _castVote(
        uint256 proposalId,
        address account,
        uint8 support,
        string memory reason
    ) internal virtual returns (uint256) {
        return _castVote(proposalId, account, support, reason, _defaultParams());
    }

    /**
     * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve
     * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function.
     *
     * Emits a {IGovernor-VoteCast} event.
     */
    function _castVote(
        uint256 proposalId,
        address account,
        uint8 support,
        string memory reason,
        bytes memory params
    ) internal virtual returns (uint256) {
        ProposalCore storage proposal = _proposals[proposalId];
        require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active");

        uint256 weight = _getVotes(account, proposal.voteStart, params);
        _countVote(proposalId, account, support, weight, params);

        if (params.length == 0) {
            emit VoteCast(account, proposalId, support, weight, reason);
        } else {
            emit VoteCastWithParams(account, proposalId, support, weight, reason, params);
        }

        return weight;
    }

    /**
     * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor
     * is some contract other than the governor itself, like when using a timelock, this function can be invoked
     * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake.
     * Note that if the executor is simply the governor itself, use of `relay` is redundant.
     */
    function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance {
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        Address.verifyCallResult(success, returndata, "Governor: relay reverted without message");
    }

    /**
     * @dev Address through which the governor executes action. Will be overloaded by module that execute actions
     * through another contract such as a timelock.
     */
    function _executor() internal view virtual returns (address) {
        return address(this);
    }

    /**
     * @dev See {IERC721Receiver-onERC721Received}.
     */
    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }

    /**
     * @dev See {IERC1155Receiver-onERC1155Received}.
     */
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    /**
     * @dev See {IERC1155Receiver-onERC1155BatchReceived}.
     */
    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155BatchReceived.selector;
    }

    /**
     * @dev Check if the proposer is authorized to submit a proposal with the given description.
     *
     * If the proposal description ends with `#proposer=0x???`, where `0x???` is an address written as a hex string
     * (case insensitive), then the submission of this proposal will only be authorized to said address.
     *
     * This is used for frontrunning protection. By adding this pattern at the end of their proposal, one can ensure
     * that no other address can submit the same proposal. An attacker would have to either remove or change that part,
     * which would result in a different proposal id.
     *
     * If the description does not match this pattern, it is unrestricted and anyone can submit it. This includes:
     * - If the `0x???` part is not a valid hex string.
     * - If the `0x???` part is a valid hex string, but does not contain exactly 40 hex digits.
     * - If it ends with the expected suffix followed by newlines or other whitespace.
     * - If it ends with some other similar suffix, e.g. `#other=abc`.
     * - If it does not end with any such suffix.
     */
    function _isValidDescriptionForProposer(
        address proposer,
        string memory description
    ) internal view virtual returns (bool) {
        uint256 len = bytes(description).length;

        // Length is too short to contain a valid proposer suffix
        if (len < 52) {
            return true;
        }

        // Extract what would be the `#proposer=0x` marker beginning the suffix
        bytes12 marker;
        assembly {
            // - Start of the string contents in memory = description + 32
            // - First character of the marker = len - 52
            //   - Length of "#proposer=0x0000000000000000000000000000000000000000" = 52
            // - We read the memory word starting at the first character of the marker:
            //   - (description + 32) + (len - 52) = description + (len - 20)
            // - Note: Solidity will ignore anything past the first 12 bytes
            marker := mload(add(description, sub(len, 20)))
        }

        // If the marker is not found, there is no proposer suffix to check
        if (marker != bytes12("#proposer=0x")) {
            return true;
        }

        // Parse the 40 characters following the marker as uint160
        uint160 recovered = 0;
        for (uint256 i = len - 40; i < len; ++i) {
            (bool isHex, uint8 value) = _tryHexToUint(bytes(description)[i]);
            // If any of the characters is not a hex digit, ignore the suffix entirely
            if (!isHex) {
                return true;
            }
            recovered = (recovered << 4) | value;
        }

        return recovered == uint160(proposer);
    }

    /**
     * @dev Try to parse a character from a string as a hex value. Returns `(true, value)` if the char is in
     * `[0-9a-fA-F]` and `(false, 0)` otherwise. Value is guaranteed to be in the range `0 <= value < 16`
     */
    function _tryHexToUint(bytes1 char) private pure returns (bool, uint8) {
        uint8 c = uint8(char);
        unchecked {
            // Case 0-9
            if (47 < c && c < 58) {
                return (true, c - 48);
            }
            // Case A-F
            else if (64 < c && c < 71) {
                return (true, c - 55);
            }
            // Case a-f
            else if (96 < c && c < 103) {
                return (true, c - 87);
            }
            // Else: not a hex char
            else {
                return (false, 0);
            }
        }
    }
}

File 35 of 37 : IGovernorCompatibilityBravo.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/compatibility/IGovernorCompatibilityBravo.sol)

pragma solidity ^0.8.0;

import "../IGovernor.sol";

/**
 * @dev Interface extension that adds missing functions to the {Governor} core to provide `GovernorBravo` compatibility.
 *
 * _Available since v4.3._
 */
abstract contract IGovernorCompatibilityBravo is IGovernor {
    /**
     * @dev Proposal structure from Compound Governor Bravo. Not actually used by the compatibility layer, as
     * {{proposal}} returns a very different structure.
     */
    struct Proposal {
        uint256 id;
        address proposer;
        uint256 eta;
        address[] targets;
        uint256[] values;
        string[] signatures;
        bytes[] calldatas;
        uint256 startBlock;
        uint256 endBlock;
        uint256 forVotes;
        uint256 againstVotes;
        uint256 abstainVotes;
        bool canceled;
        bool executed;
        mapping(address => Receipt) receipts;
    }

    /**
     * @dev Receipt structure from Compound Governor Bravo
     */
    struct Receipt {
        bool hasVoted;
        uint8 support;
        uint96 votes;
    }

    /**
     * @dev Part of the Governor Bravo's interface.
     */
    function quorumVotes() public view virtual returns (uint256);

    /**
     * @dev Part of the Governor Bravo's interface: _"The official record of all proposals ever proposed"_.
     */
    function proposals(
        uint256
    )
        public
        view
        virtual
        returns (
            uint256 id,
            address proposer,
            uint256 eta,
            uint256 startBlock,
            uint256 endBlock,
            uint256 forVotes,
            uint256 againstVotes,
            uint256 abstainVotes,
            bool canceled,
            bool executed
        );

    /**
     * @dev Part of the Governor Bravo's interface: _"Function used to propose a new proposal"_.
     */
    function propose(
        address[] memory targets,
        uint256[] memory values,
        string[] memory signatures,
        bytes[] memory calldatas,
        string memory description
    ) public virtual returns (uint256);

    /**
     * @dev Part of the Governor Bravo's interface: _"Queues a proposal of state succeeded"_.
     */
    function queue(uint256 proposalId) public virtual;

    /**
     * @dev Part of the Governor Bravo's interface: _"Executes a queued proposal if eta has passed"_.
     */
    function execute(uint256 proposalId) public payable virtual;

    /**
     * @dev Cancels a proposal only if the sender is the proposer or the proposer delegates' voting power dropped below the proposal threshold.
     */
    function cancel(uint256 proposalId) public virtual;

    /**
     * @dev Part of the Governor Bravo's interface: _"Gets actions of a proposal"_.
     */
    function getActions(
        uint256 proposalId
    )
        public
        view
        virtual
        returns (
            address[] memory targets,
            uint256[] memory values,
            string[] memory signatures,
            bytes[] memory calldatas
        );

    /**
     * @dev Part of the Governor Bravo's interface: _"Gets the receipt for a voter on a given proposal"_.
     */
    function getReceipt(uint256 proposalId, address voter) public view virtual returns (Receipt memory);
}

File 36 of 37 : SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

File 37 of 37 : StorageSlot.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
 * _Available since v4.9 for `string`, `bytes`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */
    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */
    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@src/=src/",
    "@test/=test/",
    "@script-deploy/=script/deploy/",
    "@governance/=lib/frax-governance/",
    "@solmate/=lib/solmate/",
    "@chainlink/=lib/frax-governance/node_modules/@chainlink/",
    "@eth-optimism/=lib/frax-governance/node_modules/@eth-optimism/contracts/",
    "@gnosis.pm/=lib/frax-governance/node_modules/@gnosis.pm/",
    "ds-test/=lib/frax-governance/node_modules/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "frax-governance/=lib/frax-governance/",
    "frax-standard-solidity/=lib/frax-governance/node_modules/frax-standard-solidity/src/",
    "frax-std/=lib/frax-governance/node_modules/frax-standard-solidity/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin-solidity/=lib/frax-governance/node_modules/openzeppelin-solidity/contracts/",
    "openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "safe-contracts/=lib/frax-governance/node_modules/@gnosis.pm/safe-contracts/contracts/",
    "safe-tools/=lib/frax-governance/node_modules/safe-tools/src/",
    "solady/=lib/frax-governance/node_modules/solady/src/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"veFxs","type":"address"},{"internalType":"address","name":"veFxsVotingDelegation","type":"address"},{"internalType":"address[]","name":"safeAllowlist","type":"address[]"},{"internalType":"address[]","name":"delegateCallAllowlist","type":"address[]"},{"internalType":"address payable","name":"timelockController","type":"address"},{"internalType":"uint256","name":"initialVotingDelay","type":"uint256"},{"internalType":"uint256","name":"initialVotingPeriod","type":"uint256"},{"internalType":"uint256","name":"initialProposalThreshold","type":"uint256"},{"internalType":"uint256","name":"quorumNumeratorValue","type":"uint256"},{"internalType":"uint256","name":"initialVotingDelayBlocks","type":"uint256"},{"internalType":"uint256","name":"initialShortCircuitNumerator","type":"uint256"}],"internalType":"struct ConstructorParams","name":"params","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"AlreadyOnDelegateCallAllowlist","type":"error"},{"inputs":[{"internalType":"address","name":"safe","type":"address"}],"name":"AlreadyOnSafeAllowlist","type":"error"},{"inputs":[],"name":"BadBatchArgs","type":"error"},{"inputs":[],"name":"CannotCancelOptimisticTransaction","type":"error"},{"inputs":[],"name":"CannotPropose","type":"error"},{"inputs":[],"name":"CannotRelay","type":"error"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"DelegateCallNotAllowed","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[],"name":"InvalidTimepoint","type":"error"},{"inputs":[],"name":"NonceReserved","type":"error"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"NotOnDelegateCallAllowlist","type":"error"},{"inputs":[{"internalType":"address","name":"safe","type":"address"}],"name":"NotOnSafeAllowlist","type":"error"},{"inputs":[],"name":"NotTimelockController","type":"error"},{"inputs":[],"name":"ParamLengthsNotEqual","type":"error"},{"inputs":[],"name":"ProposalAlreadyCanceled","type":"error"},{"inputs":[],"name":"SameSafeVotingPeriod","type":"error"},{"inputs":[],"name":"SenderVotingWeightBelowProposalThreshold","type":"error"},{"inputs":[],"name":"ShortCircuitNumeratorGreaterThanQuorumDenominator","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"}],"name":"TransactionAlreadyApproved","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"WrongNonce","type":"error"},{"inputs":[],"name":"WrongProposalState","type":"error"},{"inputs":[],"name":"WrongSafeSignatureType","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"}],"name":"AddToDelegateCallAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"safe","type":"address"}],"name":"AddToSafeAllowlist","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string[]","name":"signatures","type":"string[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"voteStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"voteEnd","type":"uint256"},{"indexed":false,"internalType":"string","name":"description","type":"string"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldProposalThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newProposalThreshold","type":"uint256"}],"name":"ProposalThresholdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldQuorumNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newQuorumNumerator","type":"uint256"}],"name":"QuorumNumeratorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"}],"name":"RemoveFromDelegateCallAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"safe","type":"address"}],"name":"RemoveFromSafeAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"safe","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldSafeVotingPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newSafeVotingPeriod","type":"uint256"}],"name":"SafeVotingPeriodSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldShortCircuitNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newShortCircuitNumerator","type":"uint256"}],"name":"ShortCircuitNumeratorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"safe","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"TransactionProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldVotingDelegation","type":"address"},{"indexed":false,"internalType":"address","name":"newVotingDelegation","type":"address"}],"name":"VeFxsVotingDelegationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"VoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"VoteCastWithParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingDelayBlocks","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingDelayBlocks","type":"uint256"}],"name":"VotingDelayBlocksSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"VotingDelaySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"VotingPeriodSet","type":"event"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"$delegateCallAllowlist","outputs":[{"internalType":"uint256","name":"status","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"safe","type":"address"},{"internalType":"uint256","name":"safeNonce","type":"uint256"}],"name":"$gnosisSafeToNonceToTxHash","outputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"safe","type":"address"}],"name":"$safeAllowlist","outputs":[{"internalType":"uint256","name":"status","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"safe","type":"address"}],"name":"$safeVotingPeriod","outputs":[{"internalType":"uint256","name":"votingPeriod","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"snapshot","type":"uint256"}],"name":"$snapshotTimestampToSnapshotBlockNumber","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"$votingDelayBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLOCK_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COUNTING_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"EXTENDED_BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIMELOCK_CONTROLLER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VE_FXS","outputs":[{"internalType":"contract IVeFxs","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"teamSafe","type":"address"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"abortTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"contracts","type":"address[]"}],"name":"addToDelegateCallAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"safes","type":"address[]"}],"name":"addToSafeAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"teamSafe","type":"address"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"enum Enum.Operation","name":"operation","type":"uint8"},{"internalType":"uint256","name":"safeTxGas","type":"uint256"},{"internalType":"uint256","name":"baseGas","type":"uint256"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"address","name":"refundReceiver","type":"address"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"internalType":"struct IFraxGovernorOmega.TxHashArgs","name":"args","type":"tuple"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"addTransaction","outputs":[{"internalType":"uint256","name":"optimisticProposalId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"teamSafes","type":"address[]"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"enum Enum.Operation","name":"operation","type":"uint8"},{"internalType":"uint256","name":"safeTxGas","type":"uint256"},{"internalType":"uint256","name":"baseGas","type":"uint256"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"address","name":"refundReceiver","type":"address"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"internalType":"struct IFraxGovernorOmega.TxHashArgs[]","name":"args","type":"tuple[]"},{"internalType":"bytes[]","name":"signatures","type":"bytes[]"}],"name":"batchAddTransaction","outputs":[{"internalType":"uint256[]","name":"optimisticProposalIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"proposalId","type":"uint256[]"},{"internalType":"uint8[]","name":"support","type":"uint8[]"}],"name":"bulkCastVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"cancel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"}],"name":"castVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteBySig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"castVoteWithReason","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"castVoteWithReasonAndParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteWithReasonAndParamsBySig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clock","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"execute","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"fractionalVoteNonce","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"getVotesWithParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"hasVoted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"hashProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"lastSnapshotTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalProposer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalVotes","outputs":[{"internalType":"uint256","name":"againstVotes","type":"uint256"},{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"abstainVotes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint40","name":"voteStart","type":"uint40"},{"internalType":"uint40","name":"voteEnd","type":"uint40"},{"internalType":"bool","name":"executed","type":"bool"},{"internalType":"bool","name":"canceled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"string","name":"","type":"string"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"quorum","outputs":[{"internalType":"uint256","name":"quorumAtTimepoint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"quorumNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"teamSafe","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"rejectTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"relay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"contracts","type":"address[]"}],"name":"removeFromDelegateCallAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"safes","type":"address[]"}],"name":"removeFromSafeAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newProposalThreshold","type":"uint256"}],"name":"setProposalThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"safe","type":"address"},{"internalType":"uint256","name":"newSafeVotingPeriod","type":"uint256"}],"name":"setSafeVotingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"veFxsVotingDelegation","type":"address"}],"name":"setVeFxsVotingDelegation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"setVotingDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingDelayBlocks","type":"uint256"}],"name":"setVotingDelayBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"setVotingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shortCircuitNumerator","outputs":[{"internalType":"uint256","name":"latestShortCircuitNumerator","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"shortCircuitNumerator","outputs":[{"internalType":"uint256","name":"shortCircuitNumeratorAtTimepoint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"shortCircuitThreshold","outputs":[{"internalType":"uint256","name":"shortCircuitThresholdAtTimepoint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"state","outputs":[{"internalType":"enum IGovernor.ProposalState","name":"proposalState","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC5805","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newQuorumNumerator","type":"uint256"}],"name":"updateQuorumNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newShortCircuitNumerator","type":"uint256"}],"name":"updateShortCircuitNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"voteWeightCast","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101a060405234801562000011575f80fd5b506040516200715b3803806200715b833981016040819052620000349162000e87565b60405180610120016040528082602001516001600160a01b0316815260200182604001516001600160a01b03168152602001825f015181526020018260c0015181526020018260e0015181526020018261010001518152602001826101200151815260200182610140015181526020018261016001518152508060c001518160200151826060015183608001518460a00151856040015180620000dc620002a560201b60201c565b620000e8825f620002c0565b61012052620000f9816001620002c0565b61014052815160208084019190912060e052815190820120610100524660a0526200018660e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b60805250503060c05260026200019d82826200104a565b50620001ab905083620002f8565b620001b68262000339565b620001c181620003df565b5050600980546001600160a01b0319166001600160a01b03939093169290921790915550620001f08162000420565b5080516001600160a01b031661016052610100810151620002119062000527565b60e08101516200022190620005b6565b602080820151604080515f81526001600160a01b03909216928201929092527fc255828f3e19c78de5df3dd5b6706d49bd5dd58e76275f97bd69987870099520910160405180910390a15060a08101516001600160a01b03166101805260608101516200028e90620005f5565b60808101516200029e906200073e565b50620011ea565b6040805180820190915260018152603160f81b602082015290565b5f602083511015620002df57620002d78362000894565b9050620002f2565b81620002ec84826200104a565b5060ff90505b92915050565b60065460408051918252602082018390527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a1600655565b5f81116200039e5760405162461bcd60e51b815260206004820152602760248201527f476f7665726e6f7253657474696e67733a20766f74696e6720706572696f6420604482015266746f6f206c6f7760c81b60648201526084015b60405180910390fd5b60075460408051918252602082018390527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a1600755565b60085460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600855565b6064811115620004a55760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72566f74657351756f72756d4672616374696f6e3a2071756f60448201527f72756d4e756d657261746f72206f7665722071756f72756d44656e6f6d696e616064820152623a37b960e91b608482015260a40162000395565b5f620004b0620008d6565b9050620004e7620004d2620004c4620008f1565b65ffffffffffff1662000973565b620004dd84620009dd565b600a919062000a47565b505060408051828152602081018490527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b463399791015b60405180910390a15050565b606481111562000549576040516271e29960e21b815260040160405180910390fd5b5f6200055462000a63565b90506200057d62000568620004c4620008f1565b6200057384620009dd565b600f919062000a47565b505060408051828152602081018490527fdd2b8b2d874e19a344cba53b9fb534ea748ef117ed4b75c67569a7948645419391016200051b565b600e80549082905560408051828152602081018490527fd3c1cdfd662fbb8e44190410d3a0d46855746182cb8d1e5e41bc84f5afecef4f91016200051b565b5f5b81518110156200073a5760125f83838151811062000619576200061962001112565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205460010362000690578181815181106200065e576200065e62001112565b6020026020010151604051630b58d77560e41b81526004016200039591906001600160a01b0391909116815260200190565b600160125f848481518110620006aa57620006aa62001112565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2081905550818181518110620006ea57620006ea62001112565b60200260200101516001600160a01b03167f4149776fc93a7a68120df1638269488e1915cd17b09b0ab741e6bf768a38c46d60405160405180910390a262000732816200113a565b9050620005f7565b5050565b5f5b81518110156200073a5760135f83838151811062000762576200076262001112565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103620007d957818181518110620007a757620007a762001112565b60200260200101516040516394369fd360e01b81526004016200039591906001600160a01b0391909116815260200190565b600160135f848481518110620007f357620007f362001112565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f20819055507ff48d3b938905d7162ca91551f61d4d458d43159e04847eb28ed7d94fbdb3bc2f82828151811062000854576200085462001112565b60200260200101516040516200087991906001600160a01b0391909116815260200190565b60405180910390a16200088c816200113a565b905062000740565b5f80829050601f81511115620008c1578260405163305a27a960e01b815260040162000395919062001155565b8051620008ce8262001189565b179392505050565b5f620008e3600a62000a6b565b6001600160e01b0316905090565b600954604080516324776b7d60e21b815290515f926001600160a01b0316916391ddadf49160048083019260209291908290030181865afa92505050801562000959575060408051601f3d908101601f191682019092526200095691810190620011ad565b60015b6200096e57620009694362000ab6565b905090565b919050565b5f63ffffffff821115620009d95760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b606482015260840162000395565b5090565b5f6001600160e01b03821115620009d95760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b606482015260840162000395565b5f8062000a5685858562000b1e565b915091505b935093915050565b5f620008e3600f5b80545f90801562000aad5762000a958362000a88600184620011d4565b5f91825260209091200190565b5464010000000090046001600160e01b031662000aaf565b5f5b9392505050565b5f65ffffffffffff821115620009d95760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b606482015260840162000395565b82545f908190801562000c70575f62000b3e8762000a88600185620011d4565b60408051808201909152905463ffffffff8082168084526401000000009092046001600160e01b03166020840152919250908716101562000bc25760405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b6579730000000000604482015260640162000395565b805163ffffffff80881691160362000c10578462000be78862000a88600186620011d4565b80546001600160e01b03929092166401000000000263ffffffff90921691909117905562000c5f565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d555f8d81529190912094519151909216640100000000029216919091179101555b60200151925083915062000a5b9050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a555f8a81529182209551925190931664010000000002919093161792019190915590508162000a5b565b634e487b7160e01b5f52604160045260245ffd5b60405161018081016001600160401b038111828210171562000d045762000d0462000cca565b60405290565b604051601f8201601f191681016001600160401b038111828210171562000d355762000d3562000cca565b604052919050565b5f5b8381101562000d5957818101518382015260200162000d3f565b50505f910152565b5f82601f83011262000d71575f80fd5b81516001600160401b0381111562000d8d5762000d8d62000cca565b62000da2601f8201601f191660200162000d0a565b81815284602083860101111562000db7575f80fd5b62000dca82602083016020870162000d3d565b949350505050565b6001600160a01b038116811462000de7575f80fd5b50565b80516200096e8162000dd2565b5f82601f83011262000e07575f80fd5b815160206001600160401b0382111562000e255762000e2562000cca565b8160051b62000e3682820162000d0a565b928352848101820192828101908785111562000e50575f80fd5b83870192505b8483101562000e7c57825162000e6c8162000dd2565b8252918301919083019062000e56565b979650505050505050565b5f6020828403121562000e98575f80fd5b81516001600160401b038082111562000eaf575f80fd5b90830190610180828603121562000ec4575f80fd5b62000ece62000cde565b82518281111562000edd575f80fd5b62000eeb8782860162000d61565b82525062000efc6020840162000dea565b602082015262000f0f6040840162000dea565b604082015260608301518281111562000f26575f80fd5b62000f348782860162000df7565b60608301525060808301518281111562000f4c575f80fd5b62000f5a8782860162000df7565b60808301525062000f6e60a0840162000dea565b60a082015260c0838101519082015260e080840151908201526101008084015190820152610120808401519082015261014080840151908201526101609283015192810192909252509392505050565b600181811c9082168062000fd357607f821691505b60208210810362000ff257634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562001045575f81815260208120601f850160051c81016020861015620010205750805b601f850160051c820191505b8181101562001041578281556001016200102c565b5050505b505050565b81516001600160401b0381111562001066576200106662000cca565b6200107e8162001077845462000fbe565b8462000ff8565b602080601f831160018114620010b4575f84156200109c5750858301515b5f19600386901b1c1916600185901b17855562001041565b5f85815260208120601f198616915b82811015620010e457888601518255948401946001909101908401620010c3565b50858210156200110257878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f600182016200114e576200114e62001126565b5060010190565b602081525f82518060208401526200117581604085016020870162000d3d565b601f01601f19169190910160400192915050565b8051602080830151919081101562000ff2575f1960209190910360031b1b16919050565b5f60208284031215620011be575f80fd5b815165ffffffffffff8116811462000aaf575f80fd5b81810381811115620002f257620002f262001126565b60805160a05160c05160e0516101005161012051610140516101605161018051615ef6620012655f395f81816108f40152612a7301525f81816108200152818161269d01526137bb01525f6119e401525f6119ba01525f613f2101525f613ef901525f613e5401525f613e7e01525f613ea80152615ef65ff3fe6080604052600436106103f8575f3560e01c806384b0196e1161020a578063c28bc2fa1161011e578063e80f1aa7116100a8578063ece40cc111610078578063ece40cc114610dcb578063f23a6e6114610dea578063f8cc2e3c14610e15578063f8ce560a14610e34578063fc0c546a14610e53575f80fd5b8063e80f1aa714610d4f578063ea0217cf14610d6e578063eb9019d414610d8d578063ec2de58b14610dac575f80fd5b8063d914e172116100ee578063d914e17214610c8a578063dd4e2ba514610cb5578063deaaa7cc14610cc9578063df482caf14610cfc578063dfc3c9e714610d30575f80fd5b8063c28bc2fa14610c25578063c3dcf92214610c38578063c59057e414610c57578063ccb8370b14610c76575f80fd5b8063aa75a3c21161019f578063bc197c811161016f578063bc197c8114610b57578063be13109414610b82578063be74baf214610ba1578063c01f9e3714610bb6578063c1de4eed14610bef575f80fd5b8063aa75a3c214610ae6578063b021d2c314610b05578063b12c327714610b24578063b58131b014610b43575f80fd5b806397c3d334116101da57806397c3d33414610a8b5780639a802a6d14610a9e578063a7713a7014610abd578063a89f263814610ad1575f80fd5b806384b0196e146109ef57806386e80e9014610a165780638bb53cd314610a4157806391ddadf414610a60575f80fd5b8063438596321161030c5780635c0855891161029657806364cda3d41161026657806364cda3d41461095457806370b0f6601461097357806377d76602146109925780637b3c71d3146109b15780637d5e81e2146109d0575f80fd5b80635c085589146108c45780635d049c0a146108e35780635f398a141461091657806360c4247f14610935575f80fd5b80634bf5d7e9116102dc5780634bf5d7e9146107fb578063506d1f811461080f578063544ffc9c1461084257806354fd4d501461087c57806356781388146108a5575f80fd5b8063438596321461074657806343ec3e0914610792578063452115d6146107b15780634571969b146107d0575f80fd5b8063150b7a021161038d5780632fe3e2611161035d5780632fe3e2611461067d578063342cfab6146106b05780633932abb1146106e75780633bccf4fd146106fb5780633e4f49e61461071a575f80fd5b8063150b7a02146105dd5780632214a33f146106205780632656227d1461064b5780632d63f6931461065e575f80fd5b806306f3f9e6116103c857806306f3f9e61461052557806306fdde0314610544578063072c8e0d14610565578063143489d014610591575f80fd5b8063013cf08b1461040e57806301ffc9a7146104b957806302a251a3146104e85780630342018114610506575f80fd5b3661040a57005b60405180910390fd5b005b5f80fd5b348015610419575f80fd5b50610473610428366004614b1f565b60036020525f90815260409020546001600160a01b0381169064ffffffffff600160a01b8204811691600160c81b81049091169060ff600160f01b8204811691600160f81b90041685565b604080516001600160a01b03909616865264ffffffffff9485166020870152939092169284019290925290151560608301521515608082015260a0015b60405180910390f35b3480156104c4575f80fd5b506104d86104d3366004614b36565b610e72565b60405190151581526020016104b0565b3480156104f3575f80fd5b506007545b6040519081526020016104b0565b348015610511575f80fd5b506104f8610520366004614c9d565b610f0e565b348015610530575f80fd5b5061040861053f366004614b1f565b610f2c565b34801561054f575f80fd5b50610558610f40565b6040516104b09190614d89565b348015610570575f80fd5b5061058461057f366004614ddb565b610fd0565b6040516104b09190614ea6565b34801561059c575f80fd5b506105c56105ab366004614b1f565b5f908152600360205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016104b0565b3480156105e8575f80fd5b506106076105f7366004614ece565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016104b0565b34801561062b575f80fd5b506104f861063a366004614f31565b60146020525f908152604090205481565b6104f861065936600461509e565b6110f7565b348015610669575f80fd5b506104f8610678366004614b1f565b611223565b348015610688575f80fd5b506104f87fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af8881565b3480156106bb575f80fd5b506106cf6106ca366004615127565b611242565b6040516001600160801b0390911681526020016104b0565b3480156106f2575f80fd5b506006546104f8565b348015610706575f80fd5b506104f8610715366004615151565b611274565b348015610725575f80fd5b50610739610734366004614b1f565b611307565b6040516104b091906151af565b348015610751575f80fd5b506104d8610760366004615127565b5f918252600c602090815260408084206001600160a01b039390931684529190529020546001600160801b0316151590565b34801561079d575f80fd5b506104086107ac366004614b1f565b611478565b3480156107bc575f80fd5b506104f86107cb36600461509e565b611489565b3480156107db575f80fd5b506104f86107ea366004614f31565b60126020525f908152604090205481565b348015610806575f80fd5b506105586114a6565b34801561081a575f80fd5b506105c57f000000000000000000000000000000000000000000000000000000000000000081565b34801561084d575f80fd5b5061086161085c366004614b1f565b611550565b604080519384526020840192909252908201526060016104b0565b348015610887575f80fd5b506040805180820190915260018152603160f81b6020820152610558565b3480156108b0575f80fd5b506104f86108bf3660046151c9565b611581565b3480156108cf575f80fd5b506104086108de3660046151ea565b6115a8565b3480156108ee575f80fd5b506105c57f000000000000000000000000000000000000000000000000000000000000000081565b348015610921575f80fd5b506104f8610930366004615212565b6117bf565b348015610940575f80fd5b506104f861094f366004614b1f565b611807565b34801561095f575f80fd5b5061040861096e366004614b1f565b6118a4565b34801561097e575f80fd5b5061040861098d366004614b1f565b6118b5565b34801561099d575f80fd5b506104086109ac36600461528f565b6118c6565b3480156109bc575f80fd5b506104f86109cb3660046152f5565b61194d565b3480156109db575f80fd5b506104f86109ea36600461533e565b611993565b3480156109fa575f80fd5b50610a036119ad565b6040516104b097969594939291906153ea565b348015610a21575f80fd5b506104f8610a30366004614f31565b60136020525f908152604090205481565b348015610a4c575f80fd5b50610408610a5b36600461544b565b611a33565b348015610a6b575f80fd5b50610a74611ba5565b60405165ffffffffffff90911681526020016104b0565b348015610a96575f80fd5b5060646104f8565b348015610aa9575f80fd5b506104f8610ab8366004615489565b611c1c565b348015610ac8575f80fd5b506104f8611c32565b348015610adc575f80fd5b506104f8600e5481565b348015610af1575f80fd5b50610408610b00366004614f31565b611c4b565b348015610b10575f80fd5b506104f8610b1f3660046154db565b611c5c565b348015610b2f575f80fd5b50610408610b3e366004615548565b611fb6565b348015610b4e575f80fd5b506104f861231d565b348015610b62575f80fd5b50610607610b71366004615596565b63bc197c8160e01b95945050505050565b348015610b8d575f80fd5b50610408610b9c36600461544b565b612327565b348015610bac575f80fd5b506104f860115481565b348015610bc1575f80fd5b506104f8610bd0366004614b1f565b5f90815260036020526040902054600160c81b900464ffffffffff1690565b348015610bfa575f80fd5b506104f8610c093660046151ea565b601560209081525f928352604080842090915290825290205481565b610408610c3336600461561e565b61236e565b348015610c43575f80fd5b50610408610c5236600461544b565b612387565b348015610c62575f80fd5b506104f8610c7136600461509e565b6124ed565b348015610c81575f80fd5b506104f8612526565b348015610c95575f80fd5b506104f8610ca4366004614b1f565b60106020525f908152604090205481565b348015610cc0575f80fd5b50610558612531565b348015610cd4575f80fd5b506104f87f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b348015610d07575f80fd5b506106cf610d16366004614f31565b600d6020525f90815260409020546001600160801b031681565b348015610d3b575f80fd5b506104f8610d4a366004614b1f565b612551565b348015610d5a575f80fd5b50610408610d6936600461544b565b6125dd565b348015610d79575f80fd5b50610408610d88366004614b1f565b612620565b348015610d98575f80fd5b506104f8610da73660046151ea565b612631565b348015610db7575f80fd5b506104f8610dc6366004614b1f565b612650565b348015610dd6575f80fd5b50610408610de5366004614b1f565b612722565b348015610df5575f80fd5b50610607610e0436600461565b565b63f23a6e6160e01b95945050505050565b348015610e20575f80fd5b50610408610e2f3660046151ea565b612733565b348015610e3f575f80fd5b506104f8610e4e366004614b1f565b6127d2565b348015610e5e575f80fd5b506009546105c5906001600160a01b031681565b5f63288ace0360e11b6318df743f60e31b63bf26d89760e01b6379dd796f60e01b6001600160e01b03198616821480610eb757506001600160e01b0319868116908216145b80610ece57506001600160e01b0319868116908516145b80610ee957506001600160e01b03198616630271189760e51b145b80610f0457506301ffc9a760e01b6001600160e01b03198716145b9695505050505050565b5f610f1f8989898989898989612809565b9998505050505050505050565b610f34612a68565b610f3d81612ab3565b50565b606060028054610f4f906156ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7b906156ba565b8015610fc65780601f10610f9d57610100808354040283529160200191610fc6565b820191905f5260205f20905b815481529060010190602001808311610fa957829003601f168201915b5050505050905090565b60608584141580610fe15750858214155b15610fff57604051630a1eb2d160e11b815260040160405180910390fd5b856001600160401b0381111561101757611017614bb1565b604051908082528060200260200182016040528015611040578160200160208202803683370190505b5090505f5b868110156110ec576110bf888883818110611062576110626156f2565b90506020020160208101906110779190614f31565b878784818110611089576110896156f2565b905060200281019061109b9190615706565b8686858181106110ad576110ad6156f2565b9050602002810190610b1f9190615725565b8282815181106110d1576110d16156f2565b60209081029190910101526110e58161577b565b9050611045565b509695505050505050565b5f80611105868686866124ed565b90505f61111182611307565b905060048160078111156111275761112761519b565b1480611144575060058160078111156111425761114261519b565b145b61119a5760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c206e6f74207375636365737366756044820152601b60fa1b60648201526084016103ff565b5f8281526003602052604090819020805460ff60f01b1916600160f01b179055517f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f906111ea9084815260200190565b60405180910390a16111ff8288888888612bae565b61120c8288888888612c39565b6112198288888888612bae565b5095945050505050565b5f90815260036020526040902054600160a01b900464ffffffffff1690565b5f828152600c602090815260408083206001600160a01b03851684529091529020546001600160801b03165b92915050565b604080517f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f602082015290810186905260ff851660608201525f9081906112e0906112d8906080015b60405160208183030381529060405280519060200120612d32565b868686612d5e565b90506112fc87828860405180602001604052805f815250612d7a565b979650505050505050565b5f8181526003602052604081208054600160f01b900460ff161561132e5750600792915050565b8054600160f81b900460ff16156113485750600292915050565b5f61135284611223565b9050805f036113a35760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a20756e6b6e6f776e2070726f706f73616c20696400000060448201526064016103ff565b5f6113ac611ba5565b65ffffffffffff16905080821015806113d257505f828152601060205260409020544311155b156113e157505f949350505050565b6113ea85612da4565b156113fa57506004949350505050565b61140385612dd2565b1561141357506003949350505050565b5f85815260036020526040902054600160c81b900464ffffffffff168181106114425750600195945050505050565b61144b86612deb565b801561145b575061145b86612e3c565b1561146c5750600395945050505050565b50600495945050505050565b611480612a68565b610f3d81612e70565b5f60405160016205739760e41b0319815260040160405180910390fd5b60095460408051634bf5d7e960e01b815290516060926001600160a01b031691634bf5d7e9916004808301925f9291908290030181865afa92505050801561150f57506040513d5f823e601f3d908101601f1916820160405261150c9190810190615793565b60015b61154b575060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b919050565b5f908152600b6020526040902080546001909101546001600160801b0380831693600160801b909304811692911690565b5f803390506115a084828560405180602001604052805f815250612d7a565b949350505050565b6001600160a01b0382165f9081526015602090815260408083208484529091528120549080806115d88685612ef4565b91945092509050600360408051602081019091525f905261161e6107348585857fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706124ed565b600781111561162f5761162f61519b565b1461164d57604051630fd1155b60e41b815260040160405180910390fd5b5f8690505f6116cc826040518061014001604052808b6001600160a01b031681526020015f815260200160405180602001604052805f81525081526020015f600181111561169d5761169d61519b565b81525f6020820181905260408201819052606082018190526080820181905260a082015260c0018a9052613016565b604051631f60ca5d60e21b8152306004820152602481018290529091506001600160a01b03831690637d832974906044016020604051808303815f875af1158015611719573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061173d91906157fb565b60010361176057604051635c0abc6d60e11b8152600481018290526024016103ff565b60405163d4d9bdcd60e01b8152600481018290526001600160a01b0383169063d4d9bdcd906024015f604051808303815f87803b15801561179f575f80fd5b505af11580156117b1573d5f803e3d5ffd5b505050505050505050505050565b5f803390506112fc87828888888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508a92506130bd915050565b600a80545f91829061181a600184615812565b8154811061182a5761182a6156f2565b5f9182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b0316928201929092529150841061187f57602001516001600160e01b03169392505050565b61189361188b85613214565b600a9061327c565b6001600160e01b0316949350505050565b6118ac612a68565b610f3d81613329565b6118bd612a68565b610f3d81613367565b828181146118e75760405163a669fc0560e01b815260040160405180910390fd5b5f5b8181101561194557611934868683818110611906576119066156f2565b9050602002013585858481811061191f5761191f6156f2565b90506020020160208101906108bf9190615825565b5061193e8161577b565b90506118e9565b505050505050565b5f80339050610f0486828787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250612d7a92505050565b5f60405163098bb82f60e01b815260040160405180910390fd5b5f606080828080836119df7f0000000000000000000000000000000000000000000000000000000000000000836133a8565b611a0a7f000000000000000000000000000000000000000000000000000000000000000060016133a8565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b611a3b612a68565b5f5b81811015611ba05760135f848484818110611a5a57611a5a6156f2565b9050602002016020810190611a6f9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f20545f03611ae157828282818110611aa757611aa76156f2565b9050602002016020810190611abc9190614f31565b604051630ee1e0b360e41b81526001600160a01b0390911660048201526024016103ff565b60135f848484818110611af657611af66156f2565b9050602002016020810190611b0b9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f205f90557f3f75b27f9b6f643d57ab0006da862b383ffc26813fc08462f2d56270aaa950c0838383818110611b6057611b606156f2565b9050602002016020810190611b759190614f31565b6040516001600160a01b03909116815260200160405180910390a1611b998161577b565b9050611a3d565b505050565b600954604080516324776b7d60e21b815290515f926001600160a01b0316916391ddadf49160048083019260209291908290030181865afa925050508015611c0a575060408051601f3d908101601f19168201909252611c079181019061583e565b60015b61154b57611c1743613451565b905090565b5f611c288484846134b7565b90505b9392505050565b5f611c3d600a61352a565b6001600160e01b0316905090565b611c53612a68565b610f3d81613561565b5f611c66856135bb565b6001611c786080860160608701615871565b6001811115611c8957611c8961519b565b148015611cc6575060135f611ca16020870187614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f2054600114155b15611cfd57611cd86020850185614f31565b6040516317645e7d60e21b81526001600160a01b0390911660048201526024016103ff565b5f8590505f816001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d6291906157fb565b9050611da485858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508592506135f1915050565b6001600160a01b0387165f9081526015602090815260408083206101208a0135845290915290205415611dea57604051639e01d15b60e01b815260040160405180910390fd5b816001600160a01b031663affed0e06040518163ffffffff1660e01b81526004016020604051808303815f875af1158015611e27573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e4b91906157fb565b8661012001351015611e705760405163d9c6386f60e01b815260040160405180910390fd5b5f611e8383611e7e8961588a565b613016565b90506001600160a01b0383166312fb68e082611ea260408b018b615725565b8a8a886040518763ffffffff1660e01b8152600401611ec69695949392919061596e565b5f6040518083038186803b158015611edc575f80fd5b505afa158015611eee573d5f803e3d5ffd5b505050505f805f611eff8b85612ef4565b925092509250611f2083838360405180602001604052805f8152508f613658565b96508360155f8d6001600160a01b03166001600160a01b031681526020019081526020015f205f8c610120013581526020019081526020015f208190555086848c6001600160a01b03167f5ed3fb2763971f1f5e3d1e6f215e92ebe28160b512c2da07f4b12a46021adb0b8d6101200135604051611fa091815260200190565b60405180910390a4505050505050949350505050565b611fbf836135bb565b5f8390505f816001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612000573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061202491906157fb565b905061206684848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508592506135f1915050565b5f826001600160a01b031663affed0e06040518163ffffffff1660e01b81526004016020604051808303815f875af11580156120a4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120c891906157fb565b90505f836001600160a01b031663d8d11f78885f805f805f805f8b6040518a63ffffffff1660e01b8152600401612107999897969594939291906159c2565b602060405180830381865afa158015612122573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214691906157fb565b6040516297db4760e51b81529091506001600160a01b038516906312fb68e09061217a9084908a908a908990600401615a31565b5f6040518083038186803b158015612190575f80fd5b505afa1580156121a2573d5f803e3d5ffd5b5050506001600160a01b0388165f908152601560209081526040808320868452909152812054915081156122bd575f805f6121dd8c86612ef4565b60408051602081019091525f90529194509250905061221e8383837fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706124ed565b93505f61222a85611307565b905060028160078111156122405761224061519b565b0361225e576040516303ff04cd60e51b815260040160405180910390fd5b5f858152600360205260409081902080546001600160f81b0316600160f81b179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c906122b09087815260200190565b60405180910390a1505050505b60405163d4d9bdcd60e01b8152600481018490526001600160a01b0387169063d4d9bdcd906024015f604051808303815f87803b1580156122fc575f80fd5b505af115801561230e573d5f803e3d5ffd5b50505050505050505050505050565b5f611c1760085490565b61232f612a68565b61236a8282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250613a1b92505050565b5050565b604051635adddc5560e01b815260040160405180910390fd5b61238f612a68565b5f5b81811015611ba05760125f8484848181106123ae576123ae6156f2565b90506020020160208101906123c39190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f20545f03612435578282828181106123fb576123fb6156f2565b90506020020160208101906124109190614f31565b60405163138c2add60e01b81526001600160a01b0390911660048201526024016103ff565b60125f84848481811061244a5761244a6156f2565b905060200201602081019061245f9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f205f9055828282818110612493576124936156f2565b90506020020160208101906124a89190614f31565b6001600160a01b03167fe710dd5e6adb3eb2ba468162b8ead4d66e26d337074a5067caab50b676925ab860405160405180910390a26124e68161577b565b9050612391565b5f848484846040516020016125059493929190615af2565b60408051601f19818403018152919052805160209091012095945050505050565b5f611c3d600f61352a565b6060604051806080016040528060498152602001615e7860499139905090565b600f80545f918290612564600184615812565b81548110612574576125746156f2565b5f9182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b031692820192909252915084106125c957602001516001600160e01b03169392505050565b6118936125d585613214565b600f9061327c565b6125e5612a68565b61236a8282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250613b5e92505050565b612628612a68565b610f3d81613c91565b5f611c2b838361264b60408051602081019091525f815290565b6134b7565b5f81158061265e5750428210155b1561267c5760405163749c2c6d60e01b815260040160405180910390fd5b606461268783612551565b604051630981b24d60e41b8152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063981b24d090602401602060405180830381865afa1580156126ea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061270e91906157fb565b6127189190615b3c565b61126e9190615b67565b61272a612a68565b610f3d81613d31565b61273b612a68565b6001600160a01b0382165f9081526014602052604090205481810361277357604051631a73bda360e11b815260040160405180910390fd5b6001600160a01b0383165f818152601460209081526040918290208590558151928352820183905281018390527fad48c7f5802308fb2675c0f699237e1a6d39e5170f647470b1d8ed2803262e599060600160405180910390a1505050565b5f8115806127e05750428210155b156127fe5760405163749c2c6d60e01b815260040160405180910390fd5b606461268783611807565b5f84516040148061281957508451155b6128975760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201527f6c696420706172616d7320666f72207369676e61747572652d626173656420766064820152626f746560e81b608482015260a4016103ff565b5f6129166112d87fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af888c8c8c8c6040516128d1929190615b86565b60405180910390208b805190602001206040516020016112bd959493929190948552602085019390935260ff9190911660408401526060830152608082015260a00190565b90508551604003612a17576040868101516001600160a01b0383165f908152600d60205291909120546001600160801b03918216911681146129c05760405162461bcd60e51b815260206004820152603b60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a207369676e60448201527f61747572652068617320616c7265616479206265656e2075736564000000000060648201526084016103ff565b6001600160a01b0382165f908152600d6020526040812080546001600160801b0316916129ec83615b95565b91906101000a8154816001600160801b0302191690836001600160801b031602179055505060308752505b612a5a8a828b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508d92506130bd915050565b9a9950505050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614612ab1576040516362c4ffa560e11b815260040160405180910390fd5b565b6064811115612b365760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72566f74657351756f72756d4672616374696f6e3a2071756f60448201527f72756d4e756d657261746f72206f7665722071756f72756d44656e6f6d696e616064820152623a37b960e91b608482015260a4016103ff565b5f612b3f611c32565b9050612b6e612b5c612b4f611ba5565b65ffffffffffff16613214565b612b6584613d72565b600a9190613dda565b505060408051828152602081018490527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b463399791015b60405180910390a15050565b612c32565b845181101561194557306001600160a01b0316858281518110612bd857612bd86156f2565b60200260200101516001600160a01b031603612c2257612c22838281518110612c0357612c036156f2565b6020026020010151805190602001206004613df490919063ffffffff16565b612c2b8161577b565b9050612bb3565b5050505050565b5f604051806060016040528060278152602001615e516027913990505f5b8551811015612d29575f80878381518110612c7457612c746156f2565b60200260200101516001600160a01b0316878481518110612c9757612c976156f2565b6020026020010151878581518110612cb157612cb16156f2565b6020026020010151604051612cc69190615bba565b5f6040518083038185875af1925050503d805f8114612d00576040519150601f19603f3d011682016040523d82523d5f602084013e612d05565b606091505b5091509150612d15828286613e2f565b50505080612d229061577b565b9050612c57565b50505050505050565b5f61126e612d3e613e48565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f612d6d87878787613f71565b915091506112198161402e565b5f612d9b85858585612d9660408051602081019091525f815290565b6130bd565b95945050505050565b5f80612daf83611550565b509150505f612dbd84611223565b9050612dc881612650565b9091119392505050565b5f80612ddd83611550565b505090505f612dbd84611223565b5f805f80612df885611550565b9250925092505f828411612e0c5782612e0e565b835b90505f612e1a87611223565b9050612e268383615bcb565b612e2f826127d2565b1115979650505050505050565b5f805f612e4884611550565b5091509150815f148015612e5a575080155b15612e6857505f9392505050565b111592915050565b6064811115612e91576040516271e29960e21b815260040160405180910390fd5b5f612e9a612526565b9050612ebc612eaa612b4f611ba5565b612eb384613d72565b600f9190613dda565b505060408051828152602081018490527fdd2b8b2d874e19a344cba53b9fb534ea748ef117ed4b75c67569a794864541939101612ba2565b6040805160018082528183019092526060918291829160208083019080368337505060408051600180825281830190925292955090506020808301908036833701905050604080516001808252818301909252919350816020015b6060815260200190600190039081612f4f57905050905084835f81518110612f7957612f796156f2565b60200260200101906001600160a01b031690816001600160a01b0316815250505f825f81518110612fac57612fac6156f2565b60209081029190910181019190915260408051602480820188905282518083039091018152604490910190915290810180516001600160e01b031663d4d9bdcd60e01b179052815182905f90613004576130046156f2565b60200260200101819052509250925092565b5f826001600160a01b031663d8d11f78835f015184602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c61012001516040518b63ffffffff1660e01b815260040161307e9a99989796959493929190615bde565b602060405180830381865afa158015613099573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c2b91906157fb565b5f85815260036020526040812060016130d588611307565b60078111156130e6576130e661519b565b1461313f5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e6f723a20766f7465206e6f742063757272656e746c792061637460448201526269766560e81b60648201526084016103ff565b80545f9061315d908890600160a01b900464ffffffffff16866134b7565b905061316c8888888488614177565b83515f036131c057866001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4898884896040516131b39493929190615c53565b60405180910390a26112fc565b866001600160a01b03167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb87128988848989604051613201959493929190615c7a565b60405180910390a2979650505050505050565b5f63ffffffff8211156132785760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b60648201526084016103ff565b5090565b81545f90818160058111156132d6575f61329584614292565b61329f9085615812565b5f8881526020902090915081015463ffffffff90811690871610156132c6578091506132d4565b6132d1816001615bcb565b92505b505b5f6132e387878585614376565b9050801561331d57613307876132fa600184615812565b5f91825260209091200190565b54600160201b90046001600160e01b03166112fc565b5f979650505050505050565b600e80549082905560408051828152602081018490527fd3c1cdfd662fbb8e44190410d3a0d46855746182cb8d1e5e41bc84f5afecef4f9101612ba2565b60065460408051918252602082018390527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a1600655565b606060ff83146133c2576133bb836143d1565b905061126e565b8180546133ce906156ba565b80601f01602080910402602001604051908101604052809291908181526020018280546133fa906156ba565b80156134455780601f1061341c57610100808354040283529160200191613445565b820191905f5260205f20905b81548152906001019060200180831161342857829003601f168201915b5050505050905061126e565b5f65ffffffffffff8211156132785760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b60648201526084016103ff565b600954604051630748d63560e31b81526001600160a01b038581166004830152602482018590525f921690633a46b1a890604401602060405180830381865afa158015613506573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c2891906157fb565b80545f90801561355957613543836132fa600184615812565b54600160201b90046001600160e01b0316611c2b565b5f9392505050565b600980546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fc255828f3e19c78de5df3dd5b6706d49bd5dd58e76275f97bd699878700995209101612ba2565b6001600160a01b0381165f908152601260205260408120549003610f3d576040516282b42960e81b815260040160405180910390fd5b5f805f5b83811015612c325760418082028601602081015191015160ff169350915060018390036136485781306001600160a01b03821603613646576040516308fbb1df60e31b815260040160405180910390fd5b505b6136518161577b565b90506135f5565b5f61366c86868686805190602001206124ed565b9050845186511461368f5760405162461bcd60e51b81526004016103ff90615cbf565b83518651146136b05760405162461bcd60e51b81526004016103ff90615cbf565b5f8651116137005760405162461bcd60e51b815260206004820152601860248201527f476f7665726e6f723a20656d7074792070726f706f73616c000000000000000060448201526064016103ff565b5f81815260036020526040902054600160a01b900464ffffffffff16156137735760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c20616c72656164792065786973746044820152607360f81b60648201526084016103ff565b335f61377e60065490565b613786611ba5565b65ffffffffffff166137989190615bcb565b6040516396d6d2fb60e01b8152600481018290529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906396d6d2fb906024015f604051808303815f87803b1580156137fc575f80fd5b505af192505050801561380d575060015b5060118290556001600160a01b0385165f908152601460205260408120549081810361383b5760075461383d565b815b90506138498185615bcb565b925050506040518060a00160405280846001600160a01b031681526020018364ffffffffff1681526020018264ffffffffff1681526020015f151581526020015f151581525060035f8681526020019081526020015f205f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151815f0160146101000a81548164ffffffffff021916908364ffffffffff1602179055506040820151815f0160196101000a81548164ffffffffff021916908364ffffffffff1602179055506060820151815f01601e6101000a81548160ff0219169083151502179055506080820151815f01601f6101000a81548160ff021916908315150217905550905050600e54436139699190615bcb565b5f8381526010602052604090205588517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e090859085908c908c906001600160401b038111156139ba576139ba614bb1565b6040519080825280602002602001820160405280156139ed57816020015b60608152602001906001900390816139d85790505b508c88888e604051613a0799989796959493929190615d00565b60405180910390a150505095945050505050565b5f5b815181101561236a5760135f838381518110613a3b57613a3b6156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103613aad57818181518110613a7c57613a7c6156f2565b60200260200101516040516394369fd360e01b81526004016103ff91906001600160a01b0391909116815260200190565b600160135f848481518110613ac457613ac46156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f20819055507ff48d3b938905d7162ca91551f61d4d458d43159e04847eb28ed7d94fbdb3bc2f828281518110613b2257613b226156f2565b6020026020010151604051613b4691906001600160a01b0391909116815260200190565b60405180910390a1613b578161577b565b9050613a1d565b5f5b815181101561236a5760125f838381518110613b7e57613b7e6156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103613bf057818181518110613bbf57613bbf6156f2565b6020026020010151604051630b58d77560e41b81526004016103ff91906001600160a01b0391909116815260200190565b600160125f848481518110613c0757613c076156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2081905550818181518110613c4457613c446156f2565b60200260200101516001600160a01b03167f4149776fc93a7a68120df1638269488e1915cd17b09b0ab741e6bf768a38c46d60405160405180910390a2613c8a8161577b565b9050613b60565b5f8111613cf05760405162461bcd60e51b815260206004820152602760248201527f476f7665726e6f7253657474696e67733a20766f74696e6720706572696f6420604482015266746f6f206c6f7760c81b60648201526084016103ff565b60075460408051918252602082018390527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a1600755565b60085460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600855565b5f6001600160e01b038211156132785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b60648201526084016103ff565b5f80613de785858561440e565b915091505b935093915050565b8154600160801b90819004600f0b5f818152600180860160205260409091209390935583546001600160801b03908116939091011602179055565b60608315613e3e575081611c2b565b611c2b83836145a9565b5f306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015613ea057507f000000000000000000000000000000000000000000000000000000000000000046145b15613eca57507f000000000000000000000000000000000000000000000000000000000000000090565b611c17604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613fa657505f90506003614025565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613ff7573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811661401f575f60019250925050614025565b91505f90505b94509492505050565b5f8160048111156140415761404161519b565b036140495750565b600181600481111561405d5761405d61519b565b036140aa5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016103ff565b60028160048111156140be576140be61519b565b0361410b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016103ff565b600381600481111561411f5761411f61519b565b03610f3d5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016103ff565b5f82116141d45760405162461bcd60e51b815260206004820152602560248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a206e6f2077604482015264195a59da1d60da1b60648201526084016103ff565b5f858152600c602090815260408083206001600160a01b03881684529091529020546001600160801b031682116142615760405162461bcd60e51b815260206004820152602b60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20616c6c2060448201526a1dd95a59da1d0818d85cdd60aa1b60648201526084016103ff565b5f61426b836145d3565b905081515f03614286576142818686838761463b565b611945565b61194586868385614815565b5f815f036142a157505f919050565b5f60016142ad84614a36565b901c6001901b905060018184816142c6576142c6615b53565b048201901c905060018184816142de576142de615b53565b048201901c905060018184816142f6576142f6615b53565b048201901c9050600181848161430e5761430e615b53565b048201901c9050600181848161432657614326615b53565b048201901c9050600181848161433e5761433e615b53565b048201901c9050600181848161435657614356615b53565b048201901c9050611c2b8182858161437057614370615b53565b04614ac9565b5f5b818310156143c9575f61438b8484614ade565b5f8781526020902090915063ffffffff86169082015463ffffffff1611156143b5578092506143c3565b6143c0816001615bcb565b93505b50614378565b509392505050565b60605f6143dd83614af8565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b82545f9081908015614551575f61442a876132fa600185615812565b60408051808201909152905463ffffffff808216808452600160201b9092046001600160e01b0316602084015291925090871610156144ab5760405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b657973000000000060448201526064016103ff565b805163ffffffff8088169116036144f357846144cc886132fa600186615812565b80546001600160e01b0392909216600160201b0263ffffffff909216919091179055614541565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d555f8d81529190912094519151909216600160201b029216919091179101555b602001519250839150613dec9050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a555f8a815291822095519251909316600160201b029190931617920191909155905081613dec565b8151156145b95781518083602001fd5b8060405162461bcd60e51b81526004016103ff9190614d89565b5f6001600160801b038211156132785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b60648201526084016103ff565b5f848152600c602090815260408083206001600160a01b03871684529091529020546001600160801b0316156146835760405162461bcd60e51b81526004016103ff90615dd5565b5f848152600c602090815260408083206001600160a01b0387168452909152902080546001600160801b0319166001600160801b03841617905560ff8116614714575f848152600b6020526040812080548492906146eb9084906001600160801b0316615e29565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061480f565b5f1960ff82160161474f575f848152600b6020526040902080548391906010906146eb908490600160801b90046001600160801b0316615e29565b60011960ff821601614784575f848152600b6020526040812060010180548492906146eb9084906001600160801b0316615e29565b60405162461bcd60e51b815260206004820152605460248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201527f6c696420737570706f72742076616c75652c206d75737420626520696e636c7560648201527364656420696e20566f74655479706520656e756d60601b608482015260a4016103ff565b50505050565b805160301461487b5760405162461bcd60e51b815260206004820152602c60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201526b6c696420766f74654461746160a01b60648201526084016103ff565b6020818101516040808401515f888152600c85528281206001600160a01b038916825290945290832054608083811c946001600160801b03948516949390911c929091169081836148cc8688615bcb565b6148d69190615bcb565b6148e09190615bcb565b9050866001600160801b031681111561490b5760405162461bcd60e51b81526004016103ff90615dd5565b5f898152600c602090815260408083206001600160a01b038c168452825280832080546001600160801b0319166001600160801b03868116919091179091558c8452600b83529281902081516060808201845282548087168352600160801b900486169482019490945260019190910154909316838201528051918201905281518190614999908990615e29565b6001600160801b031681526020018683602001516149b79190615e29565b6001600160801b031681526020018583604001516149d59190615e29565b6001600160801b039081169091525f9b8c52600b602090815260409c8d90208351918401518316600160801b0291831691909117815591909b01516001909101805491909b166001600160801b031990911617909955505050505050505050565b5f80608083901c15614a4a57608092831c92015b604083901c15614a5c57604092831c92015b602083901c15614a6e57602092831c92015b601083901c15614a8057601092831c92015b600883901c15614a9257600892831c92015b600483901c15614aa457600492831c92015b600283901c15614ab657600292831c92015b600183901c1561126e5760010192915050565b5f818310614ad75781611c2b565b5090919050565b5f614aec6002848418615b67565b611c2b90848416615bcb565b5f60ff8216601f81111561126e57604051632cd44ac360e21b815260040160405180910390fd5b5f60208284031215614b2f575f80fd5b5035919050565b5f60208284031215614b46575f80fd5b81356001600160e01b031981168114611c2b575f80fd5b803560ff8116811461154b575f80fd5b5f8083601f840112614b7d575f80fd5b5081356001600160401b03811115614b93575f80fd5b602083019150836020828501011115614baa575f80fd5b9250929050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b0381118282101715614be857614be8614bb1565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614c1657614c16614bb1565b604052919050565b5f6001600160401b03821115614c3657614c36614bb1565b50601f01601f191660200190565b5f614c56614c5184614c1e565b614bee565b9050828152838383011115614c69575f80fd5b828260208301375f602084830101529392505050565b5f82601f830112614c8e575f80fd5b611c2b83833560208501614c44565b5f805f805f805f8060e0898b031215614cb4575f80fd5b88359750614cc460208a01614b5d565b965060408901356001600160401b0380821115614cdf575f80fd5b614ceb8c838d01614b6d565b909850965060608b0135915080821115614d03575f80fd5b50614d108b828c01614c7f565b945050614d1f60808a01614b5d565b925060a0890135915060c089013590509295985092959890939650565b5f5b83811015614d56578181015183820152602001614d3e565b50505f910152565b5f8151808452614d75816020860160208601614d3c565b601f01601f19169290920160200192915050565b602081525f611c2b6020830184614d5e565b5f8083601f840112614dab575f80fd5b5081356001600160401b03811115614dc1575f80fd5b6020830191508360208260051b8501011115614baa575f80fd5b5f805f805f8060608789031215614df0575f80fd5b86356001600160401b0380821115614e06575f80fd5b614e128a838b01614d9b565b90985096506020890135915080821115614e2a575f80fd5b614e368a838b01614d9b565b90965094506040890135915080821115614e4e575f80fd5b50614e5b89828a01614d9b565b979a9699509497509295939492505050565b5f8151808452602080850194508084015f5b83811015614e9b57815187529582019590820190600101614e7f565b509495945050505050565b602081525f611c2b6020830184614e6d565b80356001600160a01b038116811461154b575f80fd5b5f805f8060808587031215614ee1575f80fd5b614eea85614eb8565b9350614ef860208601614eb8565b92506040850135915060608501356001600160401b03811115614f19575f80fd5b614f2587828801614c7f565b91505092959194509250565b5f60208284031215614f41575f80fd5b611c2b82614eb8565b5f6001600160401b03821115614f6257614f62614bb1565b5060051b60200190565b5f82601f830112614f7b575f80fd5b81356020614f8b614c5183614f4a565b82815260059290921b84018101918181019086841115614fa9575f80fd5b8286015b848110156110ec57614fbe81614eb8565b8352918301918301614fad565b5f82601f830112614fda575f80fd5b81356020614fea614c5183614f4a565b82815260059290921b84018101918181019086841115615008575f80fd5b8286015b848110156110ec578035835291830191830161500c565b5f82601f830112615032575f80fd5b81356020615042614c5183614f4a565b82815260059290921b84018101918181019086841115615060575f80fd5b8286015b848110156110ec5780356001600160401b03811115615082575f8081fd5b6150908986838b0101614c7f565b845250918301918301615064565b5f805f80608085870312156150b1575f80fd5b84356001600160401b03808211156150c7575f80fd5b6150d388838901614f6c565b955060208701359150808211156150e8575f80fd5b6150f488838901614fcb565b94506040870135915080821115615109575f80fd5b5061511687828801615023565b949793965093946060013593505050565b5f8060408385031215615138575f80fd5b8235915061514860208401614eb8565b90509250929050565b5f805f805f60a08688031215615165575f80fd5b8535945061517560208701614b5d565b935061518360408701614b5d565b94979396509394606081013594506080013592915050565b634e487b7160e01b5f52602160045260245ffd5b60208101600883106151c3576151c361519b565b91905290565b5f80604083850312156151da575f80fd5b8235915061514860208401614b5d565b5f80604083850312156151fb575f80fd5b61520483614eb8565b946020939093013593505050565b5f805f805f60808688031215615226575f80fd5b8535945061523660208701614b5d565b935060408601356001600160401b0380821115615251575f80fd5b61525d89838a01614b6d565b90955093506060880135915080821115615275575f80fd5b5061528288828901614c7f565b9150509295509295909350565b5f805f80604085870312156152a2575f80fd5b84356001600160401b03808211156152b8575f80fd5b6152c488838901614d9b565b909650945060208701359150808211156152dc575f80fd5b506152e987828801614d9b565b95989497509550505050565b5f805f8060608587031215615308575f80fd5b8435935061531860208601614b5d565b925060408501356001600160401b03811115615332575f80fd5b6152e987828801614b6d565b5f805f8060808587031215615351575f80fd5b84356001600160401b0380821115615367575f80fd5b61537388838901614f6c565b95506020870135915080821115615388575f80fd5b61539488838901614fcb565b945060408701359150808211156153a9575f80fd5b6153b588838901615023565b935060608701359150808211156153ca575f80fd5b508501601f810187136153db575f80fd5b614f2587823560208401614c44565b60ff60f81b8816815260e060208201525f61540860e0830189614d5e565b828103604084015261541a8189614d5e565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050612a5a8185614e6d565b5f806020838503121561545c575f80fd5b82356001600160401b03811115615471575f80fd5b61547d85828601614d9b565b90969095509350505050565b5f805f6060848603121561549b575f80fd5b6154a484614eb8565b92506020840135915060408401356001600160401b038111156154c5575f80fd5b6154d186828701614c7f565b9150509250925092565b5f805f80606085870312156154ee575f80fd5b6154f785614eb8565b935060208501356001600160401b0380821115615512575f80fd5b908601906101408289031215615526575f80fd5b9093506040860135908082111561553b575f80fd5b506152e987828801614b6d565b5f805f6040848603121561555a575f80fd5b61556384614eb8565b925060208401356001600160401b0381111561557d575f80fd5b61558986828701614b6d565b9497909650939450505050565b5f805f805f60a086880312156155aa575f80fd5b6155b386614eb8565b94506155c160208701614eb8565b935060408601356001600160401b03808211156155dc575f80fd5b6155e889838a01614fcb565b945060608801359150808211156155fd575f80fd5b61560989838a01614fcb565b93506080880135915080821115615275575f80fd5b5f805f8060608587031215615631575f80fd5b61563a85614eb8565b93506020850135925060408501356001600160401b03811115615332575f80fd5b5f805f805f60a0868803121561566f575f80fd5b61567886614eb8565b945061568660208701614eb8565b9350604086013592506060860135915060808601356001600160401b038111156156ae575f80fd5b61528288828901614c7f565b600181811c908216806156ce57607f821691505b6020821081036156ec57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b5f823561013e1983360301811261571b575f80fd5b9190910192915050565b5f808335601e1984360301811261573a575f80fd5b8301803591506001600160401b03821115615753575f80fd5b602001915036819003821315614baa575f80fd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161578c5761578c615767565b5060010190565b5f602082840312156157a3575f80fd5b81516001600160401b038111156157b8575f80fd5b8201601f810184136157c8575f80fd5b80516157d6614c5182614c1e565b8181528560208385010111156157ea575f80fd5b612d9b826020830160208601614d3c565b5f6020828403121561580b575f80fd5b5051919050565b8181038181111561126e5761126e615767565b5f60208284031215615835575f80fd5b611c2b82614b5d565b5f6020828403121561584e575f80fd5b815165ffffffffffff81168114611c2b575f80fd5b80356002811061154b575f80fd5b5f60208284031215615881575f80fd5b611c2b82615863565b5f610140823603121561589b575f80fd5b6158a3614bc5565b6158ac83614eb8565b81526020830135602082015260408301356001600160401b038111156158d0575f80fd5b6158dc36828601614c7f565b6040830152506158ee60608401615863565b60608201526080830135608082015260a083013560a082015260c083013560c082015261591d60e08401614eb8565b60e0820152610100615930818501614eb8565b9082015261012092830135928101929092525090565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b868152608060208201525f615987608083018789615946565b828103604084015261599a818688615946565b915050826060830152979650505050505050565b600281106159be576159be61519b565b9052565b6001600160a01b038a81168252602082018a9052610140604083018190525f838201526101608301916159f8606085018c6159ae565b60808401999099525060a082019690965260c081019490945291851660e084015290931661010082015261012001919091529392505050565b848152608060208201525f608082015260a060408201525f615a5760a083018587615946565b905082606083015295945050505050565b5f8151808452602080850194508084015f5b83811015614e9b5781516001600160a01b031687529582019590820190600101615a7a565b5f81518084526020808501808196508360051b810191508286015f5b85811015615ae5578284038952615ad3848351614d5e565b98850198935090840190600101615abb565b5091979650505050505050565b608081525f615b046080830187615a68565b8281036020840152615b168187614e6d565b90508281036040840152615b2a8186615a9f565b91505082606083015295945050505050565b808202811582820484141761126e5761126e615767565b634e487b7160e01b5f52601260045260245ffd5b5f82615b8157634e487b7160e01b5f52601260045260245ffd5b500490565b818382375f9101908152919050565b5f6001600160801b03808316818103615bb057615bb0615767565b6001019392505050565b5f825161571b818460208701614d3c565b8082018082111561126e5761126e615767565b6001600160a01b038b81168252602082018b9052610140604083018190525f91615c0a8483018d614d5e565b9250615c19606085018c6159ae565b60808401999099525060a082019690965260c081019490945291851660e08401529093166101008201526101200191909152949350505050565b84815260ff84166020820152826040820152608060608201525f610f046080830184614d5e565b85815260ff8516602082015283604082015260a060608201525f615ca160a0830185614d5e565b8281036080840152615cb38185614d5e565b98975050505050505050565b60208082526021908201527f476f7665726e6f723a20696e76616c69642070726f706f73616c206c656e67746040820152600d60fb1b606082015260800190565b5f6101208b8352602060018060a01b038c1681850152816040850152615d288285018c615a68565b91508382036060850152615d3c828b614e6d565b915083820360808501528189518084528284019150828160051b850101838c015f5b83811015615d8c57601f19878403018552615d7a838351614d5e565b94860194925090850190600101615d5e565b505086810360a0880152615da0818c615a9f565b9450505050508560c08401528460e0840152828103610100840152615dc58185614d5e565b9c9b505050505050505050505050565b60208082526034908201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20766f7465604082015273081ddbdd5b1908195e18d95959081dd95a59da1d60621b606082015260800190565b6001600160801b03818116838216019080821115615e4957615e49615767565b509291505056fe476f7665726e6f723a2063616c6c20726576657274656420776974686f7574206d657373616765737570706f72743d627261766f2671756f72756d3d616761696e73742c6162737461696e2671756f72756d3d666f722c6162737461696e26706172616d733d6672616374696f6e616ca2646970667358221220af80f8a495daf41067f05498bcb0a99923f9476d7d24e3147f7c56cadbe78bc564736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a00000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c6000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000078ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000001146726178476f7665726e6f724f6d6567610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c60000000000000000000000007a8a1e6966ac5b67aca3c9308fa798bb56ecac3800000000000000000000000000000000000000000000000000000000000000010000000000000000000000008adb68e26b725af5e4b9c7deefe53d7edaaeec87

Deployed Bytecode

0x6080604052600436106103f8575f3560e01c806384b0196e1161020a578063c28bc2fa1161011e578063e80f1aa7116100a8578063ece40cc111610078578063ece40cc114610dcb578063f23a6e6114610dea578063f8cc2e3c14610e15578063f8ce560a14610e34578063fc0c546a14610e53575f80fd5b8063e80f1aa714610d4f578063ea0217cf14610d6e578063eb9019d414610d8d578063ec2de58b14610dac575f80fd5b8063d914e172116100ee578063d914e17214610c8a578063dd4e2ba514610cb5578063deaaa7cc14610cc9578063df482caf14610cfc578063dfc3c9e714610d30575f80fd5b8063c28bc2fa14610c25578063c3dcf92214610c38578063c59057e414610c57578063ccb8370b14610c76575f80fd5b8063aa75a3c21161019f578063bc197c811161016f578063bc197c8114610b57578063be13109414610b82578063be74baf214610ba1578063c01f9e3714610bb6578063c1de4eed14610bef575f80fd5b8063aa75a3c214610ae6578063b021d2c314610b05578063b12c327714610b24578063b58131b014610b43575f80fd5b806397c3d334116101da57806397c3d33414610a8b5780639a802a6d14610a9e578063a7713a7014610abd578063a89f263814610ad1575f80fd5b806384b0196e146109ef57806386e80e9014610a165780638bb53cd314610a4157806391ddadf414610a60575f80fd5b8063438596321161030c5780635c0855891161029657806364cda3d41161026657806364cda3d41461095457806370b0f6601461097357806377d76602146109925780637b3c71d3146109b15780637d5e81e2146109d0575f80fd5b80635c085589146108c45780635d049c0a146108e35780635f398a141461091657806360c4247f14610935575f80fd5b80634bf5d7e9116102dc5780634bf5d7e9146107fb578063506d1f811461080f578063544ffc9c1461084257806354fd4d501461087c57806356781388146108a5575f80fd5b8063438596321461074657806343ec3e0914610792578063452115d6146107b15780634571969b146107d0575f80fd5b8063150b7a021161038d5780632fe3e2611161035d5780632fe3e2611461067d578063342cfab6146106b05780633932abb1146106e75780633bccf4fd146106fb5780633e4f49e61461071a575f80fd5b8063150b7a02146105dd5780632214a33f146106205780632656227d1461064b5780632d63f6931461065e575f80fd5b806306f3f9e6116103c857806306f3f9e61461052557806306fdde0314610544578063072c8e0d14610565578063143489d014610591575f80fd5b8063013cf08b1461040e57806301ffc9a7146104b957806302a251a3146104e85780630342018114610506575f80fd5b3661040a57005b60405180910390fd5b005b5f80fd5b348015610419575f80fd5b50610473610428366004614b1f565b60036020525f90815260409020546001600160a01b0381169064ffffffffff600160a01b8204811691600160c81b81049091169060ff600160f01b8204811691600160f81b90041685565b604080516001600160a01b03909616865264ffffffffff9485166020870152939092169284019290925290151560608301521515608082015260a0015b60405180910390f35b3480156104c4575f80fd5b506104d86104d3366004614b36565b610e72565b60405190151581526020016104b0565b3480156104f3575f80fd5b506007545b6040519081526020016104b0565b348015610511575f80fd5b506104f8610520366004614c9d565b610f0e565b348015610530575f80fd5b5061040861053f366004614b1f565b610f2c565b34801561054f575f80fd5b50610558610f40565b6040516104b09190614d89565b348015610570575f80fd5b5061058461057f366004614ddb565b610fd0565b6040516104b09190614ea6565b34801561059c575f80fd5b506105c56105ab366004614b1f565b5f908152600360205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016104b0565b3480156105e8575f80fd5b506106076105f7366004614ece565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016104b0565b34801561062b575f80fd5b506104f861063a366004614f31565b60146020525f908152604090205481565b6104f861065936600461509e565b6110f7565b348015610669575f80fd5b506104f8610678366004614b1f565b611223565b348015610688575f80fd5b506104f87fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af8881565b3480156106bb575f80fd5b506106cf6106ca366004615127565b611242565b6040516001600160801b0390911681526020016104b0565b3480156106f2575f80fd5b506006546104f8565b348015610706575f80fd5b506104f8610715366004615151565b611274565b348015610725575f80fd5b50610739610734366004614b1f565b611307565b6040516104b091906151af565b348015610751575f80fd5b506104d8610760366004615127565b5f918252600c602090815260408084206001600160a01b039390931684529190529020546001600160801b0316151590565b34801561079d575f80fd5b506104086107ac366004614b1f565b611478565b3480156107bc575f80fd5b506104f86107cb36600461509e565b611489565b3480156107db575f80fd5b506104f86107ea366004614f31565b60126020525f908152604090205481565b348015610806575f80fd5b506105586114a6565b34801561081a575f80fd5b506105c57f000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a81565b34801561084d575f80fd5b5061086161085c366004614b1f565b611550565b604080519384526020840192909252908201526060016104b0565b348015610887575f80fd5b506040805180820190915260018152603160f81b6020820152610558565b3480156108b0575f80fd5b506104f86108bf3660046151c9565b611581565b3480156108cf575f80fd5b506104086108de3660046151ea565b6115a8565b3480156108ee575f80fd5b506105c57f000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c681565b348015610921575f80fd5b506104f8610930366004615212565b6117bf565b348015610940575f80fd5b506104f861094f366004614b1f565b611807565b34801561095f575f80fd5b5061040861096e366004614b1f565b6118a4565b34801561097e575f80fd5b5061040861098d366004614b1f565b6118b5565b34801561099d575f80fd5b506104086109ac36600461528f565b6118c6565b3480156109bc575f80fd5b506104f86109cb3660046152f5565b61194d565b3480156109db575f80fd5b506104f86109ea36600461533e565b611993565b3480156109fa575f80fd5b50610a036119ad565b6040516104b097969594939291906153ea565b348015610a21575f80fd5b506104f8610a30366004614f31565b60136020525f908152604090205481565b348015610a4c575f80fd5b50610408610a5b36600461544b565b611a33565b348015610a6b575f80fd5b50610a74611ba5565b60405165ffffffffffff90911681526020016104b0565b348015610a96575f80fd5b5060646104f8565b348015610aa9575f80fd5b506104f8610ab8366004615489565b611c1c565b348015610ac8575f80fd5b506104f8611c32565b348015610adc575f80fd5b506104f8600e5481565b348015610af1575f80fd5b50610408610b00366004614f31565b611c4b565b348015610b10575f80fd5b506104f8610b1f3660046154db565b611c5c565b348015610b2f575f80fd5b50610408610b3e366004615548565b611fb6565b348015610b4e575f80fd5b506104f861231d565b348015610b62575f80fd5b50610607610b71366004615596565b63bc197c8160e01b95945050505050565b348015610b8d575f80fd5b50610408610b9c36600461544b565b612327565b348015610bac575f80fd5b506104f860115481565b348015610bc1575f80fd5b506104f8610bd0366004614b1f565b5f90815260036020526040902054600160c81b900464ffffffffff1690565b348015610bfa575f80fd5b506104f8610c093660046151ea565b601560209081525f928352604080842090915290825290205481565b610408610c3336600461561e565b61236e565b348015610c43575f80fd5b50610408610c5236600461544b565b612387565b348015610c62575f80fd5b506104f8610c7136600461509e565b6124ed565b348015610c81575f80fd5b506104f8612526565b348015610c95575f80fd5b506104f8610ca4366004614b1f565b60106020525f908152604090205481565b348015610cc0575f80fd5b50610558612531565b348015610cd4575f80fd5b506104f87f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b348015610d07575f80fd5b506106cf610d16366004614f31565b600d6020525f90815260409020546001600160801b031681565b348015610d3b575f80fd5b506104f8610d4a366004614b1f565b612551565b348015610d5a575f80fd5b50610408610d6936600461544b565b6125dd565b348015610d79575f80fd5b50610408610d88366004614b1f565b612620565b348015610d98575f80fd5b506104f8610da73660046151ea565b612631565b348015610db7575f80fd5b506104f8610dc6366004614b1f565b612650565b348015610dd6575f80fd5b50610408610de5366004614b1f565b612722565b348015610df5575f80fd5b50610607610e0436600461565b565b63f23a6e6160e01b95945050505050565b348015610e20575f80fd5b50610408610e2f3660046151ea565b612733565b348015610e3f575f80fd5b506104f8610e4e366004614b1f565b6127d2565b348015610e5e575f80fd5b506009546105c5906001600160a01b031681565b5f63288ace0360e11b6318df743f60e31b63bf26d89760e01b6379dd796f60e01b6001600160e01b03198616821480610eb757506001600160e01b0319868116908216145b80610ece57506001600160e01b0319868116908516145b80610ee957506001600160e01b03198616630271189760e51b145b80610f0457506301ffc9a760e01b6001600160e01b03198716145b9695505050505050565b5f610f1f8989898989898989612809565b9998505050505050505050565b610f34612a68565b610f3d81612ab3565b50565b606060028054610f4f906156ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7b906156ba565b8015610fc65780601f10610f9d57610100808354040283529160200191610fc6565b820191905f5260205f20905b815481529060010190602001808311610fa957829003601f168201915b5050505050905090565b60608584141580610fe15750858214155b15610fff57604051630a1eb2d160e11b815260040160405180910390fd5b856001600160401b0381111561101757611017614bb1565b604051908082528060200260200182016040528015611040578160200160208202803683370190505b5090505f5b868110156110ec576110bf888883818110611062576110626156f2565b90506020020160208101906110779190614f31565b878784818110611089576110896156f2565b905060200281019061109b9190615706565b8686858181106110ad576110ad6156f2565b9050602002810190610b1f9190615725565b8282815181106110d1576110d16156f2565b60209081029190910101526110e58161577b565b9050611045565b509695505050505050565b5f80611105868686866124ed565b90505f61111182611307565b905060048160078111156111275761112761519b565b1480611144575060058160078111156111425761114261519b565b145b61119a5760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c206e6f74207375636365737366756044820152601b60fa1b60648201526084016103ff565b5f8281526003602052604090819020805460ff60f01b1916600160f01b179055517f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f906111ea9084815260200190565b60405180910390a16111ff8288888888612bae565b61120c8288888888612c39565b6112198288888888612bae565b5095945050505050565b5f90815260036020526040902054600160a01b900464ffffffffff1690565b5f828152600c602090815260408083206001600160a01b03851684529091529020546001600160801b03165b92915050565b604080517f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f602082015290810186905260ff851660608201525f9081906112e0906112d8906080015b60405160208183030381529060405280519060200120612d32565b868686612d5e565b90506112fc87828860405180602001604052805f815250612d7a565b979650505050505050565b5f8181526003602052604081208054600160f01b900460ff161561132e5750600792915050565b8054600160f81b900460ff16156113485750600292915050565b5f61135284611223565b9050805f036113a35760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a20756e6b6e6f776e2070726f706f73616c20696400000060448201526064016103ff565b5f6113ac611ba5565b65ffffffffffff16905080821015806113d257505f828152601060205260409020544311155b156113e157505f949350505050565b6113ea85612da4565b156113fa57506004949350505050565b61140385612dd2565b1561141357506003949350505050565b5f85815260036020526040902054600160c81b900464ffffffffff168181106114425750600195945050505050565b61144b86612deb565b801561145b575061145b86612e3c565b1561146c5750600395945050505050565b50600495945050505050565b611480612a68565b610f3d81612e70565b5f60405160016205739760e41b0319815260040160405180910390fd5b60095460408051634bf5d7e960e01b815290516060926001600160a01b031691634bf5d7e9916004808301925f9291908290030181865afa92505050801561150f57506040513d5f823e601f3d908101601f1916820160405261150c9190810190615793565b60015b61154b575060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b919050565b5f908152600b6020526040902080546001909101546001600160801b0380831693600160801b909304811692911690565b5f803390506115a084828560405180602001604052805f815250612d7a565b949350505050565b6001600160a01b0382165f9081526015602090815260408083208484529091528120549080806115d88685612ef4565b91945092509050600360408051602081019091525f905261161e6107348585857fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706124ed565b600781111561162f5761162f61519b565b1461164d57604051630fd1155b60e41b815260040160405180910390fd5b5f8690505f6116cc826040518061014001604052808b6001600160a01b031681526020015f815260200160405180602001604052805f81525081526020015f600181111561169d5761169d61519b565b81525f6020820181905260408201819052606082018190526080820181905260a082015260c0018a9052613016565b604051631f60ca5d60e21b8152306004820152602481018290529091506001600160a01b03831690637d832974906044016020604051808303815f875af1158015611719573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061173d91906157fb565b60010361176057604051635c0abc6d60e11b8152600481018290526024016103ff565b60405163d4d9bdcd60e01b8152600481018290526001600160a01b0383169063d4d9bdcd906024015f604051808303815f87803b15801561179f575f80fd5b505af11580156117b1573d5f803e3d5ffd5b505050505050505050505050565b5f803390506112fc87828888888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508a92506130bd915050565b600a80545f91829061181a600184615812565b8154811061182a5761182a6156f2565b5f9182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b0316928201929092529150841061187f57602001516001600160e01b03169392505050565b61189361188b85613214565b600a9061327c565b6001600160e01b0316949350505050565b6118ac612a68565b610f3d81613329565b6118bd612a68565b610f3d81613367565b828181146118e75760405163a669fc0560e01b815260040160405180910390fd5b5f5b8181101561194557611934868683818110611906576119066156f2565b9050602002013585858481811061191f5761191f6156f2565b90506020020160208101906108bf9190615825565b5061193e8161577b565b90506118e9565b505050505050565b5f80339050610f0486828787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250612d7a92505050565b5f60405163098bb82f60e01b815260040160405180910390fd5b5f606080828080836119df7f46726178476f7665726e6f724f6d656761000000000000000000000000000011836133a8565b611a0a7f310000000000000000000000000000000000000000000000000000000000000160016133a8565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b611a3b612a68565b5f5b81811015611ba05760135f848484818110611a5a57611a5a6156f2565b9050602002016020810190611a6f9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f20545f03611ae157828282818110611aa757611aa76156f2565b9050602002016020810190611abc9190614f31565b604051630ee1e0b360e41b81526001600160a01b0390911660048201526024016103ff565b60135f848484818110611af657611af66156f2565b9050602002016020810190611b0b9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f205f90557f3f75b27f9b6f643d57ab0006da862b383ffc26813fc08462f2d56270aaa950c0838383818110611b6057611b606156f2565b9050602002016020810190611b759190614f31565b6040516001600160a01b03909116815260200160405180910390a1611b998161577b565b9050611a3d565b505050565b600954604080516324776b7d60e21b815290515f926001600160a01b0316916391ddadf49160048083019260209291908290030181865afa925050508015611c0a575060408051601f3d908101601f19168201909252611c079181019061583e565b60015b61154b57611c1743613451565b905090565b5f611c288484846134b7565b90505b9392505050565b5f611c3d600a61352a565b6001600160e01b0316905090565b611c53612a68565b610f3d81613561565b5f611c66856135bb565b6001611c786080860160608701615871565b6001811115611c8957611c8961519b565b148015611cc6575060135f611ca16020870187614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f2054600114155b15611cfd57611cd86020850185614f31565b6040516317645e7d60e21b81526001600160a01b0390911660048201526024016103ff565b5f8590505f816001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d6291906157fb565b9050611da485858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508592506135f1915050565b6001600160a01b0387165f9081526015602090815260408083206101208a0135845290915290205415611dea57604051639e01d15b60e01b815260040160405180910390fd5b816001600160a01b031663affed0e06040518163ffffffff1660e01b81526004016020604051808303815f875af1158015611e27573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e4b91906157fb565b8661012001351015611e705760405163d9c6386f60e01b815260040160405180910390fd5b5f611e8383611e7e8961588a565b613016565b90506001600160a01b0383166312fb68e082611ea260408b018b615725565b8a8a886040518763ffffffff1660e01b8152600401611ec69695949392919061596e565b5f6040518083038186803b158015611edc575f80fd5b505afa158015611eee573d5f803e3d5ffd5b505050505f805f611eff8b85612ef4565b925092509250611f2083838360405180602001604052805f8152508f613658565b96508360155f8d6001600160a01b03166001600160a01b031681526020019081526020015f205f8c610120013581526020019081526020015f208190555086848c6001600160a01b03167f5ed3fb2763971f1f5e3d1e6f215e92ebe28160b512c2da07f4b12a46021adb0b8d6101200135604051611fa091815260200190565b60405180910390a4505050505050949350505050565b611fbf836135bb565b5f8390505f816001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612000573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061202491906157fb565b905061206684848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508592506135f1915050565b5f826001600160a01b031663affed0e06040518163ffffffff1660e01b81526004016020604051808303815f875af11580156120a4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120c891906157fb565b90505f836001600160a01b031663d8d11f78885f805f805f805f8b6040518a63ffffffff1660e01b8152600401612107999897969594939291906159c2565b602060405180830381865afa158015612122573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214691906157fb565b6040516297db4760e51b81529091506001600160a01b038516906312fb68e09061217a9084908a908a908990600401615a31565b5f6040518083038186803b158015612190575f80fd5b505afa1580156121a2573d5f803e3d5ffd5b5050506001600160a01b0388165f908152601560209081526040808320868452909152812054915081156122bd575f805f6121dd8c86612ef4565b60408051602081019091525f90529194509250905061221e8383837fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706124ed565b93505f61222a85611307565b905060028160078111156122405761224061519b565b0361225e576040516303ff04cd60e51b815260040160405180910390fd5b5f858152600360205260409081902080546001600160f81b0316600160f81b179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c906122b09087815260200190565b60405180910390a1505050505b60405163d4d9bdcd60e01b8152600481018490526001600160a01b0387169063d4d9bdcd906024015f604051808303815f87803b1580156122fc575f80fd5b505af115801561230e573d5f803e3d5ffd5b50505050505050505050505050565b5f611c1760085490565b61232f612a68565b61236a8282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250613a1b92505050565b5050565b604051635adddc5560e01b815260040160405180910390fd5b61238f612a68565b5f5b81811015611ba05760125f8484848181106123ae576123ae6156f2565b90506020020160208101906123c39190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f20545f03612435578282828181106123fb576123fb6156f2565b90506020020160208101906124109190614f31565b60405163138c2add60e01b81526001600160a01b0390911660048201526024016103ff565b60125f84848481811061244a5761244a6156f2565b905060200201602081019061245f9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f205f9055828282818110612493576124936156f2565b90506020020160208101906124a89190614f31565b6001600160a01b03167fe710dd5e6adb3eb2ba468162b8ead4d66e26d337074a5067caab50b676925ab860405160405180910390a26124e68161577b565b9050612391565b5f848484846040516020016125059493929190615af2565b60408051601f19818403018152919052805160209091012095945050505050565b5f611c3d600f61352a565b6060604051806080016040528060498152602001615e7860499139905090565b600f80545f918290612564600184615812565b81548110612574576125746156f2565b5f9182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b031692820192909252915084106125c957602001516001600160e01b03169392505050565b6118936125d585613214565b600f9061327c565b6125e5612a68565b61236a8282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250613b5e92505050565b612628612a68565b610f3d81613c91565b5f611c2b838361264b60408051602081019091525f815290565b6134b7565b5f81158061265e5750428210155b1561267c5760405163749c2c6d60e01b815260040160405180910390fd5b606461268783612551565b604051630981b24d60e41b8152600481018590527f000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a6001600160a01b03169063981b24d090602401602060405180830381865afa1580156126ea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061270e91906157fb565b6127189190615b3c565b61126e9190615b67565b61272a612a68565b610f3d81613d31565b61273b612a68565b6001600160a01b0382165f9081526014602052604090205481810361277357604051631a73bda360e11b815260040160405180910390fd5b6001600160a01b0383165f818152601460209081526040918290208590558151928352820183905281018390527fad48c7f5802308fb2675c0f699237e1a6d39e5170f647470b1d8ed2803262e599060600160405180910390a1505050565b5f8115806127e05750428210155b156127fe5760405163749c2c6d60e01b815260040160405180910390fd5b606461268783611807565b5f84516040148061281957508451155b6128975760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201527f6c696420706172616d7320666f72207369676e61747572652d626173656420766064820152626f746560e81b608482015260a4016103ff565b5f6129166112d87fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af888c8c8c8c6040516128d1929190615b86565b60405180910390208b805190602001206040516020016112bd959493929190948552602085019390935260ff9190911660408401526060830152608082015260a00190565b90508551604003612a17576040868101516001600160a01b0383165f908152600d60205291909120546001600160801b03918216911681146129c05760405162461bcd60e51b815260206004820152603b60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a207369676e60448201527f61747572652068617320616c7265616479206265656e2075736564000000000060648201526084016103ff565b6001600160a01b0382165f908152600d6020526040812080546001600160801b0316916129ec83615b95565b91906101000a8154816001600160801b0302191690836001600160801b031602179055505060308752505b612a5a8a828b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508d92506130bd915050565b9a9950505050505050505050565b336001600160a01b037f000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c61614612ab1576040516362c4ffa560e11b815260040160405180910390fd5b565b6064811115612b365760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72566f74657351756f72756d4672616374696f6e3a2071756f60448201527f72756d4e756d657261746f72206f7665722071756f72756d44656e6f6d696e616064820152623a37b960e91b608482015260a4016103ff565b5f612b3f611c32565b9050612b6e612b5c612b4f611ba5565b65ffffffffffff16613214565b612b6584613d72565b600a9190613dda565b505060408051828152602081018490527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b463399791015b60405180910390a15050565b612c32565b845181101561194557306001600160a01b0316858281518110612bd857612bd86156f2565b60200260200101516001600160a01b031603612c2257612c22838281518110612c0357612c036156f2565b6020026020010151805190602001206004613df490919063ffffffff16565b612c2b8161577b565b9050612bb3565b5050505050565b5f604051806060016040528060278152602001615e516027913990505f5b8551811015612d29575f80878381518110612c7457612c746156f2565b60200260200101516001600160a01b0316878481518110612c9757612c976156f2565b6020026020010151878581518110612cb157612cb16156f2565b6020026020010151604051612cc69190615bba565b5f6040518083038185875af1925050503d805f8114612d00576040519150601f19603f3d011682016040523d82523d5f602084013e612d05565b606091505b5091509150612d15828286613e2f565b50505080612d229061577b565b9050612c57565b50505050505050565b5f61126e612d3e613e48565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f612d6d87878787613f71565b915091506112198161402e565b5f612d9b85858585612d9660408051602081019091525f815290565b6130bd565b95945050505050565b5f80612daf83611550565b509150505f612dbd84611223565b9050612dc881612650565b9091119392505050565b5f80612ddd83611550565b505090505f612dbd84611223565b5f805f80612df885611550565b9250925092505f828411612e0c5782612e0e565b835b90505f612e1a87611223565b9050612e268383615bcb565b612e2f826127d2565b1115979650505050505050565b5f805f612e4884611550565b5091509150815f148015612e5a575080155b15612e6857505f9392505050565b111592915050565b6064811115612e91576040516271e29960e21b815260040160405180910390fd5b5f612e9a612526565b9050612ebc612eaa612b4f611ba5565b612eb384613d72565b600f9190613dda565b505060408051828152602081018490527fdd2b8b2d874e19a344cba53b9fb534ea748ef117ed4b75c67569a794864541939101612ba2565b6040805160018082528183019092526060918291829160208083019080368337505060408051600180825281830190925292955090506020808301908036833701905050604080516001808252818301909252919350816020015b6060815260200190600190039081612f4f57905050905084835f81518110612f7957612f796156f2565b60200260200101906001600160a01b031690816001600160a01b0316815250505f825f81518110612fac57612fac6156f2565b60209081029190910181019190915260408051602480820188905282518083039091018152604490910190915290810180516001600160e01b031663d4d9bdcd60e01b179052815182905f90613004576130046156f2565b60200260200101819052509250925092565b5f826001600160a01b031663d8d11f78835f015184602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c61012001516040518b63ffffffff1660e01b815260040161307e9a99989796959493929190615bde565b602060405180830381865afa158015613099573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c2b91906157fb565b5f85815260036020526040812060016130d588611307565b60078111156130e6576130e661519b565b1461313f5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e6f723a20766f7465206e6f742063757272656e746c792061637460448201526269766560e81b60648201526084016103ff565b80545f9061315d908890600160a01b900464ffffffffff16866134b7565b905061316c8888888488614177565b83515f036131c057866001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4898884896040516131b39493929190615c53565b60405180910390a26112fc565b866001600160a01b03167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb87128988848989604051613201959493929190615c7a565b60405180910390a2979650505050505050565b5f63ffffffff8211156132785760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b60648201526084016103ff565b5090565b81545f90818160058111156132d6575f61329584614292565b61329f9085615812565b5f8881526020902090915081015463ffffffff90811690871610156132c6578091506132d4565b6132d1816001615bcb565b92505b505b5f6132e387878585614376565b9050801561331d57613307876132fa600184615812565b5f91825260209091200190565b54600160201b90046001600160e01b03166112fc565b5f979650505050505050565b600e80549082905560408051828152602081018490527fd3c1cdfd662fbb8e44190410d3a0d46855746182cb8d1e5e41bc84f5afecef4f9101612ba2565b60065460408051918252602082018390527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a1600655565b606060ff83146133c2576133bb836143d1565b905061126e565b8180546133ce906156ba565b80601f01602080910402602001604051908101604052809291908181526020018280546133fa906156ba565b80156134455780601f1061341c57610100808354040283529160200191613445565b820191905f5260205f20905b81548152906001019060200180831161342857829003601f168201915b5050505050905061126e565b5f65ffffffffffff8211156132785760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b60648201526084016103ff565b600954604051630748d63560e31b81526001600160a01b038581166004830152602482018590525f921690633a46b1a890604401602060405180830381865afa158015613506573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c2891906157fb565b80545f90801561355957613543836132fa600184615812565b54600160201b90046001600160e01b0316611c2b565b5f9392505050565b600980546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fc255828f3e19c78de5df3dd5b6706d49bd5dd58e76275f97bd699878700995209101612ba2565b6001600160a01b0381165f908152601260205260408120549003610f3d576040516282b42960e81b815260040160405180910390fd5b5f805f5b83811015612c325760418082028601602081015191015160ff169350915060018390036136485781306001600160a01b03821603613646576040516308fbb1df60e31b815260040160405180910390fd5b505b6136518161577b565b90506135f5565b5f61366c86868686805190602001206124ed565b9050845186511461368f5760405162461bcd60e51b81526004016103ff90615cbf565b83518651146136b05760405162461bcd60e51b81526004016103ff90615cbf565b5f8651116137005760405162461bcd60e51b815260206004820152601860248201527f476f7665726e6f723a20656d7074792070726f706f73616c000000000000000060448201526064016103ff565b5f81815260036020526040902054600160a01b900464ffffffffff16156137735760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c20616c72656164792065786973746044820152607360f81b60648201526084016103ff565b335f61377e60065490565b613786611ba5565b65ffffffffffff166137989190615bcb565b6040516396d6d2fb60e01b8152600481018290529091505f906001600160a01b037f000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a16906396d6d2fb906024015f604051808303815f87803b1580156137fc575f80fd5b505af192505050801561380d575060015b5060118290556001600160a01b0385165f908152601460205260408120549081810361383b5760075461383d565b815b90506138498185615bcb565b925050506040518060a00160405280846001600160a01b031681526020018364ffffffffff1681526020018264ffffffffff1681526020015f151581526020015f151581525060035f8681526020019081526020015f205f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151815f0160146101000a81548164ffffffffff021916908364ffffffffff1602179055506040820151815f0160196101000a81548164ffffffffff021916908364ffffffffff1602179055506060820151815f01601e6101000a81548160ff0219169083151502179055506080820151815f01601f6101000a81548160ff021916908315150217905550905050600e54436139699190615bcb565b5f8381526010602052604090205588517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e090859085908c908c906001600160401b038111156139ba576139ba614bb1565b6040519080825280602002602001820160405280156139ed57816020015b60608152602001906001900390816139d85790505b508c88888e604051613a0799989796959493929190615d00565b60405180910390a150505095945050505050565b5f5b815181101561236a5760135f838381518110613a3b57613a3b6156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103613aad57818181518110613a7c57613a7c6156f2565b60200260200101516040516394369fd360e01b81526004016103ff91906001600160a01b0391909116815260200190565b600160135f848481518110613ac457613ac46156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f20819055507ff48d3b938905d7162ca91551f61d4d458d43159e04847eb28ed7d94fbdb3bc2f828281518110613b2257613b226156f2565b6020026020010151604051613b4691906001600160a01b0391909116815260200190565b60405180910390a1613b578161577b565b9050613a1d565b5f5b815181101561236a5760125f838381518110613b7e57613b7e6156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103613bf057818181518110613bbf57613bbf6156f2565b6020026020010151604051630b58d77560e41b81526004016103ff91906001600160a01b0391909116815260200190565b600160125f848481518110613c0757613c076156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2081905550818181518110613c4457613c446156f2565b60200260200101516001600160a01b03167f4149776fc93a7a68120df1638269488e1915cd17b09b0ab741e6bf768a38c46d60405160405180910390a2613c8a8161577b565b9050613b60565b5f8111613cf05760405162461bcd60e51b815260206004820152602760248201527f476f7665726e6f7253657474696e67733a20766f74696e6720706572696f6420604482015266746f6f206c6f7760c81b60648201526084016103ff565b60075460408051918252602082018390527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a1600755565b60085460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600855565b5f6001600160e01b038211156132785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b60648201526084016103ff565b5f80613de785858561440e565b915091505b935093915050565b8154600160801b90819004600f0b5f818152600180860160205260409091209390935583546001600160801b03908116939091011602179055565b60608315613e3e575081611c2b565b611c2b83836145a9565b5f306001600160a01b037f000000000000000000000000bcb25d7582d0738a77508096b05488d49181b25516148015613ea057507f000000000000000000000000000000000000000000000000000000000000000146145b15613eca57507f18e45c9fb31a5a64c5309dfee5edd1a39f1985a326c9af56738d3ce72494894990565b611c17604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f620ac8ea4a3c475715e3a262a03da2938e289791e878a009589871e19bdbc67d918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613fa657505f90506003614025565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613ff7573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811661401f575f60019250925050614025565b91505f90505b94509492505050565b5f8160048111156140415761404161519b565b036140495750565b600181600481111561405d5761405d61519b565b036140aa5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016103ff565b60028160048111156140be576140be61519b565b0361410b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016103ff565b600381600481111561411f5761411f61519b565b03610f3d5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016103ff565b5f82116141d45760405162461bcd60e51b815260206004820152602560248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a206e6f2077604482015264195a59da1d60da1b60648201526084016103ff565b5f858152600c602090815260408083206001600160a01b03881684529091529020546001600160801b031682116142615760405162461bcd60e51b815260206004820152602b60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20616c6c2060448201526a1dd95a59da1d0818d85cdd60aa1b60648201526084016103ff565b5f61426b836145d3565b905081515f03614286576142818686838761463b565b611945565b61194586868385614815565b5f815f036142a157505f919050565b5f60016142ad84614a36565b901c6001901b905060018184816142c6576142c6615b53565b048201901c905060018184816142de576142de615b53565b048201901c905060018184816142f6576142f6615b53565b048201901c9050600181848161430e5761430e615b53565b048201901c9050600181848161432657614326615b53565b048201901c9050600181848161433e5761433e615b53565b048201901c9050600181848161435657614356615b53565b048201901c9050611c2b8182858161437057614370615b53565b04614ac9565b5f5b818310156143c9575f61438b8484614ade565b5f8781526020902090915063ffffffff86169082015463ffffffff1611156143b5578092506143c3565b6143c0816001615bcb565b93505b50614378565b509392505050565b60605f6143dd83614af8565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b82545f9081908015614551575f61442a876132fa600185615812565b60408051808201909152905463ffffffff808216808452600160201b9092046001600160e01b0316602084015291925090871610156144ab5760405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b657973000000000060448201526064016103ff565b805163ffffffff8088169116036144f357846144cc886132fa600186615812565b80546001600160e01b0392909216600160201b0263ffffffff909216919091179055614541565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d555f8d81529190912094519151909216600160201b029216919091179101555b602001519250839150613dec9050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a555f8a815291822095519251909316600160201b029190931617920191909155905081613dec565b8151156145b95781518083602001fd5b8060405162461bcd60e51b81526004016103ff9190614d89565b5f6001600160801b038211156132785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b60648201526084016103ff565b5f848152600c602090815260408083206001600160a01b03871684529091529020546001600160801b0316156146835760405162461bcd60e51b81526004016103ff90615dd5565b5f848152600c602090815260408083206001600160a01b0387168452909152902080546001600160801b0319166001600160801b03841617905560ff8116614714575f848152600b6020526040812080548492906146eb9084906001600160801b0316615e29565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061480f565b5f1960ff82160161474f575f848152600b6020526040902080548391906010906146eb908490600160801b90046001600160801b0316615e29565b60011960ff821601614784575f848152600b6020526040812060010180548492906146eb9084906001600160801b0316615e29565b60405162461bcd60e51b815260206004820152605460248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201527f6c696420737570706f72742076616c75652c206d75737420626520696e636c7560648201527364656420696e20566f74655479706520656e756d60601b608482015260a4016103ff565b50505050565b805160301461487b5760405162461bcd60e51b815260206004820152602c60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201526b6c696420766f74654461746160a01b60648201526084016103ff565b6020818101516040808401515f888152600c85528281206001600160a01b038916825290945290832054608083811c946001600160801b03948516949390911c929091169081836148cc8688615bcb565b6148d69190615bcb565b6148e09190615bcb565b9050866001600160801b031681111561490b5760405162461bcd60e51b81526004016103ff90615dd5565b5f898152600c602090815260408083206001600160a01b038c168452825280832080546001600160801b0319166001600160801b03868116919091179091558c8452600b83529281902081516060808201845282548087168352600160801b900486169482019490945260019190910154909316838201528051918201905281518190614999908990615e29565b6001600160801b031681526020018683602001516149b79190615e29565b6001600160801b031681526020018583604001516149d59190615e29565b6001600160801b039081169091525f9b8c52600b602090815260409c8d90208351918401518316600160801b0291831691909117815591909b01516001909101805491909b166001600160801b031990911617909955505050505050505050565b5f80608083901c15614a4a57608092831c92015b604083901c15614a5c57604092831c92015b602083901c15614a6e57602092831c92015b601083901c15614a8057601092831c92015b600883901c15614a9257600892831c92015b600483901c15614aa457600492831c92015b600283901c15614ab657600292831c92015b600183901c1561126e5760010192915050565b5f818310614ad75781611c2b565b5090919050565b5f614aec6002848418615b67565b611c2b90848416615bcb565b5f60ff8216601f81111561126e57604051632cd44ac360e21b815260040160405180910390fd5b5f60208284031215614b2f575f80fd5b5035919050565b5f60208284031215614b46575f80fd5b81356001600160e01b031981168114611c2b575f80fd5b803560ff8116811461154b575f80fd5b5f8083601f840112614b7d575f80fd5b5081356001600160401b03811115614b93575f80fd5b602083019150836020828501011115614baa575f80fd5b9250929050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b0381118282101715614be857614be8614bb1565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614c1657614c16614bb1565b604052919050565b5f6001600160401b03821115614c3657614c36614bb1565b50601f01601f191660200190565b5f614c56614c5184614c1e565b614bee565b9050828152838383011115614c69575f80fd5b828260208301375f602084830101529392505050565b5f82601f830112614c8e575f80fd5b611c2b83833560208501614c44565b5f805f805f805f8060e0898b031215614cb4575f80fd5b88359750614cc460208a01614b5d565b965060408901356001600160401b0380821115614cdf575f80fd5b614ceb8c838d01614b6d565b909850965060608b0135915080821115614d03575f80fd5b50614d108b828c01614c7f565b945050614d1f60808a01614b5d565b925060a0890135915060c089013590509295985092959890939650565b5f5b83811015614d56578181015183820152602001614d3e565b50505f910152565b5f8151808452614d75816020860160208601614d3c565b601f01601f19169290920160200192915050565b602081525f611c2b6020830184614d5e565b5f8083601f840112614dab575f80fd5b5081356001600160401b03811115614dc1575f80fd5b6020830191508360208260051b8501011115614baa575f80fd5b5f805f805f8060608789031215614df0575f80fd5b86356001600160401b0380821115614e06575f80fd5b614e128a838b01614d9b565b90985096506020890135915080821115614e2a575f80fd5b614e368a838b01614d9b565b90965094506040890135915080821115614e4e575f80fd5b50614e5b89828a01614d9b565b979a9699509497509295939492505050565b5f8151808452602080850194508084015f5b83811015614e9b57815187529582019590820190600101614e7f565b509495945050505050565b602081525f611c2b6020830184614e6d565b80356001600160a01b038116811461154b575f80fd5b5f805f8060808587031215614ee1575f80fd5b614eea85614eb8565b9350614ef860208601614eb8565b92506040850135915060608501356001600160401b03811115614f19575f80fd5b614f2587828801614c7f565b91505092959194509250565b5f60208284031215614f41575f80fd5b611c2b82614eb8565b5f6001600160401b03821115614f6257614f62614bb1565b5060051b60200190565b5f82601f830112614f7b575f80fd5b81356020614f8b614c5183614f4a565b82815260059290921b84018101918181019086841115614fa9575f80fd5b8286015b848110156110ec57614fbe81614eb8565b8352918301918301614fad565b5f82601f830112614fda575f80fd5b81356020614fea614c5183614f4a565b82815260059290921b84018101918181019086841115615008575f80fd5b8286015b848110156110ec578035835291830191830161500c565b5f82601f830112615032575f80fd5b81356020615042614c5183614f4a565b82815260059290921b84018101918181019086841115615060575f80fd5b8286015b848110156110ec5780356001600160401b03811115615082575f8081fd5b6150908986838b0101614c7f565b845250918301918301615064565b5f805f80608085870312156150b1575f80fd5b84356001600160401b03808211156150c7575f80fd5b6150d388838901614f6c565b955060208701359150808211156150e8575f80fd5b6150f488838901614fcb565b94506040870135915080821115615109575f80fd5b5061511687828801615023565b949793965093946060013593505050565b5f8060408385031215615138575f80fd5b8235915061514860208401614eb8565b90509250929050565b5f805f805f60a08688031215615165575f80fd5b8535945061517560208701614b5d565b935061518360408701614b5d565b94979396509394606081013594506080013592915050565b634e487b7160e01b5f52602160045260245ffd5b60208101600883106151c3576151c361519b565b91905290565b5f80604083850312156151da575f80fd5b8235915061514860208401614b5d565b5f80604083850312156151fb575f80fd5b61520483614eb8565b946020939093013593505050565b5f805f805f60808688031215615226575f80fd5b8535945061523660208701614b5d565b935060408601356001600160401b0380821115615251575f80fd5b61525d89838a01614b6d565b90955093506060880135915080821115615275575f80fd5b5061528288828901614c7f565b9150509295509295909350565b5f805f80604085870312156152a2575f80fd5b84356001600160401b03808211156152b8575f80fd5b6152c488838901614d9b565b909650945060208701359150808211156152dc575f80fd5b506152e987828801614d9b565b95989497509550505050565b5f805f8060608587031215615308575f80fd5b8435935061531860208601614b5d565b925060408501356001600160401b03811115615332575f80fd5b6152e987828801614b6d565b5f805f8060808587031215615351575f80fd5b84356001600160401b0380821115615367575f80fd5b61537388838901614f6c565b95506020870135915080821115615388575f80fd5b61539488838901614fcb565b945060408701359150808211156153a9575f80fd5b6153b588838901615023565b935060608701359150808211156153ca575f80fd5b508501601f810187136153db575f80fd5b614f2587823560208401614c44565b60ff60f81b8816815260e060208201525f61540860e0830189614d5e565b828103604084015261541a8189614d5e565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050612a5a8185614e6d565b5f806020838503121561545c575f80fd5b82356001600160401b03811115615471575f80fd5b61547d85828601614d9b565b90969095509350505050565b5f805f6060848603121561549b575f80fd5b6154a484614eb8565b92506020840135915060408401356001600160401b038111156154c5575f80fd5b6154d186828701614c7f565b9150509250925092565b5f805f80606085870312156154ee575f80fd5b6154f785614eb8565b935060208501356001600160401b0380821115615512575f80fd5b908601906101408289031215615526575f80fd5b9093506040860135908082111561553b575f80fd5b506152e987828801614b6d565b5f805f6040848603121561555a575f80fd5b61556384614eb8565b925060208401356001600160401b0381111561557d575f80fd5b61558986828701614b6d565b9497909650939450505050565b5f805f805f60a086880312156155aa575f80fd5b6155b386614eb8565b94506155c160208701614eb8565b935060408601356001600160401b03808211156155dc575f80fd5b6155e889838a01614fcb565b945060608801359150808211156155fd575f80fd5b61560989838a01614fcb565b93506080880135915080821115615275575f80fd5b5f805f8060608587031215615631575f80fd5b61563a85614eb8565b93506020850135925060408501356001600160401b03811115615332575f80fd5b5f805f805f60a0868803121561566f575f80fd5b61567886614eb8565b945061568660208701614eb8565b9350604086013592506060860135915060808601356001600160401b038111156156ae575f80fd5b61528288828901614c7f565b600181811c908216806156ce57607f821691505b6020821081036156ec57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b5f823561013e1983360301811261571b575f80fd5b9190910192915050565b5f808335601e1984360301811261573a575f80fd5b8301803591506001600160401b03821115615753575f80fd5b602001915036819003821315614baa575f80fd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161578c5761578c615767565b5060010190565b5f602082840312156157a3575f80fd5b81516001600160401b038111156157b8575f80fd5b8201601f810184136157c8575f80fd5b80516157d6614c5182614c1e565b8181528560208385010111156157ea575f80fd5b612d9b826020830160208601614d3c565b5f6020828403121561580b575f80fd5b5051919050565b8181038181111561126e5761126e615767565b5f60208284031215615835575f80fd5b611c2b82614b5d565b5f6020828403121561584e575f80fd5b815165ffffffffffff81168114611c2b575f80fd5b80356002811061154b575f80fd5b5f60208284031215615881575f80fd5b611c2b82615863565b5f610140823603121561589b575f80fd5b6158a3614bc5565b6158ac83614eb8565b81526020830135602082015260408301356001600160401b038111156158d0575f80fd5b6158dc36828601614c7f565b6040830152506158ee60608401615863565b60608201526080830135608082015260a083013560a082015260c083013560c082015261591d60e08401614eb8565b60e0820152610100615930818501614eb8565b9082015261012092830135928101929092525090565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b868152608060208201525f615987608083018789615946565b828103604084015261599a818688615946565b915050826060830152979650505050505050565b600281106159be576159be61519b565b9052565b6001600160a01b038a81168252602082018a9052610140604083018190525f838201526101608301916159f8606085018c6159ae565b60808401999099525060a082019690965260c081019490945291851660e084015290931661010082015261012001919091529392505050565b848152608060208201525f608082015260a060408201525f615a5760a083018587615946565b905082606083015295945050505050565b5f8151808452602080850194508084015f5b83811015614e9b5781516001600160a01b031687529582019590820190600101615a7a565b5f81518084526020808501808196508360051b810191508286015f5b85811015615ae5578284038952615ad3848351614d5e565b98850198935090840190600101615abb565b5091979650505050505050565b608081525f615b046080830187615a68565b8281036020840152615b168187614e6d565b90508281036040840152615b2a8186615a9f565b91505082606083015295945050505050565b808202811582820484141761126e5761126e615767565b634e487b7160e01b5f52601260045260245ffd5b5f82615b8157634e487b7160e01b5f52601260045260245ffd5b500490565b818382375f9101908152919050565b5f6001600160801b03808316818103615bb057615bb0615767565b6001019392505050565b5f825161571b818460208701614d3c565b8082018082111561126e5761126e615767565b6001600160a01b038b81168252602082018b9052610140604083018190525f91615c0a8483018d614d5e565b9250615c19606085018c6159ae565b60808401999099525060a082019690965260c081019490945291851660e08401529093166101008201526101200191909152949350505050565b84815260ff84166020820152826040820152608060608201525f610f046080830184614d5e565b85815260ff8516602082015283604082015260a060608201525f615ca160a0830185614d5e565b8281036080840152615cb38185614d5e565b98975050505050505050565b60208082526021908201527f476f7665726e6f723a20696e76616c69642070726f706f73616c206c656e67746040820152600d60fb1b606082015260800190565b5f6101208b8352602060018060a01b038c1681850152816040850152615d288285018c615a68565b91508382036060850152615d3c828b614e6d565b915083820360808501528189518084528284019150828160051b850101838c015f5b83811015615d8c57601f19878403018552615d7a838351614d5e565b94860194925090850190600101615d5e565b505086810360a0880152615da0818c615a9f565b9450505050508560c08401528460e0840152828103610100840152615dc58185614d5e565b9c9b505050505050505050505050565b60208082526034908201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20766f7465604082015273081ddbdd5b1908195e18d95959081dd95a59da1d60621b606082015260800190565b6001600160801b03818116838216019080821115615e4957615e49615767565b509291505056fe476f7665726e6f723a2063616c6c20726576657274656420776974686f7574206d657373616765737570706f72743d627261766f2671756f72756d3d616761696e73742c6162737461696e2671756f72756d3d666f722c6162737461696e26706172616d733d6672616374696f6e616ca2646970667358221220af80f8a495daf41067f05498bcb0a99923f9476d7d24e3147f7c56cadbe78bc564736f6c63430008140033

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

00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a00000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c6000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000078ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000001146726178476f7665726e6f724f6d6567610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c60000000000000000000000007a8a1e6966ac5b67aca3c9308fa798bb56ecac3800000000000000000000000000000000000000000000000000000000000000010000000000000000000000008adb68e26b725af5e4b9c7deefe53d7edaaeec87

-----Decoded View---------------
Arg [0] : params (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
20 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [2] : 000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a
Arg [3] : 000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a
Arg [4] : 00000000000000000000000000000000000000000000000000000000000001c0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000220
Arg [6] : 000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c6
Arg [7] : 000000000000000000000000000000000000000000000000000000000000003c
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000078
Arg [9] : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Arg [10] : 000000000000000000000000000000000000000000000000000000000000005f
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [12] : 000000000000000000000000000000000000000000000000000000000000005f
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000011
Arg [14] : 46726178476f7665726e6f724f6d656761000000000000000000000000000000
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [16] : 000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c6
Arg [17] : 0000000000000000000000007a8a1e6966ac5b67aca3c9308fa798bb56ecac38
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [19] : 0000000000000000000000008adb68e26b725af5e4b9c7deefe53d7edaaeec87


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.