creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/L1/Colosseum.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ISemver } from \"../universal/ISemver.sol\";\nimport { IZKMerkleTrie } from \"./IZKMerkleTrie.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\nimport { SecurityCouncil } from \"./SecurityCouncil.sol\";\nimport { ZKVerifier } from \"./ZKVerifier.sol\";\n\ncontract Colosseum is Initializable, ISemver {\n    /**\n     * @notice The constant value for the first turn.\n     */\n    uint8 internal constant TURN_INIT = 1;\n\n    /**\n     * @notice The constant value for the delete output root.\n     */\n    bytes32 internal constant DELETED_OUTPUT_ROOT = bytes32(0);\n\n    /**\n     * @notice Enum of the challenge status.\n     *\n     * See the https://github.com/kroma-network/kroma/blob/dev/specs/challenge.md#state-diagram\n     * for more details.\n     *\n     * Belows are possible state transitions at current implementation.\n     *\n     *  1) NONE               → createChallenge()                   → ASSERTER_TURN\n     *  2) ASSERTER_TURN      → bisect()                            → CHALLENGER_TURN\n     *  3) ASSERTER_TURN      → on bisection timeout                → ASSERTER_TIMEOUT\n     *  4) CHALLENGER_TURN    → bisect()                            → ASSERTER_TURN\n     *  5) CHALLENGER_TURN    → when isAbleToBisect() returns false → READY_TO_PROVE\n     *  6) CHALLENGER_TURN    → on bisection timeout                → CHALLENGER_TIMEOUT\n     *  7) ASSERTER_TIMEOUT   → when proveFault() succeeds          → NONE\n     *  8) ASSERTER_TIMEOUT   → on proving timeout                  → CHALLENGER_TIMEOUT\n     *  9) READY_TO_PROVE     → when proveFault() succeeds          → NONE\n     * 10) READY_TO_PROVE     → on proving timeout                  → CHALLENGER_TIMEOUT\n     * 11) CHALLENGER_TIMEOUT → challengerTimeout()                 → NONE\n     */\n    enum ChallengeStatus {\n        NONE,\n        CHALLENGER_TURN,\n        ASSERTER_TURN,\n        CHALLENGER_TIMEOUT,\n        ASSERTER_TIMEOUT,\n        READY_TO_PROVE\n    }\n\n    /**\n     * @notice Address of the L2OutputOracle.\n     */\n    L2OutputOracle public immutable L2_ORACLE;\n\n    /**\n     * @notice Address of the ZKVerifier.\n     */\n    ZKVerifier public immutable ZK_VERIFIER;\n\n    /**\n     * @notice The period seconds for which challenges can be created per each output.\n     */\n    uint256 public immutable CREATION_PERIOD_SECONDS;\n\n    /**\n     * @notice Timeout seconds for the bisection.\n     */\n    uint256 public immutable BISECTION_TIMEOUT;\n\n    /**\n     * @notice Timeout seconds for the proving.\n     */\n    uint256 public immutable PROVING_TIMEOUT;\n\n    /**\n     * @notice The interval in L2 blocks at which checkpoints must be\n     *         submitted on L2OutputOracle contract.\n     */\n    uint256 public immutable L2_ORACLE_SUBMISSION_INTERVAL;\n\n    /**\n     * @notice The dummy transaction hash. This is used to pad if the\n     *         number of transactions is less than MAX_TXS. This is same as:\n     *         unsignedTx = {\n     *           nonce: 0,\n     *           gasLimit: 0,\n     *           gasPrice: 0,\n     *           to: address(0),\n     *           value: 0,\n     *           data: '0x',\n     *           chainId: CHAIN_ID,\n     *         }\n     *         signature = sign(unsignedTx, 0x1)\n     *         dummyHash = keccak256(rlp({\n     *           ...unsignedTx,\n     *           signature,\n     *         }))\n     */\n    bytes32 public immutable DUMMY_HASH;\n\n    /**\n     * @notice The maximum number of transactions\n     */\n    uint256 public immutable MAX_TXS;\n\n    /**\n     * @notice Address that has the ability to approve the challenge.\n     */\n    address public immutable SECURITY_COUNCIL;\n\n    /**\n     * @notice Address that has the ability to verify the merkle proof.\n     */\n    address public immutable ZK_MERKLE_TRIE;\n\n    /**\n     * @notice Length of segment array for each turn.\n     */\n    mapping(uint256 => uint256) internal segmentsLengths;\n\n    /**\n     * @notice A mapping of the challenge.\n     */\n    mapping(uint256 => mapping(address => Types.Challenge)) public challenges;\n\n    /**\n     * @notice A mapping indicating whether a public input is verified or not.\n     */\n    mapping(bytes32 => bool) public verifiedPublicInputs;\n\n    /**\n     * @notice Emitted when the challenge is created.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param asserter    Address of the asserter.\n     * @param challenger  Address of the challenger.\n     * @param timestamp   The timestamp when created.\n     */\n    event ChallengeCreated(\n        uint256 indexed outputIndex,\n        address indexed asserter,\n        address indexed challenger,\n        uint256 timestamp\n    );\n\n    /**\n     * @notice Emitted when segments are bisected.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param challenger  Address of the challenger.\n     * @param turn        The current turn.\n     * @param timestamp   The timestamp when bisected.\n     */\n    event Bisected(\n        uint256 indexed outputIndex,\n        address indexed challenger,\n        uint8 turn,\n        uint256 timestamp\n    );\n\n    /**\n     * @notice Emitted when it is ready to be proved.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param challenger  Address of the challenger.\n     */\n    event ReadyToProve(uint256 indexed outputIndex, address indexed challenger);\n\n    /**\n     * @notice Emitted when proven fault.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param challenger  Address of the challenger.\n     * @param timestamp   The timestamp when proven.\n     */\n    event Proven(uint256 indexed outputIndex, address indexed challenger, uint256 timestamp);\n\n    /**\n     * @notice Emitted when challenge is dismissed.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param challenger  Address of the challenger.\n     * @param timestamp   The timestamp when dismissed.\n     */\n    event ChallengeDismissed(\n        uint256 indexed outputIndex,\n        address indexed challenger,\n        uint256 timestamp\n    );\n\n    /**\n     * @notice Emitted when challenge is canceled.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param challenger  Address of the challenger.\n     * @param timestamp   The timestamp when canceled.\n     */\n    event ChallengeCanceled(\n        uint256 indexed outputIndex,\n        address indexed challenger,\n        uint256 timestamp\n    );\n\n    /**\n     * @notice Emitted when challenger timed out.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param challenger  Address of the challenger.\n     * @param timestamp   The timestamp when deleted.\n     */\n    event ChallengerTimedOut(\n        uint256 indexed outputIndex,\n        address indexed challenger,\n        uint256 timestamp\n    );\n\n    /**\n     * @notice A modifier that only allows the security council to call\n     */\n    modifier onlySecurityCouncil() {\n        require(msg.sender == SECURITY_COUNCIL, \"Colosseum: sender is not the security council\");\n        _;\n    }\n\n    /**\n     * @notice Reverts if the output of given index is already finalized.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     */\n    modifier outputNotFinalized(uint256 _outputIndex) {\n        require(\n            !L2_ORACLE.isFinalized(_outputIndex),\n            \"Colosseum: cannot progress challenge process about already finalized output\"\n        );\n        _;\n    }\n\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.0.0\n     */\n    string public constant version = \"1.0.0\";\n\n    /**\n     * @notice Constructs the Colosseum contract.\n     *\n     * @param _l2Oracle              Address of the L2OutputOracle contract.\n     * @param _zkVerifier            Address of the ZKVerifier contract.\n     * @param _submissionInterval    Interval in blocks at which checkpoints must be submitted.\n     * @param _creationPeriodSeconds Seconds The period seconds for which challenges can be created per each output.\n     * @param _bisectionTimeout      Timeout seconds for the bisection.\n     * @param _provingTimeout        Timeout seconds for the proving.\n     * @param _dummyHash             Dummy hash.\n     * @param _maxTxs                Number of max transactions per block.\n     * @param _segmentsLengths       Lengths of segments.\n     * @param _securityCouncil       Address of security council.\n     * @param _zkMerkleTrie          Address of zk merkle trie.\n     */\n    constructor(\n        L2OutputOracle _l2Oracle,\n        ZKVerifier _zkVerifier,\n        uint256 _submissionInterval,\n        uint256 _creationPeriodSeconds,\n        uint256 _bisectionTimeout,\n        uint256 _provingTimeout,\n        bytes32 _dummyHash,\n        uint256 _maxTxs,\n        uint256[] memory _segmentsLengths,\n        address _securityCouncil,\n        address _zkMerkleTrie\n    ) {\n        L2_ORACLE = _l2Oracle;\n        ZK_VERIFIER = _zkVerifier;\n        CREATION_PERIOD_SECONDS = _creationPeriodSeconds;\n        BISECTION_TIMEOUT = _bisectionTimeout;\n        PROVING_TIMEOUT = _provingTimeout;\n        L2_ORACLE_SUBMISSION_INTERVAL = _submissionInterval;\n        DUMMY_HASH = _dummyHash;\n        MAX_TXS = _maxTxs;\n        SECURITY_COUNCIL = _securityCouncil;\n        ZK_MERKLE_TRIE = _zkMerkleTrie;\n        initialize(_segmentsLengths);\n    }\n\n    /**\n     * @notice Initializer.\n     */\n    function initialize(uint256[] memory _segmentsLengths) public initializer {\n        _setSegmentsLengths(_segmentsLengths);\n    }\n\n    /**\n     * @notice Creates a challenge against an invalid output.\n     *\n     * @param _outputIndex   Index of the invalid L2 checkpoint output.\n     * @param _l1BlockHash   The block hash of L1 at the time the output L2 block was created.\n     * @param _l1BlockNumber The block number of L1 with the specified L1 block hash.\n     * @param _segments      Array of the segment. A segment is the first output root of a specific range.\n     */\n    function createChallenge(\n        uint256 _outputIndex,\n        bytes32 _l1BlockHash,\n        uint256 _l1BlockNumber,\n        bytes32[] calldata _segments\n    ) external outputNotFinalized(_outputIndex) {\n        require(_outputIndex > 0, \"Colosseum: challenge for genesis output is not allowed\");\n\n        Types.Challenge storage challenge = challenges[_outputIndex][msg.sender];\n\n        if (challenge.turn >= TURN_INIT) {\n            ChallengeStatus status = _challengeStatus(challenge);\n            require(\n                status == ChallengeStatus.CHALLENGER_TIMEOUT,\n                \"Colosseum: the challenge for given output index is already in progress\"\n            );\n\n            _challengerTimeout(_outputIndex, msg.sender);\n        }\n\n        Types.CheckpointOutput memory targetOutput = L2_ORACLE.getL2Output(_outputIndex);\n\n        require(\n            targetOutput.timestamp + CREATION_PERIOD_SECONDS >= block.timestamp,\n            \"Colosseum: cannot create a challenge after the creation period\"\n        );\n\n        require(\n            targetOutput.outputRoot != DELETED_OUTPUT_ROOT,\n            \"Colosseum: challenge for deleted output is not allowed\"\n        );\n\n        require(\n            msg.sender != targetOutput.submitter,\n            \"Colosseum: the asserter and challenger must be different\"\n        );\n\n        if (_l1BlockHash != bytes32(0) && blockhash(_l1BlockNumber) != bytes32(0)) {\n            // Like L2OutputOracle, it reverts transactions when L1 reorged.\n            require(\n                blockhash(_l1BlockNumber) == _l1BlockHash,\n                \"Colosseum: block hash does not match the hash at the expected height\"\n            );\n        }\n\n        Types.CheckpointOutput memory prevOutput = L2_ORACLE.getL2Output(_outputIndex - 1);\n\n        // If the previous output has been deleted, the first segment will not be compared with the previous output.\n        if (prevOutput.outputRoot == DELETED_OUTPUT_ROOT) {\n            _validateSegments(TURN_INIT, _segments[0], targetOutput.outputRoot, _segments);\n        } else {\n            _validateSegments(TURN_INIT, prevOutput.outputRoot, targetOutput.outputRoot, _segments);\n        }\n\n        L2_ORACLE.VALIDATOR_POOL().addPendingBond(_outputIndex, msg.sender);\n\n        _updateSegments(\n            challenge,\n            _segments,\n            targetOutput.l2BlockNumber - L2_ORACLE_SUBMISSION_INTERVAL,\n            L2_ORACLE_SUBMISSION_INTERVAL\n        );\n        challenge.turn = TURN_INIT;\n        challenge.asserter = targetOutput.submitter;\n        challenge.challenger = msg.sender;\n        _updateTimeout(challenge);\n\n        emit ChallengeCreated(_outputIndex, targetOutput.submitter, msg.sender, block.timestamp);\n    }\n\n    /**\n     * @notice Selects an invalid section and submit segments of that section.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     * @param _pos         Position of the last valid segment.\n     * @param _segments    Array of the segment. A segment is the first output root of a specific range.\n     */\n    function bisect(\n        uint256 _outputIndex,\n        address _challenger,\n        uint256 _pos,\n        bytes32[] calldata _segments\n    ) external outputNotFinalized(_outputIndex) {\n        Types.Challenge storage challenge = challenges[_outputIndex][_challenger];\n        ChallengeStatus status = _challengeStatus(challenge);\n\n        if (_cancelIfOutputDeleted(_outputIndex, challenge.challenger, status)) {\n            return;\n        }\n\n        address expectedSender;\n        if (status == ChallengeStatus.CHALLENGER_TURN) {\n            expectedSender = challenge.challenger;\n        } else if (status == ChallengeStatus.ASSERTER_TURN) {\n            expectedSender = challenge.asserter;\n        }\n        require(msg.sender == expectedSender, \"Colosseum: not your turn\");\n\n        uint8 newTurn = challenge.turn + 1;\n\n        _validateSegments(\n            newTurn,\n            challenge.segments[_pos],\n            challenge.segments[_pos + 1],\n            _segments\n        );\n\n        uint256 segSize = _nextSegSize(challenge);\n        uint256 segStart = challenge.segStart + _pos * segSize;\n\n        _updateSegments(challenge, _segments, segStart, segSize);\n\n        challenge.turn = newTurn;\n        _updateTimeout(challenge);\n\n        emit Bisected(_outputIndex, _challenger, newTurn, block.timestamp);\n\n        if (!_isAbleToBisect(challenge)) {\n            emit ReadyToProve(_outputIndex, _challenger);\n        }\n    }\n\n    /**\n     * @notice Proves that a specific output is invalid using ZKP.\n     *         This function can only be called in the READY_TO_PROVE and ASSERTER_TIMEOUT states.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _pos         Position of the last valid segment.\n     * @param _proof       Proof for public input validation.\n     * @param _zkproof     Halo2 proofs composed of points and scalars.\n     *                     See https://zcash.github.io/halo2/design/implementation/proofs.html.\n     * @param _pair        Aggregated multi-opening proofs and public inputs. (Currently only 2 public inputs)\n     */\n    function proveFault(\n        uint256 _outputIndex,\n        uint256 _pos,\n        Types.PublicInputProof calldata _proof,\n        uint256[] calldata _zkproof,\n        uint256[] calldata _pair\n    ) external outputNotFinalized(_outputIndex) {\n        Types.Challenge storage challenge = challenges[_outputIndex][msg.sender];\n        ChallengeStatus status = _challengeStatus(challenge);\n\n        if (_cancelIfOutputDeleted(_outputIndex, challenge.challenger, status)) {\n            return;\n        }\n\n        require(\n            status == ChallengeStatus.READY_TO_PROVE || status == ChallengeStatus.ASSERTER_TIMEOUT,\n            \"Colosseum: impossible to prove the fault in current status\"\n        );\n\n        bytes32 srcOutputRoot = Hashing.hashOutputRootProof(_proof.srcOutputRootProof);\n        bytes32 dstOutputRoot = Hashing.hashOutputRootProof(_proof.dstOutputRootProof);\n\n        _validateOutputRootProof(\n            _pos,\n            challenge,\n            srcOutputRoot,\n            dstOutputRoot,\n            _proof.srcOutputRootProof,\n            _proof.dstOutputRootProof\n        );\n        _validatePublicInput(\n            _proof.srcOutputRootProof,\n            _proof.dstOutputRootProof,\n            _proof.publicInput,\n            _proof.rlps\n        );\n        _validateWithdrawalStorageRoot(\n            _proof.merkleProof,\n            _proof.l2ToL1MessagePasserBalance,\n            _proof.l2ToL1MessagePasserCodeHash,\n            _proof.dstOutputRootProof.messagePasserStorageRoot,\n            _proof.dstOutputRootProof.stateRoot\n        );\n\n        bytes32 publicInputHash = _hashPublicInput(\n            _proof.srcOutputRootProof.stateRoot,\n            _proof.publicInput\n        );\n\n        require(\n            !verifiedPublicInputs[publicInputHash],\n            \"Colosseum: public input that has already been validated cannot be used again\"\n        );\n\n        require(ZK_VERIFIER.verify(_zkproof, _pair, publicInputHash), \"Colosseum: invalid proof\");\n        emit Proven(_outputIndex, msg.sender, block.timestamp);\n\n        // Scope to call the security council, to avoid stack too deep.\n        {\n            Types.CheckpointOutput memory output = L2_ORACLE.getL2Output(_outputIndex);\n\n            bytes memory callbackData = abi.encodeWithSelector(\n                this.dismissChallenge.selector,\n                _outputIndex,\n                msg.sender,\n                challenge.asserter,\n                output.outputRoot,\n                publicInputHash\n            );\n\n            // Request outputRoot validation to security council\n            SecurityCouncil(SECURITY_COUNCIL).requestValidation(\n                output.outputRoot,\n                output.l2BlockNumber,\n                callbackData\n            );\n        }\n\n        verifiedPublicInputs[publicInputHash] = true;\n        delete challenges[_outputIndex][msg.sender];\n\n        // Delete output root.\n        L2_ORACLE.replaceL2Output(_outputIndex, DELETED_OUTPUT_ROOT, msg.sender);\n        // The challenger's bond is also included in the bond for that output.\n        L2_ORACLE.VALIDATOR_POOL().increaseBond(_outputIndex, msg.sender);\n    }\n\n    /**\n     * @notice Calls a private function that deletes the challenge because the challenger has timed out.\n     *         Reverts if the challenger hasn't timed out.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     */\n    function challengerTimeout(uint256 _outputIndex, address _challenger) external {\n        Types.Challenge storage challenge = challenges[_outputIndex][_challenger];\n        ChallengeStatus status = _challengeStatus(challenge);\n\n        require(\n            status == ChallengeStatus.CHALLENGER_TIMEOUT,\n            \"Colosseum: can only be called if the challenger is in timout\"\n        );\n\n        _challengerTimeout(_outputIndex, _challenger);\n    }\n\n    /**\n     * @notice Cancels the challenge.\n     *         Reverts if is not possible to cancel the sender's challenge for the given output index.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     */\n    function cancelChallenge(uint256 _outputIndex) external {\n        Types.Challenge storage challenge = challenges[_outputIndex][msg.sender];\n        ChallengeStatus status = _challengeStatus(challenge);\n\n        require(status != ChallengeStatus.NONE, \"Colosseum: the challenge does not exist\");\n\n        require(\n            _cancelIfOutputDeleted(_outputIndex, challenge.challenger, status),\n            \"Colosseum: challenge cannot be cancelled\"\n        );\n    }\n\n    /**\n     * @notice Dismisses the challenge and rollback l2 output.\n     *         This function can only be called by Security Council contract.\n     *\n     * @param _outputIndex      Index of the L2 checkpoint output.\n     * @param _challenger       Address of the challenger.\n     * @param _asserter         Address of the asserter.\n     * @param _outputRoot       The L2 output root to rollback.\n     * @param _publicInputHash  Hash of public input.\n     */\n    function dismissChallenge(\n        uint256 _outputIndex,\n        address _challenger,\n        address _asserter,\n        bytes32 _outputRoot,\n        bytes32 _publicInputHash\n    ) external onlySecurityCouncil {\n        require(\n            _outputRoot != DELETED_OUTPUT_ROOT,\n            \"Colosseum: cannot rollback output to zero hash\"\n        );\n        require(\n            L2_ORACLE.getL2Output(_outputIndex).outputRoot == DELETED_OUTPUT_ROOT,\n            \"Colosseum: only can rollback if the output has been deleted\"\n        );\n        verifiedPublicInputs[_publicInputHash] = false;\n\n        // Rollback output root.\n        L2_ORACLE.replaceL2Output(_outputIndex, _outputRoot, _asserter);\n\n        emit ChallengeDismissed(_outputIndex, _challenger, block.timestamp);\n    }\n\n    /**\n     * @notice Deletes the L2 output root forcefully by the Security Council\n     *         when zk-proving is not possible due to an undeniable bug.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     */\n    function forceDeleteOutput(uint256 _outputIndex)\n        external\n        onlySecurityCouncil\n        outputNotFinalized(_outputIndex)\n    {\n        // Check if the output is deleted.\n        Types.CheckpointOutput memory output = L2_ORACLE.getL2Output(_outputIndex);\n        require(\n            output.outputRoot != DELETED_OUTPUT_ROOT,\n            \"Colosseum: the output has already been deleted\"\n        );\n\n        // Delete output root.\n        L2_ORACLE.replaceL2Output(_outputIndex, DELETED_OUTPUT_ROOT, SECURITY_COUNCIL);\n    }\n\n    /**\n     * @notice Reverts if the given segments are invalid.\n     *\n     * @param _turn      The current turn.\n     * @param _prevFirst The first segment of previous turn.\n     * @param _prevLast  The last segment of previous turn.\n     * @param _segments  Array of the segment.\n     */\n    function _validateSegments(\n        uint8 _turn,\n        bytes32 _prevFirst,\n        bytes32 _prevLast,\n        bytes32[] memory _segments\n    ) private view {\n        uint256 segLen = _segments.length;\n\n        require(getSegmentsLength(_turn) == segLen, \"Colosseum: invalid segments length\");\n        require(_prevFirst == _segments[0], \"Colosseum: the first segment must be matched\");\n        require(\n            _prevLast != _segments[segLen - 1],\n            \"Colosseum: the last segment must not be matched\"\n        );\n    }\n\n    /**\n     * @notice Updates the segment information for a given challenge.\n     *\n     * @param _challenge The challenge data.\n     * @param _segments  Array of the segment.\n     * @param _segStart  The L2 block number of the first segment.\n     * @param _segSize   The number of L2 blocks.\n     */\n    function _updateSegments(\n        Types.Challenge storage _challenge,\n        bytes32[] memory _segments,\n        uint256 _segStart,\n        uint256 _segSize\n    ) private {\n        _challenge.segments = _segments;\n        _challenge.segStart = _segStart;\n        _challenge.segSize = _segSize;\n    }\n\n    /**\n     * @notice Updates timestamp of the challenge timeout.\n     *\n     * @param _challenge The challenge data to update.\n     */\n    function _updateTimeout(Types.Challenge storage _challenge) private {\n        if (!_isAbleToBisect(_challenge)) {\n            _challenge.timeoutAt = uint64(block.timestamp + PROVING_TIMEOUT);\n        } else {\n            _challenge.timeoutAt = uint64(block.timestamp + BISECTION_TIMEOUT);\n        }\n    }\n\n    /**\n     * @notice Validates and updates the lengths of segments.\n     *\n     * @param _segmentsLengths Lengths of segments.\n     */\n    function _setSegmentsLengths(uint256[] memory _segmentsLengths) private {\n        // _segmentsLengths length should be an even number in order to let challenger submit\n        // invalidity proof at the last turn.\n        require(\n            _segmentsLengths.length % 2 == 0,\n            \"Colosseum: length of segments lengths cannot be odd number\"\n        );\n\n        uint256 sum = 1;\n        for (uint256 i = 0; i < _segmentsLengths.length; ) {\n            segmentsLengths[i] = _segmentsLengths[i];\n            sum = sum * (_segmentsLengths[i] - 1);\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        require(sum == L2_ORACLE_SUBMISSION_INTERVAL, \"Colosseum: invalid segments lengths\");\n    }\n\n    /**\n     * @notice Checks if the L2ToL1MesagePasser account is included in the given state root.\n     *\n     * @param _merkleProof                 Merkle proof of L2ToL1MessagePasser account against the state root.\n     * @param _l2ToL1MessagePasserBalance  Balance of the L2ToL1MessagePasser account.\n     * @param _l2ToL1MessagePasserCodeHash Codehash of the L2ToL1MessagePasser account.\n     * @param _messagePasserStorageRoot    Storage root of the L2ToL1MessagePasser account.\n     * @param _stateRoot                   State root.\n     */\n    function _validateWithdrawalStorageRoot(\n        bytes[] calldata _merkleProof,\n        bytes32 _l2ToL1MessagePasserBalance,\n        bytes32 _l2ToL1MessagePasserCodeHash,\n        bytes32 _messagePasserStorageRoot,\n        bytes32 _stateRoot\n    ) private view {\n        // TODO(chokobole): Can we fix the codeHash?\n        bytes memory l2ToL1MessagePasserAccount = abi.encodePacked(\n            uint256(0), // nonce\n            _l2ToL1MessagePasserBalance, // balance,\n            _l2ToL1MessagePasserCodeHash, // codeHash,\n            _messagePasserStorageRoot // storage root\n        );\n\n        require(\n            IZKMerkleTrie(ZK_MERKLE_TRIE).verifyInclusionProof(\n                bytes32(bytes20(Predeploys.L2_TO_L1_MESSAGE_PASSER)),\n                l2ToL1MessagePasserAccount,\n                _merkleProof,\n                _stateRoot\n            ),\n            \"Colosseum: invalid L2ToL1MessagePasser inclusion proof\"\n        );\n    }\n\n    /**\n     * @notice Validates the output root proofs.\n     *\n     * @param _pos                Position of the last valid segment.\n     * @param _challenge          The challenge data.\n     * @param _srcOutputRoot      The source output root.\n     * @param _dstOutputRoot      The destination output root.\n     * @param _srcOutputRootProof Proof of the source output root.\n     * @param _dstOutputRootProof Proof of the destination output root.\n     */\n    function _validateOutputRootProof(\n        uint256 _pos,\n        Types.Challenge storage _challenge,\n        bytes32 _srcOutputRoot,\n        bytes32 _dstOutputRoot,\n        Types.OutputRootProof calldata _srcOutputRootProof,\n        Types.OutputRootProof calldata _dstOutputRootProof\n    ) private view {\n        require(\n            _challenge.segments[_pos] == _srcOutputRoot,\n            \"Colosseum: the source segment must be matched\"\n        );\n\n        // If asserter timeout, the bisection of segments may not have ended.\n        // Therefore, segment validation only proceeds when bisection is not possible.\n        if (!_isAbleToBisect(_challenge)) {\n            require(\n                _challenge.segments[_pos + 1] != _dstOutputRoot,\n                \"Colosseum: the destination segment must not be matched\"\n            );\n        }\n\n        require(\n            _srcOutputRootProof.nextBlockHash == _dstOutputRootProof.blockHash,\n            \"Colosseum: the block hash must be matched\"\n        );\n    }\n\n    /**\n     * @notice Checks if the public input is valid.\n     *         Reverts if public input is invalid.\n     *\n     * @param _srcOutputRootProof Proof of the source output root.\n     * @param _dstOutputRootProof Proof of the destination output root.\n     * @param _publicInput        Ingredients to compute the public input used by ZK proof verification.\n     * @param _rlps               Pre-encoded RLPs to compute the next block hash of the source output root proof.\n     */\n    function _validatePublicInput(\n        Types.OutputRootProof calldata _srcOutputRootProof,\n        Types.OutputRootProof calldata _dstOutputRootProof,\n        Types.PublicInput calldata _publicInput,\n        Types.BlockHeaderRLP calldata _rlps\n    ) private pure {\n        // TODO(chokobole): check withdrawal storage root of _dstOutputRootProof against state root of _dstOutputRootProof.\n        require(\n            _publicInput.stateRoot == _dstOutputRootProof.stateRoot,\n            \"Colosseum: the state root must be matched\"\n        );\n\n        bytes32 blockHash = Hashing.hashBlockHeaderShanghai(_publicInput, _rlps);\n        require(\n            _srcOutputRootProof.nextBlockHash == blockHash,\n            \"Colosseum: the block hash from public input must be matched\"\n        );\n    }\n\n    /**\n     * @notice Cancels the challenge if the output root to be challenged has already been deleted.\n     *         If the output root has been deleted, delete the challenge and refund the challenger's pending bond.\n     *         Reverts when challenger is timed out or called by non-challenger.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     * @param _status      Current status of the challenge.\n     *\n     * @return Whether the challenge was canceled.\n     */\n    function _cancelIfOutputDeleted(\n        uint256 _outputIndex,\n        address _challenger,\n        ChallengeStatus _status\n    ) private returns (bool) {\n        bytes32 outputRoot = L2_ORACLE.getL2Output(_outputIndex).outputRoot;\n        if (outputRoot != DELETED_OUTPUT_ROOT) {\n            return false;\n        }\n\n        // If the output is deleted, the asserter does not need to do anything further.\n        require(msg.sender == _challenger, \"Colosseum: sender is not a challenger\");\n\n        require(\n            _status != ChallengeStatus.CHALLENGER_TIMEOUT,\n            \"Colosseum: challenge cannot be cancelled if challenger timed out\"\n        );\n\n        delete challenges[_outputIndex][msg.sender];\n        emit ChallengeCanceled(_outputIndex, msg.sender, block.timestamp);\n\n        L2_ORACLE.VALIDATOR_POOL().releasePendingBond(_outputIndex, msg.sender, msg.sender);\n\n        return true;\n    }\n\n    /**\n     * @notice Deletes the challenge because the challenger timed out.\n     *         The winner is the asserter, and challenger loses the bond.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     */\n    function _challengerTimeout(uint256 _outputIndex, address _challenger) private {\n        delete challenges[_outputIndex][_challenger];\n        emit ChallengerTimedOut(_outputIndex, _challenger, block.timestamp);\n\n        // After output is finalized, the challenger's bond is included in the balance of output submitter.\n        if (L2_ORACLE.isFinalized(_outputIndex)) {\n            Types.CheckpointOutput memory targetOutput = L2_ORACLE.getL2Output(_outputIndex);\n            L2_ORACLE.VALIDATOR_POOL().releasePendingBond(\n                _outputIndex,\n                _challenger,\n                targetOutput.submitter\n            );\n        } else {\n            // Because the challenger lost, the challenger's bond is included in the bond for that output.\n            L2_ORACLE.VALIDATOR_POOL().increaseBond(_outputIndex, _challenger);\n        }\n    }\n\n    /**\n     * @notice Hashes the public input with padding dummy transactions.\n     *\n     * @param _prevStateRoot Previous state root.\n     * @param _publicInput   Ingredients to compute the public input used by ZK proof verification.\n     *\n     * @return Hash of public input.\n     */\n    function _hashPublicInput(bytes32 _prevStateRoot, Types.PublicInput calldata _publicInput)\n        private\n        view\n        returns (bytes32)\n    {\n        bytes32[] memory dummyHashes;\n        if (_publicInput.txHashes.length < MAX_TXS) {\n            dummyHashes = Hashing.generateDummyHashes(\n                DUMMY_HASH,\n                MAX_TXS - _publicInput.txHashes.length\n            );\n        }\n\n        // NOTE(chokobole): We cannot calculate the Ethereum transaction root solely\n        // based on transaction hashes. It is necessary to have access to the original\n        // transactions. Considering the imposed constraints and the difficulty\n        // of providing a preimage that would generate the desired public input hash\n        // from an attacker's perspective, we have decided to omit the verification\n        // using the transaction root.\n        return Hashing.hashPublicInput(_prevStateRoot, _publicInput, dummyHashes);\n    }\n\n    /**\n     * @notice Returns the number of L2 blocks for the next turn.\n     *\n     * @param _challenge The current challenge data.\n     *\n     * @return The number of L2 blocks for the next turn.\n     */\n    function _nextSegSize(Types.Challenge storage _challenge) private view returns (uint256) {\n        uint8 turn = _challenge.turn;\n        return _challenge.segSize / (getSegmentsLength(turn) - 1);\n    }\n\n    /**\n     * @notice Determines whether a given timestamp is past.\n     *\n     * @param _sec The timestamp to check.\n     *\n     * @return Whether it's in the past.\n     */\n    function _isPast(uint256 _sec) private view returns (bool) {\n        return block.timestamp > _sec;\n    }\n\n    /**\n     * @notice Determines if bisection is possible.\n     *\n     * @param _challenge The current challenge data.\n     *\n     * @return Whether bisection is possible.\n     */\n    function _isAbleToBisect(Types.Challenge storage _challenge) private view returns (bool) {\n        return _nextSegSize(_challenge) > 1;\n    }\n\n    /**\n     * @notice Determines if the next turn is the challenger's turn.\n     *         Note that challenger turns are odd numbers and asserter turns are even numbers.\n     *\n     * @param _turn The current turn.\n     *\n     * @return Whether the next turn is the challenger's turn.\n     */\n    function _isNextForChallenger(uint8 _turn) private pure returns (bool) {\n        // If the _turn value is even, it means that the asserter has completed its turn,\n        // so the next turn will be the challenger's turn.\n        return _turn % 2 == 0;\n    }\n\n    /**\n     * @notice Returns status of a given challenge.\n     *\n     * @param _challenge The challenge data.\n     *\n     * @return The status of the challenge.\n     */\n    function _challengeStatus(Types.Challenge storage _challenge)\n        private\n        view\n        returns (ChallengeStatus)\n    {\n        if (_challenge.turn < TURN_INIT) {\n            return ChallengeStatus.NONE;\n        }\n\n        bool isChallengerTurn = _isNextForChallenger(_challenge.turn);\n\n        // Check if it's a timed out challenge.\n        if (_isPast(_challenge.timeoutAt)) {\n            // timeout on challenger turn\n            if (isChallengerTurn) {\n                return ChallengeStatus.CHALLENGER_TIMEOUT;\n            }\n\n            // If the asserter times out and the challenger does not prove fault,\n            // the challenger is assumed to have timed out.\n            if (_isPast(_challenge.timeoutAt + PROVING_TIMEOUT)) {\n                return ChallengeStatus.CHALLENGER_TIMEOUT;\n            }\n\n            // timeout on asserter turn\n            return ChallengeStatus.ASSERTER_TIMEOUT;\n        }\n\n        // If bisection is not possible, the Challenger must execute the fault proof.\n        if (!_isAbleToBisect(_challenge)) {\n            return ChallengeStatus.READY_TO_PROVE;\n        }\n\n        return isChallengerTurn ? ChallengeStatus.CHALLENGER_TURN : ChallengeStatus.ASSERTER_TURN;\n    }\n\n    /**\n     * @notice Returns the challenge corresponding to the given L2 output index.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     *\n     * @return The challenge data.\n     */\n    function getChallenge(uint256 _outputIndex, address _challenger)\n        external\n        view\n        returns (Types.Challenge memory)\n    {\n        return challenges[_outputIndex][_challenger];\n    }\n\n    /**\n     * @notice Returns the challenge status corresponding to the given L2 output index.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     *\n     * @return The status of the challenge.\n     */\n    function getStatus(uint256 _outputIndex, address _challenger)\n        external\n        view\n        returns (ChallengeStatus)\n    {\n        Types.Challenge storage challenge = challenges[_outputIndex][_challenger];\n        return _challengeStatus(challenge);\n    }\n\n    /**\n     * @notice Returns the segment length required for that turn.\n     *\n     * @param _turn The challenge turn.\n     *\n     * @return The segments length.\n     */\n    function getSegmentsLength(uint8 _turn) public view returns (uint256) {\n        require(_turn >= TURN_INIT, \"Colosseum: invalid turn\");\n        return segmentsLengths[_turn - 1];\n    }\n\n    /**\n     * @notice Determines whether bisection is possible in the challenge corresponding to the given\n     *         L2 output index.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     *\n     * @return Whether bisection is possible.\n     */\n    function isAbleToBisect(uint256 _outputIndex, address _challenger) public view returns (bool) {\n        Types.Challenge storage challenge = challenges[_outputIndex][_challenger];\n        return _isAbleToBisect(challenge);\n    }\n\n    /**\n     * @notice Determines whether current timestamp is in challenge creation period corresponding to the given L2 output index.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     *\n     * @return Whether current timestamp is in challenge creation period.\n     */\n    function isInCreationPeriod(uint256 _outputIndex) external view returns (bool) {\n        Types.CheckpointOutput memory targetOutput = L2_ORACLE.getL2Output(_outputIndex);\n        return targetOutput.timestamp + CREATION_PERIOD_SECONDS >= block.timestamp;\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: setting the version to 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _initializing;\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "contracts/libraries/Hashing.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Encoding } from \"./Encoding.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\nimport { Types } from \"./Types.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Kroma's various different hashing schemes.\n */\nlibrary Hashing {\n    /**\n     * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n     *         given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n     *         system.\n     *\n     * @param _tx User deposit transaction to hash.\n     *\n     * @return Hash of the RLP encoded L2 deposit transaction.\n     */\n    function hashDepositTransaction(\n        Types.UserDepositTransaction memory _tx\n    ) internal pure returns (bytes32) {\n        return keccak256(Encoding.encodeDepositTransaction(_tx));\n    }\n\n    /**\n     * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n     *         of the L2 transaction that corresponds to a deposit is unique and is\n     *         deterministically generated from L1 transaction data.\n     *\n     * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n     * @param _logIndex    The index of the log that created the deposit transaction.\n     *\n     * @return Hash of the deposit transaction's \"source hash\".\n     */\n    function hashDepositSource(\n        bytes32 _l1BlockHash,\n        uint64 _logIndex\n    ) internal pure returns (bytes32) {\n        bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n        return keccak256(abi.encode(bytes32(0), depositId));\n    }\n\n    /**\n     * @notice Hashes the cross domain message based on the version that is encoded into the\n     *         message nonce.\n     *\n     * @param _nonce    Message nonce with version encoded into the first two bytes.\n     * @param _sender   Address of the sender of the message.\n     * @param _target   Address of the target of the message.\n     * @param _value    ETH value to send to the target.\n     * @param _gasLimit Gas limit to use for the message.\n     * @param _data     Data to send with the message.\n     *\n     * @return Hashed cross domain message.\n     */\n    function hashCrossDomainMessage(\n        uint256 _nonce,\n        address _sender,\n        address _target,\n        uint256 _value,\n        uint256 _gasLimit,\n        bytes memory _data\n    ) internal pure returns (bytes32) {\n        (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n        if (version == 0) {\n            return hashCrossDomainMessageV0(_nonce, _sender, _target, _value, _gasLimit, _data);\n        } else {\n            revert(\"Hashing: unknown cross domain message version\");\n        }\n    }\n\n    /**\n     * @notice Hashes a cross domain message based on the V0 (current) encoding.\n     *\n     * @param _nonce    Message nonce.\n     * @param _sender   Address of the sender of the message.\n     * @param _target   Address of the target of the message.\n     * @param _value    ETH value to send to the target.\n     * @param _gasLimit Gas limit to use for the message.\n     * @param _data     Data to send with the message.\n     *\n     * @return Hashed cross domain message.\n     */\n    function hashCrossDomainMessageV0(\n        uint256 _nonce,\n        address _sender,\n        address _target,\n        uint256 _value,\n        uint256 _gasLimit,\n        bytes memory _data\n    ) internal pure returns (bytes32) {\n        return\n            keccak256(\n                Encoding.encodeCrossDomainMessageV0(\n                    _nonce,\n                    _sender,\n                    _target,\n                    _value,\n                    _gasLimit,\n                    _data\n                )\n            );\n    }\n\n    /**\n     * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n     *\n     * @param _tx Withdrawal transaction to hash.\n     *\n     * @return Hashed withdrawal transaction.\n     */\n    function hashWithdrawal(\n        Types.WithdrawalTransaction memory _tx\n    ) internal pure returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n            );\n    }\n\n    /**\n     * @notice Hashes the various elements of an output root proof into an output root hash which\n     *         can be used to check if the proof is valid.\n     *\n     * @param _outputRootProof Output root proof which should be hashed to an output root.\n     *\n     * @return Hashed output root proof.\n     */\n    function hashOutputRootProof(\n        Types.OutputRootProof memory _outputRootProof\n    ) internal pure returns (bytes32) {\n        if (_outputRootProof.version == bytes32(uint256(0))) {\n            return hashOutputRootProofV0(_outputRootProof);\n        } else {\n            revert(\"Hashing: unknown output root proof version\");\n        }\n    }\n\n    /**\n     * @notice Hashes the various elements of an output root proof into an output root hash which\n     *         can be used to check if the proof is valid. (version 0)\n     *\n     * @param _outputRootProof Output root proof which should be hashed to an output root.\n     *\n     * @return Hashed output root proof.\n     */\n    function hashOutputRootProofV0(\n        Types.OutputRootProof memory _outputRootProof\n    ) internal pure returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    _outputRootProof.version,\n                    _outputRootProof.stateRoot,\n                    _outputRootProof.messagePasserStorageRoot,\n                    _outputRootProof.blockHash,\n                    _outputRootProof.nextBlockHash\n                )\n            );\n    }\n\n    /**\n     * @notice Fills the values of the block hash fields to a given bytes.\n     *\n     * @param _publicInput Public input which should be hashed to a block hash.\n     * @param _rlps        Pre-RLP encoded data which should be hashed to a block hash.\n     * @param _raw         An array of bytes to be populated.\n     */\n    function _fillBlockHashFieldsToBytes(\n        Types.PublicInput memory _publicInput,\n        Types.BlockHeaderRLP memory _rlps,\n        bytes[] memory _raw\n    ) private pure {\n        _raw[0] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.parentHash));\n        _raw[1] = _rlps.uncleHash;\n        _raw[2] = _rlps.coinbase;\n        _raw[3] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.stateRoot));\n        _raw[4] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.transactionsRoot));\n        _raw[5] = _rlps.receiptsRoot;\n        _raw[6] = _rlps.logsBloom;\n        _raw[7] = _rlps.difficulty;\n        _raw[8] = RLPWriter.writeUint(_publicInput.number);\n        _raw[9] = RLPWriter.writeUint(_publicInput.gasLimit);\n        _raw[10] = _rlps.gasUsed;\n        _raw[11] = RLPWriter.writeUint(_publicInput.timestamp);\n        _raw[12] = _rlps.extraData;\n        _raw[13] = _rlps.mixHash;\n        _raw[14] = _rlps.nonce;\n        _raw[15] = RLPWriter.writeUint(_publicInput.baseFee);\n    }\n\n    /**\n     * @notice Hashes the various elements of a block header into a block hash(before shanghai).\n     *\n     * @param _publicInput Public input which should be hashed to a block hash.\n     * @param _rlps        Pre-RLP encoded data which should be hashed to a block hash.\n     *\n     * @return Hashed block header.\n     */\n    function hashBlockHeader(\n        Types.PublicInput memory _publicInput,\n        Types.BlockHeaderRLP memory _rlps\n    ) internal pure returns (bytes32) {\n        bytes[] memory raw = new bytes[](16);\n        _fillBlockHashFieldsToBytes(_publicInput, _rlps, raw);\n        return keccak256(RLPWriter.writeList(raw));\n    }\n\n    /**\n     * @notice Hashes the various elements of a block header into a block hash(after shanghai).\n     *\n     * @param _publicInput Public input which should be hashed to a block hash.\n     * @param _rlps        Pre-RLP encoded data which should be hashed to a block hash.\n     *\n     * @return Hashed block header.\n     */\n    function hashBlockHeaderShanghai(\n        Types.PublicInput memory _publicInput,\n        Types.BlockHeaderRLP memory _rlps\n    ) internal pure returns (bytes32) {\n        bytes[] memory raw = new bytes[](17);\n        _fillBlockHashFieldsToBytes(_publicInput, _rlps, raw);\n        raw[16] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.withdrawalsRoot));\n        return keccak256(RLPWriter.writeList(raw));\n    }\n\n    /**\n     * @notice Hashes the various elements of a public input into a public input hash.\n     *\n     * @param _prevStateRoot Previous state root.\n     * @param _publicInput   Public input which should be hashed to a public input hash.\n     * @param _dummyHashes   Dummy hashes returned from generateDummyHashes().\n     *\n     * @return Hashed block header.\n     */\n    function hashPublicInput(\n        bytes32 _prevStateRoot,\n        Types.PublicInput memory _publicInput,\n        bytes32[] memory _dummyHashes\n    ) internal pure returns (bytes32) {\n        return\n            keccak256(\n                abi.encodePacked(\n                    _prevStateRoot,\n                    _publicInput.stateRoot,\n                    // NOTE(0xHansLee): the withdrawalsRoot is not used in Scroll's zkEVM circuit, so it is filled by zero\n                    bytes32(0),\n                    _publicInput.blockHash,\n                    _publicInput.parentHash,\n                    _publicInput.number,\n                    _publicInput.timestamp,\n                    _publicInput.baseFee,\n                    _publicInput.gasLimit,\n                    uint16(_publicInput.txHashes.length),\n                    _publicInput.txHashes,\n                    _dummyHashes\n                )\n            );\n    }\n\n    /**\n     * @notice Generates a bytes32 array filled with a dummy hash for the given length.\n     *\n     * @param _dummyHashes Dummy hash.\n     * @param _length      A length of the array.\n     *\n     * @return Bytes32 array filled with dummy hash.\n     */\n    function generateDummyHashes(\n        bytes32 _dummyHashes,\n        uint256 _length\n    ) internal pure returns (bytes32[] memory) {\n        bytes32[] memory hashes = new bytes32[](_length);\n        for (uint256 i = 0; i < _length; i++) {\n            hashes[i] = _dummyHashes;\n        }\n        return hashes;\n    }\n}\n"
      },
      "contracts/libraries/Predeploys.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Predeploys\n * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.\n */\nlibrary Predeploys {\n    /**\n     * @notice Address of the ProxyAdmin predeploy.\n     */\n    address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000000;\n\n    /**\n     * @notice Address of the L1Block predeploy.\n     */\n    address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000002;\n\n    /**\n     * @notice Address of the L2ToL1MessagePasser predeploy.\n     */\n    address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000003;\n\n    /**\n     * @notice Address of the L2CrossDomainMessenger predeploy.\n     */\n    address internal constant L2_CROSS_DOMAIN_MESSENGER =\n        0x4200000000000000000000000000000000000004;\n\n    /**\n     * @notice Address of the GasPriceOracle predeploy. Includes fee information\n     *         and helpers for computing the L1 portion of the transaction fee.\n     */\n    address internal constant GAS_PRICE_ORACLE = 0x4200000000000000000000000000000000000005;\n\n    /**\n     * @notice Address of the ProtocolVault predeploy.\n     */\n    address internal constant PROTOCOL_VAULT = 0x4200000000000000000000000000000000000006;\n\n    /**\n     * @notice Address of the L1FeeVault predeploy.\n     */\n    address internal constant L1_FEE_VAULT = 0x4200000000000000000000000000000000000007;\n\n    /**\n     * @notice Address of the ValidatorRewardVault predeploy.\n     */\n    address internal constant VALIDATOR_REWARD_VAULT = 0x4200000000000000000000000000000000000008;\n\n    /**\n     * @notice Address of the L2StandardBridge predeploy.\n     */\n    address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000009;\n\n    /**\n     * @notice Address of the L2ERC721Bridge predeploy.\n     */\n    address internal constant L2_ERC721_BRIDGE = 0x420000000000000000000000000000000000000A;\n\n    /**\n     * @notice Address of the KromaMintableERC20Factory predeploy.\n     */\n    address internal constant KROMA_MINTABLE_ERC20_FACTORY =\n        0x420000000000000000000000000000000000000B;\n\n    /**\n     * @notice Address of the KromaMintableERC721Factory predeploy.\n     */\n    address internal constant KROMA_MINTABLE_ERC721_FACTORY =\n        0x420000000000000000000000000000000000000c;\n}\n"
      },
      "contracts/libraries/Types.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Kroma contract system.\n */\nlibrary Types {\n    /**\n     * @notice CheckpointOutput represents a commitment to the state of L2 checkpoint. The timestamp\n     *         is the L1 timestamp that the output root is posted. This timestamp is used to verify\n     *         that the finalization period has passed since the output root was submitted.\n     *\n     * @custom:field submitter     Address of the output submitter.\n     * @custom:field outputRoot    Hash of the L2 output.\n     * @custom:field timestamp     Timestamp of the L1 block that the output root was submitted in.\n     * @custom:field l2BlockNumber L2 block number that the output corresponds to.\n     */\n    struct CheckpointOutput {\n        address submitter;\n        bytes32 outputRoot;\n        uint128 timestamp;\n        uint128 l2BlockNumber;\n    }\n\n    /**\n     * @notice Struct representing the elements that are hashed together to generate an output root\n     *         which itself represents a snapshot of the L2 state.\n     *\n     * @custom:field version                  Version of the output root.\n     * @custom:field stateRoot                Root of the state trie at the block of this output.\n     * @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n     * @custom:field blockHash                Hash of the block this output was generated from.\n     * @custom:field nextBlockHash            Hash of the next block.\n     */\n    struct OutputRootProof {\n        bytes32 version;\n        bytes32 stateRoot;\n        bytes32 messagePasserStorageRoot;\n        bytes32 blockHash;\n        bytes32 nextBlockHash;\n    }\n\n    /**\n     * @notice Struct representing the elements that are hashed together to generate a public input.\n     *\n     * @custom:field blockHash        The hash of the block.\n     * @custom:field parentHash       The hash of the previous block.\n     * @custom:field timestamp        The block time.\n     * @custom:field number           The block number.\n     * @custom:field gasLimit         Maximum gas allowed.\n     * @custom:field baseFee          The base fee per gas.\n     * @custom:field transactionsRoot Root hash of the transactions.\n     * @custom:field stateRoot        Root hash of the state trie.\n     * @custom:field withdrawalsRoot  Root hash of the withdrawals.\n     * @custom:field txHashes         Array of hash of the transaction.\n     */\n    struct PublicInput {\n        bytes32 blockHash;\n        bytes32 parentHash;\n        uint64 timestamp;\n        uint64 number;\n        uint64 gasLimit;\n        uint256 baseFee;\n        bytes32 transactionsRoot;\n        bytes32 stateRoot;\n        bytes32 withdrawalsRoot;\n        bytes32[] txHashes;\n    }\n\n    /**\n     * @notice Struct representing the elements that are hashed together to generate a block hash.\n     *         Some of fields that are contained in PublicInput are omitted.\n     *\n     * @custom:field uncleHash    RLP encoded uncle hash.\n     * @custom:field coinbase     RLP encoded coinbase.\n     * @custom:field receiptsRoot RLP encoded receipts root.\n     * @custom:field logsBloom    RLP encoded logs bloom.\n     * @custom:field difficulty   RLP encoded difficulty.\n     * @custom:field gasUsed      RLP encoded gas used.\n     * @custom:field extraData    RLP encoded extra data.\n     * @custom:field mixHash      RLP encoded mix hash.\n     * @custom:field nonce        RLP encoded nonce.\n     */\n    struct BlockHeaderRLP {\n        bytes uncleHash;\n        bytes coinbase;\n        bytes receiptsRoot;\n        bytes logsBloom;\n        bytes difficulty;\n        bytes gasUsed;\n        bytes extraData;\n        bytes mixHash;\n        bytes nonce;\n    }\n\n    /**\n     * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n     *         user (as opposed to a system deposit transaction generated by the system).\n     *\n     * @custom:field from        Address of the sender of the transaction.\n     * @custom:field to          Address of the recipient of the transaction.\n     * @custom:field isCreation  True if the transaction is a contract creation.\n     * @custom:field value       Value to send to the recipient.\n     * @custom:field mint        Amount of ETH to mint.\n     * @custom:field gasLimit    Gas limit of the transaction.\n     * @custom:field data        Data of the transaction.\n     * @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n     * @custom:field logIndex    Index of the log in the block the transaction was submitted in.\n     */\n    struct UserDepositTransaction {\n        address from;\n        address to;\n        bool isCreation;\n        uint256 value;\n        uint256 mint;\n        uint64 gasLimit;\n        bytes data;\n        bytes32 l1BlockHash;\n        uint64 logIndex;\n    }\n\n    /**\n     * @notice Struct representing a withdrawal transaction.\n     *\n     * @custom:field nonce    Nonce of the withdrawal transaction\n     * @custom:field sender   Address of the sender of the transaction.\n     * @custom:field target   Address of the recipient of the transaction.\n     * @custom:field value    Value to send to the recipient.\n     * @custom:field gasLimit Gas limit of the transaction.\n     * @custom:field data     Data of the transaction.\n     */\n    struct WithdrawalTransaction {\n        uint256 nonce;\n        address sender;\n        address target;\n        uint256 value;\n        uint256 gasLimit;\n        bytes data;\n    }\n\n    /**\n     * @notice Struct representing a challenge.\n     *\n     * @custom:field turn       The current turn.\n     * @custom:field timeoutAt  Timeout timestamp of the next turn.\n     * @custom:field asserter   Address of the asserter.\n     * @custom:field challenger Address of the challenger.\n     * @custom:field segments   Array of the segment.\n     * @custom:field segStart   The L2 block number of the first segment.\n     * @custom:field segSize    The number of L2 blocks.\n     */\n    struct Challenge {\n        uint8 turn;\n        uint64 timeoutAt;\n        address asserter;\n        address challenger;\n        bytes32[] segments;\n        uint256 segSize;\n        uint256 segStart;\n    }\n\n    /**\n     * @notice Struct representing a validator's bond.\n     *\n     * @custom:field amount    Amount of the lock.\n     * @custom:field expiresAt The expiration timestamp of bond.\n     */\n    struct Bond {\n        uint128 amount;\n        uint128 expiresAt;\n    }\n\n    /**\n     * @notice Struct representing multisig transaction data.\n     *\n     * @custom:field target   The destination address to run the transaction.\n     * @custom:field executed Record whether a transaction was executed or not.\n     * @custom:field value    The value passed in while executing the transaction.\n     * @custom:field data     Calldata for transaction.\n     */\n    struct MultiSigTransaction {\n        address target;\n        bool executed;\n        uint256 value;\n        bytes data;\n    }\n\n    /**\n     * @notice Struct representing multisig confirmation data.\n     *\n     * @custom:field confirmationCount The sum of confirmations.\n     * @custom:field confirmedBy       Map data that stores whether confirmation is performed by account.\n     */\n    struct MultiSigConfirmation {\n        uint256 confirmationCount;\n        mapping(address => bool) confirmedBy;\n    }\n\n    /**\n     * @notice Struct representing the data for verifying the public input.\n     *\n     * @custom:field srcOutputRootProof          Proof of the source output root.\n     * @custom:field dstOutputRootProof          Proof of the destination output root.\n     * @custom:field publicInput                 Ingredients to compute the public input used by ZK proof verification.\n     * @custom:field rlps                        Pre-encoded RLPs to compute the next block hash\n     *                                           of the source output root proof.\n     * @custom:field l2ToL1MessagePasserBalance  Balance of the L2ToL1MessagePasser account.\n     * @custom:field l2ToL1MessagePasserCodeHash Codehash of the L2ToL1MessagePasser account.\n     * @custom:field merkleProof                 Merkle proof of L2ToL1MessagePasser account against the state root.\n     */\n    struct PublicInputProof {\n        OutputRootProof srcOutputRootProof;\n        OutputRootProof dstOutputRootProof;\n        PublicInput publicInput;\n        BlockHeaderRLP rlps;\n        bytes32 l2ToL1MessagePasserBalance;\n        bytes32 l2ToL1MessagePasserCodeHash;\n        bytes[] merkleProof;\n    }\n}\n"
      },
      "contracts/universal/ISemver.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ISemver\n/// @notice ISemver is a simple contract for ensuring that contracts are\n///         versioned using semantic versioning.\ninterface ISemver {\n    /// @notice Getter for the semantic version of the contract. This is not\n    ///         meant to be used onchain but instead meant to be used by offchain\n    ///         tooling.\n    /// @return Semver contract version as a string.\n    function version() external view returns (string memory);\n}\n"
      },
      "contracts/L1/IZKMerkleTrie.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IZKMerkleTrie\n */\ninterface IZKMerkleTrie {\n    /**\n     * @notice Verifies a proof that a given key/value pair is present in the trie.\n     *\n     * @param _key    Key of the node to search for, as a hex string.\n     * @param _value  Value of the node to search for, as a hex string.\n     * @param _proofs Merkle trie inclusion proof for the desired node.\n     * @param _root   Known root of the Merkle trie. Used to verify that the included proof is\n     *                correctly constructed.\n     *\n     * @return Whether or not the proof is valid.\n     */\n    function verifyInclusionProof(\n        bytes32 _key,\n        bytes memory _value,\n        bytes[] memory _proofs,\n        bytes32 _root\n    ) external view returns (bool);\n}\n"
      },
      "contracts/L1/L2OutputOracle.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\n\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ISemver } from \"../universal/ISemver.sol\";\nimport { ValidatorPool } from \"./ValidatorPool.sol\";\n\n/**\n * @custom:proxied\n * @title L2OutputOracle\n * @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a\n *         commitment to the state of the L2 chain. Other contracts like the KromaPortal use\n *         these outputs to verify information about the state of L2.\n */\ncontract L2OutputOracle is Initializable, ISemver {\n    /**\n     * @notice The address of the validator pool contract. Can be updated via upgrade.\n     */\n    ValidatorPool public immutable VALIDATOR_POOL;\n\n    /**\n     * @notice The address of the colosseum contract. Can be updated via upgrade.\n     */\n    address public immutable COLOSSEUM;\n\n    /**\n     * @notice The interval in L2 blocks at which checkpoints must be submitted. Although this is\n     *         immutable, it can be modified by upgrading the implementation contract.\n     *         Note that nodes that fetch and use this value need to restart when it is modified.\n     */\n    uint256 public immutable SUBMISSION_INTERVAL;\n\n    /**\n     * @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified.\n     */\n    uint256 public immutable L2_BLOCK_TIME;\n\n    /**\n     * @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.\n     */\n    uint256 public immutable FINALIZATION_PERIOD_SECONDS;\n\n    /**\n     * @notice The number of the first L2 block recorded in this contract.\n     */\n    uint256 public startingBlockNumber;\n\n    /**\n     * @notice The timestamp of the first L2 block recorded in this contract.\n     */\n    uint256 public startingTimestamp;\n\n    /**\n     * @notice Array of L2 checkpoint outputs.\n     */\n    Types.CheckpointOutput[] internal l2Outputs;\n\n    /**\n     * @notice Emitted when an output is submitted.\n     *\n     * @param outputRoot    The output root.\n     * @param l2OutputIndex The index of the output in the l2Outputs array.\n     * @param l2BlockNumber The L2 block number of the output root.\n     * @param l1Timestamp   The L1 timestamp when submitted.\n     */\n    event OutputSubmitted(\n        bytes32 indexed outputRoot,\n        uint256 indexed l2OutputIndex,\n        uint256 indexed l2BlockNumber,\n        uint256 l1Timestamp\n    );\n\n    /**\n     * @notice Emitted when an output is replaced.\n     *\n     * @param outputIndex   Replaced L2 output index.\n     * @param newOutputRoot L2 output root after replacement.\n     */\n    event OutputReplaced(uint256 indexed outputIndex, bytes32 newOutputRoot);\n\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.0.0\n     */\n    string public constant version = \"1.0.0\";\n\n    /**\n     * @notice Constructs the L2OutputOracle contract.\n     *\n     * @param _validatorPool             The address of the ValidatorPool contract.\n     * @param _colosseum                 The address of the Colosseum contract.\n     * @param _submissionInterval        Interval in blocks at which checkpoints must be submitted.\n     * @param _l2BlockTime               The time per L2 block, in seconds.\n     * @param _startingBlockNumber       The number of the first L2 block.\n     * @param _startingTimestamp         The timestamp of the first L2 block.\n     * @param _finalizationPeriodSeconds Output finalization time in seconds.\n     */\n    constructor(\n        ValidatorPool _validatorPool,\n        address _colosseum,\n        uint256 _submissionInterval,\n        uint256 _l2BlockTime,\n        uint256 _startingBlockNumber,\n        uint256 _startingTimestamp,\n        uint256 _finalizationPeriodSeconds\n    ) {\n        require(_l2BlockTime > 0, \"L2OutputOracle: L2 block time must be greater than 0\");\n        require(\n            _submissionInterval > 0,\n            \"L2OutputOracle: submission interval must be greater than 0\"\n        );\n\n        VALIDATOR_POOL = _validatorPool;\n        COLOSSEUM = _colosseum;\n        SUBMISSION_INTERVAL = _submissionInterval;\n        L2_BLOCK_TIME = _l2BlockTime;\n        FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;\n\n        initialize(_startingBlockNumber, _startingTimestamp);\n    }\n\n    /**\n     * @notice Initializer.\n     *\n     * @param _startingBlockNumber Block number for the first recorded L2 block.\n     * @param _startingTimestamp   Timestamp for the first recorded L2 block.\n     */\n    function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp)\n        public\n        initializer\n    {\n        require(\n            _startingTimestamp <= block.timestamp,\n            \"L2OutputOracle: starting L2 timestamp must be less than current time\"\n        );\n\n        startingTimestamp = _startingTimestamp;\n        startingBlockNumber = _startingBlockNumber;\n    }\n\n    /**\n     * @notice Replaces the output that corresponds to the given output index.\n     *         Only the Colosseum contract can replace an output.\n     *\n     * @param _l2OutputIndex Index of the L2 output to be replaced.\n     * @param _newOutputRoot The L2 output root to replace the existing one.\n     * @param _submitter     Address of the L2 output submitter.\n     */\n    function replaceL2Output(\n        uint256 _l2OutputIndex,\n        bytes32 _newOutputRoot,\n        address _submitter\n    ) external {\n        require(\n            msg.sender == COLOSSEUM,\n            \"L2OutputOracle: only the colosseum contract can replace an output\"\n        );\n\n        require(_submitter != address(0), \"L2OutputOracle: submitter address cannot be zero\");\n\n        // Make sure we're not *increasing* the length of the array.\n        require(\n            _l2OutputIndex < l2Outputs.length,\n            \"L2OutputOracle: cannot replace an output after the latest output index\"\n        );\n\n        Types.CheckpointOutput storage output = l2Outputs[_l2OutputIndex];\n        // Do not allow replacing any outputs that have already been finalized.\n        require(\n            block.timestamp - output.timestamp < FINALIZATION_PERIOD_SECONDS,\n            \"L2OutputOracle: cannot replace an output that has already been finalized\"\n        );\n\n        output.outputRoot = _newOutputRoot;\n        output.submitter = _submitter;\n\n        emit OutputReplaced(_l2OutputIndex, _newOutputRoot);\n    }\n\n    /**\n     * @notice Accepts an outputRoot and the block number of the corresponding L2 block.\n     *         The block number must be equal to the current value returned by `nextBlockNumber()`\n     *         in order to be accepted. This function may only be called by the validator.\n     *\n     * @param _outputRoot    The L2 output of the checkpoint block.\n     * @param _l2BlockNumber The L2 block number that resulted in _outputRoot.\n     * @param _l1BlockHash   A block hash which must be included in the current chain.\n     * @param _l1BlockNumber The block number with the specified block hash.\n     */\n    function submitL2Output(\n        bytes32 _outputRoot,\n        uint256 _l2BlockNumber,\n        bytes32 _l1BlockHash,\n        uint256 _l1BlockNumber\n    ) external payable {\n        address nextValidator = VALIDATOR_POOL.nextValidator();\n        // If it's not a public round, only selected validators can submit output.\n        if (nextValidator != Constants.VALIDATOR_PUBLIC_ROUND_ADDRESS) {\n            require(\n                msg.sender == nextValidator,\n                \"L2OutputOracle: only the next selected validator can submit output\"\n            );\n        }\n\n        require(\n            _l2BlockNumber == nextBlockNumber(),\n            \"L2OutputOracle: block number must be equal to next expected block number\"\n        );\n\n        require(\n            computeL2Timestamp(_l2BlockNumber) < block.timestamp,\n            \"L2OutputOracle: cannot submit L2 output in the future\"\n        );\n\n        require(\n            _outputRoot != bytes32(0),\n            \"L2OutputOracle: L2 checkpoint output cannot be the zero hash\"\n        );\n\n        if (_l1BlockHash != bytes32(0) && blockhash(_l1BlockNumber) != bytes32(0)) {\n            // This check allows the validator to submit an output based on a given L1 block,\n            // without fear that it will be reorged out.\n            // It will be skipped if the blockheight provided is more than 256 blocks behind the\n            // chain tip (as the hash will return as zero).\n            require(\n                blockhash(_l1BlockNumber) == _l1BlockHash,\n                \"L2OutputOracle: block hash does not match the hash at the expected height\"\n            );\n        }\n\n        uint256 outputIndex = nextOutputIndex();\n\n        l2Outputs.push(\n            Types.CheckpointOutput({\n                submitter: msg.sender,\n                outputRoot: _outputRoot,\n                timestamp: uint128(block.timestamp),\n                l2BlockNumber: uint128(_l2BlockNumber)\n            })\n        );\n\n        emit OutputSubmitted(_outputRoot, outputIndex, _l2BlockNumber, block.timestamp);\n\n        VALIDATOR_POOL.createBond(\n            outputIndex,\n            uint128(block.timestamp + FINALIZATION_PERIOD_SECONDS)\n        );\n    }\n\n    /**\n     * @notice Returns an output by index. Reverts if output is not found at the given index.\n     *\n     * @param _l2OutputIndex Index of the output to return.\n     *\n     * @return The output at the given index.\n     */\n    function getL2Output(uint256 _l2OutputIndex)\n        external\n        view\n        returns (Types.CheckpointOutput memory)\n    {\n        return l2Outputs[_l2OutputIndex];\n    }\n\n    /**\n     * @notice Returns the index of the L2 output that checkpoints a given L2 block number. Uses a\n     *         binary search to find the first output greater than or equal to the given block.\n     *\n     * @param _l2BlockNumber L2 block number to find a checkpoint for.\n     *\n     * @return Index of the first checkpoint that commits to the given L2 block number.\n     */\n    function getL2OutputIndexAfter(uint256 _l2BlockNumber) public view returns (uint256) {\n        // Make sure an output for this block number has actually been submitted.\n        require(\n            _l2BlockNumber <= latestBlockNumber(),\n            \"L2OutputOracle: cannot get output for a block that has not been submitted\"\n        );\n\n        // Make sure there's at least one output submitted.\n        require(\n            l2Outputs.length > 0,\n            \"L2OutputOracle: cannot get output as no outputs have been submitted yet\"\n        );\n\n        // Find the output via binary search, guaranteed to exist.\n        uint256 lo = 0;\n        uint256 hi = l2Outputs.length;\n        while (lo < hi) {\n            uint256 mid = (lo + hi) / 2;\n            if (l2Outputs[mid].l2BlockNumber < _l2BlockNumber) {\n                lo = mid + 1;\n            } else {\n                hi = mid;\n            }\n        }\n\n        return lo;\n    }\n\n    /**\n     * @notice Returns the L2 checkpoint output that checkpoints a given L2 block number.\n     *\n     * @param _l2BlockNumber L2 block number to find a checkpoint for.\n     *\n     * @return First checkpoint that commits to the given L2 block number.\n     */\n    function getL2OutputAfter(uint256 _l2BlockNumber)\n        external\n        view\n        returns (Types.CheckpointOutput memory)\n    {\n        return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];\n    }\n\n    /**\n     * @notice Returns the index of the latest submitted output. Will revert if no outputs\n     *         have been submitted yet.\n     *\n     * @return The index of the latest submitted output.\n     */\n    function latestOutputIndex() external view returns (uint256) {\n        return l2Outputs.length - 1;\n    }\n\n    /**\n     * @notice Returns the index of the next output to be submitted.\n     *\n     * @return The index of the next output to be submitted.\n     */\n    function nextOutputIndex() public view returns (uint256) {\n        return l2Outputs.length;\n    }\n\n    /**\n     * @notice Returns the block number of the latest submitted L2 checkpoint output. If no outputs\n     *         have been submitted yet then this function will return the starting block number.\n     *\n     * @return Latest submitted L2 block number.\n     */\n    function latestBlockNumber() public view returns (uint256) {\n        return\n            l2Outputs.length == 0\n                ? startingBlockNumber\n                : l2Outputs[l2Outputs.length - 1].l2BlockNumber;\n    }\n\n    /**\n     * @notice Computes the block number of the next L2 block that needs to be checkpointed. If no\n     *         outputs have been submitted yet then this function will return the latest block\n     *         number, which is the starting block number.\n     *\n     * @return Next L2 block number.\n     */\n    function nextBlockNumber() public view returns (uint256) {\n        return\n            l2Outputs.length == 0 ? latestBlockNumber() : latestBlockNumber() + SUBMISSION_INTERVAL;\n    }\n\n    /**\n     * @notice Returns the L2 timestamp corresponding to a given L2 block number.\n     *\n     * @param _l2BlockNumber The L2 block number of the target block.\n     *\n     * @return L2 timestamp of the given block.\n     */\n    function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {\n        return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME);\n    }\n\n    /**\n     * @notice Returns the address of the L2 output submitter.\n     *\n     * @param _outputIndex Index of an output.\n     *\n     * @return Address of the submitter.\n     */\n    function getSubmitter(uint256 _outputIndex) external view returns (address) {\n        return l2Outputs[_outputIndex].submitter;\n    }\n\n    /**\n     * @notice Returns if the output of given index is finalized.\n     *\n     * @param _outputIndex Index of an output.\n     *\n     * @return If the given output is finalized or not.\n     */\n    function isFinalized(uint256 _outputIndex) external view returns (bool) {\n        return l2Outputs[_outputIndex].timestamp + FINALIZATION_PERIOD_SECONDS < block.timestamp;\n    }\n\n    /**\n     * @notice Returns the finalization time of given output index.\n     *\n     * @param _outputIndex Index of an output.\n     *\n     * @return The finalization time of given output index.\n     */\n    function finalizedAt(uint256 _outputIndex) external view returns (uint256) {\n        return l2Outputs[_outputIndex].timestamp + FINALIZATION_PERIOD_SECONDS;\n    }\n}\n"
      },
      "contracts/L1/SecurityCouncil.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { TokenMultiSigWallet } from \"../universal/TokenMultiSigWallet.sol\";\nimport { ISemver } from \"../universal/ISemver.sol\";\nimport { Colosseum } from \"./Colosseum.sol\";\n\n/**\n * @custom:proxied\n * @title SecurityCouncil\n * @notice SecurityCouncil receives validation requests for specific output data,\n *         and allows security council parties to validate & agree on transactions before execution.\n */\ncontract SecurityCouncil is TokenMultiSigWallet, ISemver {\n    /**\n     * @notice The address of the colosseum contract. Can be updated via upgrade.\n     */\n    address public immutable COLOSSEUM;\n\n    /**\n     * @notice A mapping of outputs requested to be deleted.\n     */\n    mapping(uint256 => bool) public outputsDeleteRequested;\n\n    /**\n     * @notice Emitted when a validation request is submitted.\n     *\n     * @param transactionId Index of the submitted transaction.\n     * @param outputRoot    The L2 output of the checkpoint block to be validated.\n     * @param l2BlockNumber The L2 block number to be validated.\n     */\n    event ValidationRequested(\n        uint256 indexed transactionId,\n        bytes32 outputRoot,\n        uint256 l2BlockNumber\n    );\n\n    /**\n     * @notice Emitted when an output is requested to be deleted.\n     *\n     * @param transactionId Index of the requested transaction.\n     * @param outputIndex   Index of output to be deleted.\n     */\n    event DeletionRequested(uint256 indexed transactionId, uint256 indexed outputIndex);\n\n    /**\n     * @notice Disallow calls from anyone except Colosseum.\n     */\n    modifier onlyColosseum() {\n        require(\n            msg.sender == COLOSSEUM,\n            \"SecurityCouncil: only the colosseum contract can be a sender\"\n        );\n        _;\n    }\n\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.1.0\n     */\n    string public constant version = \"1.1.0\";\n\n    /**\n     * @notice Constructs the SecurityCouncil contract.\n     *\n     * @param _colosseum Address of the Colosseum contract.\n     * @param _governor  Address of Governor contract.\n     */\n    constructor(address _colosseum, address payable _governor) TokenMultiSigWallet(_governor) {\n        COLOSSEUM = _colosseum;\n    }\n\n    /**\n     * @notice Allows the Colosseum to request for validate output data.\n     *\n     * @param _outputRoot    The L2 output of the checkpoint block to be validated.\n     * @param _l2BlockNumber The L2 block number to be validated.\n     * @param _data          Calldata for callback purpose.\n     */\n    function requestValidation(\n        bytes32 _outputRoot,\n        uint256 _l2BlockNumber,\n        bytes memory _data\n    ) public onlyColosseum {\n        uint256 transactionId = _submitTransaction(msg.sender, 0, _data);\n        emit ValidationRequested(transactionId, _outputRoot, _l2BlockNumber);\n    }\n\n    /**\n     * @notice Requests to delete an output to Colosseum forcefully.\n     *         This should only be called by one of the Security Council when undeniable bugs occur.\n     *\n     * @param _outputIndex Index of output to be deleted.\n     * @param _force       Option to forcibly make a request to delete the output.\n     */\n    function requestDeletion(uint256 _outputIndex, bool _force) public onlyTokenOwner(msg.sender) {\n        require(\n            !outputsDeleteRequested[_outputIndex] || _force,\n            \"SecurityCouncil: the output has already been requested to be deleted\"\n        );\n        bytes memory message = abi.encodeWithSelector(\n            Colosseum.forceDeleteOutput.selector,\n            _outputIndex\n        );\n        uint256 transactionId = submitTransaction(address(COLOSSEUM), 0, message);\n        // auto-confirmed by requester\n        confirmTransaction(transactionId);\n        outputsDeleteRequested[_outputIndex] = true;\n        emit DeletionRequested(transactionId, _outputIndex);\n    }\n}\n"
      },
      "contracts/L1/ZKVerifier.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.15;\n\nimport { ISemver } from \"../universal/ISemver.sol\";\n\ncontract ZKVerifier is ISemver {\n    uint256 internal immutable HASH_SCALAR_VALUE;\n    uint256 internal immutable M_56_PX_VALUE;\n    uint256 internal immutable M_56_PY_VALUE;\n\n    /**\n     * @notice Semantic version.\n     * @custom:semver 0.1.4\n     */\n    string public constant version = \"0.1.4\";\n\n    constructor(uint256 _hashScalar, uint256 _m56Px, uint256 _m56Py) {\n        HASH_SCALAR_VALUE = _hashScalar;\n        M_56_PX_VALUE = _m56Px;\n        M_56_PY_VALUE = _m56Py;\n    }\n\n    function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {\n        uint256 length = p1.length * 6;\n        uint256[] memory input = new uint256[](length);\n        uint256[1] memory result;\n        bool ret;\n\n        require(p1.length == p2.length);\n\n        for (uint256 i = 0; i < p1.length; i++) {\n            input[0 + i * 6] = p1[i].x;\n            input[1 + i * 6] = p1[i].y;\n            input[2 + i * 6] = p2[i].x[0];\n            input[3 + i * 6] = p2[i].x[1];\n            input[4 + i * 6] = p2[i].y[0];\n            input[5 + i * 6] = p2[i].y[1];\n        }\n\n        assembly {\n            ret := staticcall(gas(), 8, add(input, 0x20), mul(length, 0x20), result, 0x20)\n        }\n        require(ret);\n        return result[0] != 0;\n    }\n\n    uint256 constant q_mod =\n        21888242871839275222246405745257275088548364400416034343698204186575808495617;\n\n    function fr_invert(uint256 a) internal view returns (uint256) {\n        return fr_pow(a, q_mod - 2);\n    }\n\n    function fr_pow(uint256 a, uint256 power) internal view returns (uint256) {\n        uint256[6] memory input;\n        uint256[1] memory result;\n        bool ret;\n\n        input[0] = 32;\n        input[1] = 32;\n        input[2] = 32;\n        input[3] = a;\n        input[4] = power;\n        input[5] = q_mod;\n\n        assembly {\n            ret := staticcall(gas(), 0x05, input, 0xc0, result, 0x20)\n        }\n        require(ret);\n\n        return result[0];\n    }\n\n    function fr_div(uint256 a, uint256 b) internal view returns (uint256) {\n        require(b != 0);\n        return mulmod(a, fr_invert(b), q_mod);\n    }\n\n    function fr_mul_add(\n        uint256 a,\n        uint256 b,\n        uint256 c\n    ) internal pure returns (uint256) {\n        return addmod(mulmod(a, b, q_mod), c, q_mod);\n    }\n\n    function fr_mul_add_pm(\n        uint256[84] memory m,\n        uint256[] calldata proof,\n        uint256 opcode,\n        uint256 t\n    ) internal pure returns (uint256) {\n        for (uint256 i = 0; i < 32; i += 2) {\n            uint256 a = opcode & 0xff;\n            if (a != 0xff) {\n                opcode >>= 8;\n                uint256 b = opcode & 0xff;\n                opcode >>= 8;\n                t = addmod(mulmod(proof[a], m[b], q_mod), t, q_mod);\n            } else {\n                break;\n            }\n        }\n\n        return t;\n    }\n\n    function fr_mul_add_mt(\n        uint256[84] memory m,\n        uint256 base,\n        uint256 opcode,\n        uint256 t\n    ) internal pure returns (uint256) {\n        for (uint256 i = 0; i < 32; i += 1) {\n            uint256 a = opcode & 0xff;\n            if (a != 0xff) {\n                opcode >>= 8;\n                t = addmod(mulmod(base, t, q_mod), m[a], q_mod);\n            } else {\n                break;\n            }\n        }\n\n        return t;\n    }\n\n    function fr_reverse(uint256 input) internal pure returns (uint256 v) {\n        v = input;\n\n        // swap bytes\n        v =\n            ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) |\n            ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);\n\n        // swap 2-byte long pairs\n        v =\n            ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) |\n            ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);\n\n        // swap 4-byte long pairs\n        v =\n            ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) |\n            ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);\n\n        // swap 8-byte long pairs\n        v =\n            ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) |\n            ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);\n\n        // swap 16-byte long pairs\n        v = (v >> 128) | (v << 128);\n    }\n\n    uint256 constant p_mod =\n        21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n    struct G1Point {\n        uint256 x;\n        uint256 y;\n    }\n\n    struct G2Point {\n        uint256[2] x;\n        uint256[2] y;\n    }\n\n    function ecc_from(uint256 x, uint256 y) internal pure returns (G1Point memory r) {\n        r.x = x;\n        r.y = y;\n    }\n\n    function ecc_add(\n        uint256 ax,\n        uint256 ay,\n        uint256 bx,\n        uint256 by\n    ) internal view returns (uint256, uint256) {\n        bool ret = false;\n        G1Point memory r;\n        uint256[4] memory input_points;\n\n        input_points[0] = ax;\n        input_points[1] = ay;\n        input_points[2] = bx;\n        input_points[3] = by;\n\n        assembly {\n            ret := staticcall(gas(), 6, input_points, 0x80, r, 0x40)\n        }\n        require(ret);\n\n        return (r.x, r.y);\n    }\n\n    function ecc_sub(\n        uint256 ax,\n        uint256 ay,\n        uint256 bx,\n        uint256 by\n    ) internal view returns (uint256, uint256) {\n        return ecc_add(ax, ay, bx, p_mod - by);\n    }\n\n    function ecc_mul(\n        uint256 px,\n        uint256 py,\n        uint256 s\n    ) internal view returns (uint256, uint256) {\n        uint256[3] memory input;\n        bool ret = false;\n        G1Point memory r;\n\n        input[0] = px;\n        input[1] = py;\n        input[2] = s;\n\n        assembly {\n            ret := staticcall(gas(), 7, input, 0x60, r, 0x40)\n        }\n        require(ret);\n\n        return (r.x, r.y);\n    }\n\n    function _ecc_mul_add(uint256[5] memory input) internal view {\n        bool ret = false;\n\n        assembly {\n            ret := staticcall(gas(), 7, input, 0x60, add(input, 0x20), 0x40)\n        }\n        require(ret);\n\n        assembly {\n            ret := staticcall(gas(), 6, add(input, 0x20), 0x80, add(input, 0x60), 0x40)\n        }\n        require(ret);\n    }\n\n    function ecc_mul_add(\n        uint256 px,\n        uint256 py,\n        uint256 s,\n        uint256 qx,\n        uint256 qy\n    ) internal view returns (uint256, uint256) {\n        uint256[5] memory input;\n        input[0] = px;\n        input[1] = py;\n        input[2] = s;\n        input[3] = qx;\n        input[4] = qy;\n\n        _ecc_mul_add(input);\n\n        return (input[3], input[4]);\n    }\n\n    function ecc_mul_add_pm(\n        uint256[84] memory m,\n        uint256[] calldata proof,\n        uint256 opcode,\n        uint256 t0,\n        uint256 t1\n    ) internal view returns (uint256, uint256) {\n        uint256[5] memory input;\n        input[3] = t0;\n        input[4] = t1;\n        for (uint256 i = 0; i < 32; i += 2) {\n            uint256 a = opcode & 0xff;\n            if (a != 0xff) {\n                opcode >>= 8;\n                uint256 b = opcode & 0xff;\n                opcode >>= 8;\n                input[0] = proof[a];\n                input[1] = proof[a + 1];\n                input[2] = m[b];\n                _ecc_mul_add(input);\n            } else {\n                break;\n            }\n        }\n\n        return (input[3], input[4]);\n    }\n\n    function update_hash_scalar(\n        uint256 v,\n        uint256[144] memory absorbing,\n        uint256 pos\n    ) internal pure {\n        absorbing[pos++] = 0x02;\n        absorbing[pos++] = v;\n    }\n\n    function update_hash_point(\n        uint256 x,\n        uint256 y,\n        uint256[144] memory absorbing,\n        uint256 pos\n    ) internal pure {\n        absorbing[pos++] = 0x01;\n        absorbing[pos++] = x;\n        absorbing[pos++] = y;\n    }\n\n    function to_scalar(bytes32 r) private pure returns (uint256 v) {\n        uint256 tmp = uint256(r);\n        tmp = fr_reverse(tmp);\n        v = tmp % 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001;\n    }\n\n    function hash(uint256[144] memory absorbing, uint256 length)\n        private\n        view\n        returns (bytes32[1] memory v)\n    {\n        bool success;\n        assembly {\n            success := staticcall(sub(gas(), 2000), 2, absorbing, length, v, 32)\n            switch success\n            case 0 {\n                invalid()\n            }\n        }\n        assert(success);\n    }\n\n    function squeeze_challenge(uint256[144] memory absorbing, uint32 length)\n        internal\n        view\n        returns (uint256 v)\n    {\n        absorbing[length] = 0;\n        bytes32 res = hash(absorbing, length * 32 + 1)[0];\n        v = to_scalar(res);\n        absorbing[0] = uint256(res);\n        length = 1;\n    }\n\n    function get_verify_circuit_g2_s() internal pure returns (G2Point memory s) {\n        s.x[0] = uint256(\n            11029560635643983818885738975758839003131865733814273016801144285524936684972\n        );\n        s.x[1] = uint256(\n            10665153487364924395451186075663597035495902496253353881119509267933768999122\n        );\n        s.y[0] = uint256(\n            18790173187318184075281544452912101572166071561689308149111466352378718492148\n        );\n        s.y[1] = uint256(\n            18755874088236213082062601512863221433227017725453112019151604716957419045549\n        );\n    }\n\n    function get_verify_circuit_g2_n() internal pure returns (G2Point memory n) {\n        n.x[0] = uint256(\n            11559732032986387107991004021392285783925812861821192530917403151452391805634\n        );\n        n.x[1] = uint256(\n            10857046999023057135944570762232829481370756359578518086990519993285655852781\n        );\n        n.y[0] = uint256(\n            17805874995975841540914202342111839520379459829704422454583296818431106115052\n        );\n        n.y[1] = uint256(\n            13392588948715843804641432497768002650278120570034223513918757245338268106653\n        );\n    }\n\n    function get_target_circuit_g2_s() internal pure returns (G2Point memory s) {\n        s.x[0] = uint256(\n            11029560635643983818885738975758839003131865733814273016801144285524936684972\n        );\n        s.x[1] = uint256(\n            10665153487364924395451186075663597035495902496253353881119509267933768999122\n        );\n        s.y[0] = uint256(\n            18790173187318184075281544452912101572166071561689308149111466352378718492148\n        );\n        s.y[1] = uint256(\n            18755874088236213082062601512863221433227017725453112019151604716957419045549\n        );\n    }\n\n    function get_target_circuit_g2_n() internal pure returns (G2Point memory n) {\n        n.x[0] = uint256(\n            11559732032986387107991004021392285783925812861821192530917403151452391805634\n        );\n        n.x[1] = uint256(\n            10857046999023057135944570762232829481370756359578518086990519993285655852781\n        );\n        n.y[0] = uint256(\n            17805874995975841540914202342111839520379459829704422454583296818431106115052\n        );\n        n.y[1] = uint256(\n            13392588948715843804641432497768002650278120570034223513918757245338268106653\n        );\n    }\n\n    function get_wx_wg(uint256[] calldata proof, uint256[6] memory instances)\n        internal\n        view\n        returns (\n            uint256,\n            uint256,\n            uint256,\n            uint256\n        )\n    {\n        uint256[84] memory m;\n        uint256[144] memory absorbing;\n        uint256 t0 = 0;\n        uint256 t1 = 0;\n\n        (t0, t1) = (\n            ecc_mul(\n                17789833092049612098151701936050358897264906311798010005527050942756852717298,\n                10895600437035740537762783734736154159991587515994553016519128117735745182853,\n                instances[0]\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                10543918255196573445400399528935519333175023389167175628125725368018220699826,\n                12766487347162664556283708113947771881161039794532633041152166890738441603652,\n                instances[1],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                17008203783108743202559440655757700533653854901598142405028623347702668473277,\n                21814804208982435371780097106882418706885400711730256673026973858149650971299,\n                instances[2],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                16811698451652309858363601322080891018704447409836823044944128338389236089077,\n                18899539994854832158038246139972325143494193687503547200838261777721006548399,\n                instances[3],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                5494852631096636459288403096263717084869030781267238852252122493224146048270,\n                15370627062079108379015892130008397963684601860044622201721093508656326957966,\n                instances[4],\n                t0,\n                t1\n            )\n        );\n        (m[0], m[1]) = (\n            ecc_mul_add(\n                15605904389647533645433956766425544672547314322654580577432084020959766066522,\n                2981854610112145395053419471185791838523574193883358734299031423326998004318,\n                instances[5],\n                t0,\n                t1\n            )\n        );\n        update_hash_scalar(HASH_SCALAR_VALUE, absorbing, 0);\n        update_hash_point(m[0], m[1], absorbing, 2);\n        for (t0 = 0; t0 <= 4; t0++) {\n            update_hash_point(proof[0 + t0 * 2], proof[1 + t0 * 2], absorbing, 5 + t0 * 3);\n        }\n        m[2] = (squeeze_challenge(absorbing, 20));\n        for (t0 = 0; t0 <= 13; t0++) {\n            update_hash_point(proof[10 + t0 * 2], proof[11 + t0 * 2], absorbing, 1 + t0 * 3);\n        }\n        m[3] = (squeeze_challenge(absorbing, 43));\n        m[4] = (squeeze_challenge(absorbing, 1));\n        for (t0 = 0; t0 <= 9; t0++) {\n            update_hash_point(proof[38 + t0 * 2], proof[39 + t0 * 2], absorbing, 1 + t0 * 3);\n        }\n        m[5] = (squeeze_challenge(absorbing, 31));\n        for (t0 = 0; t0 <= 3; t0++) {\n            update_hash_point(proof[58 + t0 * 2], proof[59 + t0 * 2], absorbing, 1 + t0 * 3);\n        }\n        m[6] = (squeeze_challenge(absorbing, 13));\n        for (t0 = 0; t0 <= 70; t0++) {\n            update_hash_scalar(proof[66 + t0 * 1], absorbing, 1 + t0 * 2);\n        }\n        m[7] = (squeeze_challenge(absorbing, 143));\n        for (t0 = 0; t0 <= 3; t0++) {\n            update_hash_point(proof[137 + t0 * 2], proof[138 + t0 * 2], absorbing, 1 + t0 * 3);\n        }\n        m[8] = (squeeze_challenge(absorbing, 13));\n        m[9] = (\n            mulmod(\n                m[6],\n                13446667982376394161563610564587413125564757801019538732601045199901075958935,\n                q_mod\n            )\n        );\n        m[10] = (\n            mulmod(\n                m[6],\n                16569469942529664681363945218228869388192121720036659574609237682362097667612,\n                q_mod\n            )\n        );\n        m[11] = (\n            mulmod(\n                m[6],\n                14803907026430593724305438564799066516271154714737734572920456128449769927233,\n                q_mod\n            )\n        );\n        m[12] = (fr_pow(m[6], 67108864));\n        m[13] = (addmod(m[12], q_mod - 1, q_mod));\n        m[14] = (\n            mulmod(\n                21888242545679039938882419398440172875981108180010270949818755658014750055173,\n                m[13],\n                q_mod\n            )\n        );\n        t0 = (addmod(m[6], q_mod - 1, q_mod));\n        m[14] = (fr_div(m[14], t0));\n        m[15] = (\n            mulmod(\n                3495999257316610708652455694658595065970881061159015347599790211259094641512,\n                m[13],\n                q_mod\n            )\n        );\n        t0 = (\n            addmod(\n                m[6],\n                q_mod -\n                    14803907026430593724305438564799066516271154714737734572920456128449769927233,\n                q_mod\n            )\n        );\n        m[15] = (fr_div(m[15], t0));\n        m[16] = (\n            mulmod(\n                12851378806584061886934576302961450669946047974813165594039554733293326536714,\n                m[13],\n                q_mod\n            )\n        );\n        t0 = (\n            addmod(\n                m[6],\n                q_mod -\n                    11377606117859914088982205826922132024839443553408109299929510653283289974216,\n                q_mod\n            )\n        );\n        m[16] = (fr_div(m[16], t0));\n        m[17] = (\n            mulmod(\n                14638077285440018490948843142723135319134576188472316769433007423695824509066,\n                m[13],\n                q_mod\n            )\n        );\n        t0 = (\n            addmod(\n                m[6],\n                q_mod -\n                    3693565015985198455139889557180396682968596245011005461846595820698933079918,\n                q_mod\n            )\n        );\n        m[17] = (fr_div(m[17], t0));\n        m[18] = (\n            mulmod(\n                18027939092386982308810165776478549635922357517986691900813373197616541191289,\n                m[13],\n                q_mod\n            )\n        );\n        t0 = (\n            addmod(\n                m[6],\n                q_mod -\n                    17329448237240114492580865744088056414251735686965494637158808787419781175510,\n                q_mod\n            )\n        );\n        m[18] = (fr_div(m[18], t0));\n        m[19] = (\n            mulmod(\n                912591536032578604421866340844550116335029274442283291811906603256731601654,\n                m[13],\n                q_mod\n            )\n        );\n        t0 = (\n            addmod(\n                m[6],\n                q_mod -\n                    6047398202650739717314770882059679662647667807426525133977681644606291529311,\n                q_mod\n            )\n        );\n        m[19] = (fr_div(m[19], t0));\n        m[20] = (\n            mulmod(\n                17248638560015646562374089181598815896736916575459528793494921668169819478628,\n                m[13],\n                q_mod\n            )\n        );\n        t0 = (\n            addmod(\n                m[6],\n                q_mod -\n                    16569469942529664681363945218228869388192121720036659574609237682362097667612,\n                q_mod\n            )\n        );\n        m[20] = (fr_div(m[20], t0));\n        t0 = (addmod(m[15], m[16], q_mod));\n        t0 = (addmod(t0, m[17], q_mod));\n        t0 = (addmod(t0, m[18], q_mod));\n        m[15] = (addmod(t0, m[19], q_mod));\n        t0 = (fr_mul_add(proof[74], proof[72], proof[73]));\n        t0 = (fr_mul_add(proof[75], proof[67], t0));\n        t0 = (fr_mul_add(proof[76], proof[68], t0));\n        t0 = (fr_mul_add(proof[77], proof[69], t0));\n        t0 = (fr_mul_add(proof[78], proof[70], t0));\n        m[16] = (fr_mul_add(proof[79], proof[71], t0));\n        t0 = (mulmod(proof[67], proof[68], q_mod));\n        m[16] = (fr_mul_add(proof[80], t0, m[16]));\n        t0 = (mulmod(proof[69], proof[70], q_mod));\n        m[16] = (fr_mul_add(proof[81], t0, m[16]));\n        t0 = (addmod(1, q_mod - proof[97], q_mod));\n        m[17] = (mulmod(m[14], t0, q_mod));\n        t0 = (mulmod(proof[100], proof[100], q_mod));\n        t0 = (addmod(t0, q_mod - proof[100], q_mod));\n        m[18] = (mulmod(m[20], t0, q_mod));\n        t0 = (addmod(proof[100], q_mod - proof[99], q_mod));\n        m[19] = (mulmod(t0, m[14], q_mod));\n        m[21] = (mulmod(m[3], m[6], q_mod));\n        t0 = (addmod(m[20], m[15], q_mod));\n        m[15] = (addmod(1, q_mod - t0, q_mod));\n        m[22] = (addmod(proof[67], m[4], q_mod));\n        t0 = (fr_mul_add(proof[91], m[3], m[22]));\n        m[23] = (mulmod(t0, proof[98], q_mod));\n        t0 = (addmod(m[22], m[21], q_mod));\n        m[22] = (mulmod(t0, proof[97], q_mod));\n        m[24] = (\n            mulmod(\n                4131629893567559867359510883348571134090853742863529169391034518566172092834,\n                m[21],\n                q_mod\n            )\n        );\n        m[25] = (addmod(proof[68], m[4], q_mod));\n        t0 = (fr_mul_add(proof[92], m[3], m[25]));\n        m[23] = (mulmod(t0, m[23], q_mod));\n        t0 = (addmod(m[25], m[24], q_mod));\n        m[22] = (mulmod(t0, m[22], q_mod));\n        m[24] = (\n            mulmod(\n                4131629893567559867359510883348571134090853742863529169391034518566172092834,\n                m[24],\n                q_mod\n            )\n        );\n        m[25] = (addmod(proof[69], m[4], q_mod));\n        t0 = (fr_mul_add(proof[93], m[3], m[25]));\n        m[23] = (mulmod(t0, m[23], q_mod));\n        t0 = (addmod(m[25], m[24], q_mod));\n        m[22] = (mulmod(t0, m[22], q_mod));\n        m[24] = (\n            mulmod(\n                4131629893567559867359510883348571134090853742863529169391034518566172092834,\n                m[24],\n                q_mod\n            )\n        );\n        t0 = (addmod(m[23], q_mod - m[22], q_mod));\n        m[22] = (mulmod(t0, m[15], q_mod));\n        m[21] = (\n            mulmod(\n                m[21],\n                11166246659983828508719468090013646171463329086121580628794302409516816350802,\n                q_mod\n            )\n        );\n        m[23] = (addmod(proof[70], m[4], q_mod));\n        t0 = (fr_mul_add(proof[94], m[3], m[23]));\n        m[24] = (mulmod(t0, proof[101], q_mod));\n        t0 = (addmod(m[23], m[21], q_mod));\n        m[23] = (mulmod(t0, proof[100], q_mod));\n        m[21] = (\n            mulmod(\n                4131629893567559867359510883348571134090853742863529169391034518566172092834,\n                m[21],\n                q_mod\n            )\n        );\n        m[25] = (addmod(proof[71], m[4], q_mod));\n        t0 = (fr_mul_add(proof[95], m[3], m[25]));\n        m[24] = (mulmod(t0, m[24], q_mod));\n        t0 = (addmod(m[25], m[21], q_mod));\n        m[23] = (mulmod(t0, m[23], q_mod));\n        m[21] = (\n            mulmod(\n                4131629893567559867359510883348571134090853742863529169391034518566172092834,\n                m[21],\n                q_mod\n            )\n        );\n        m[25] = (addmod(proof[66], m[4], q_mod));\n        t0 = (fr_mul_add(proof[96], m[3], m[25]));\n        m[24] = (mulmod(t0, m[24], q_mod));\n        t0 = (addmod(m[25], m[21], q_mod));\n        m[23] = (mulmod(t0, m[23], q_mod));\n        m[21] = (\n            mulmod(\n                4131629893567559867359510883348571134090853742863529169391034518566172092834,\n                m[21],\n                q_mod\n            )\n        );\n        t0 = (addmod(m[24], q_mod - m[23], q_mod));\n        m[21] = (mulmod(t0, m[15], q_mod));\n        t0 = (addmod(proof[104], m[3], q_mod));\n        m[23] = (mulmod(proof[103], t0, q_mod));\n        t0 = (addmod(proof[106], m[4], q_mod));\n        m[23] = (mulmod(m[23], t0, q_mod));\n        m[24] = (mulmod(proof[67], proof[82], q_mod));\n        m[2] = (mulmod(0, m[2], q_mod));\n        m[24] = (addmod(m[2], m[24], q_mod));\n        m[25] = (addmod(m[2], proof[83], q_mod));\n        m[26] = (addmod(proof[104], q_mod - proof[106], q_mod));\n        t0 = (addmod(1, q_mod - proof[102], q_mod));\n        m[27] = (mulmod(m[14], t0, q_mod));\n        t0 = (mulmod(proof[102], proof[102], q_mod));\n        t0 = (addmod(t0, q_mod - proof[102], q_mod));\n        m[28] = (mulmod(m[20], t0, q_mod));\n        t0 = (addmod(m[24], m[3], q_mod));\n        m[24] = (mulmod(proof[102], t0, q_mod));\n        m[25] = (addmod(m[25], m[4], q_mod));\n        t0 = (mulmod(m[24], m[25], q_mod));\n        t0 = (addmod(m[23], q_mod - t0, q_mod));\n        m[23] = (mulmod(t0, m[15], q_mod));\n        m[24] = (mulmod(m[14], m[26], q_mod));\n        t0 = (addmod(proof[104], q_mod - proof[105], q_mod));\n        t0 = (mulmod(m[26], t0, q_mod));\n        m[26] = (mulmod(t0, m[15], q_mod));\n        t0 = (addmod(proof[109], m[3], q_mod));\n        m[29] = (mulmod(proof[108], t0, q_mod));\n        t0 = (addmod(proof[111], m[4], q_mod));\n        m[29] = (mulmod(m[29], t0, q_mod));\n        m[30] = (fr_mul_add(proof[82], proof[68], m[2]));\n        m[31] = (addmod(proof[109], q_mod - proof[111], q_mod));\n        t0 = (addmod(1, q_mod - proof[107], q_mod));\n        m[32] = (mulmod(m[14], t0, q_mod));\n        t0 = (mulmod(proof[107], proof[107], q_mod));\n        t0 = (addmod(t0, q_mod - proof[107], q_mod));\n        m[33] = (mulmod(m[20], t0, q_mod));\n        t0 = (addmod(m[30], m[3], q_mod));\n        t0 = (mulmod(proof[107], t0, q_mod));\n        t0 = (mulmod(t0, m[25], q_mod));\n        t0 = (addmod(m[29], q_mod - t0, q_mod));\n        m[29] = (mulmod(t0, m[15], q_mod));\n        m[30] = (mulmod(m[14], m[31], q_mod));\n        t0 = (addmod(proof[109], q_mod - proof[110], q_mod));\n        t0 = (mulmod(m[31], t0, q_mod));\n        m[31] = (mulmod(t0, m[15], q_mod));\n        t0 = (addmod(proof[114], m[3], q_mod));\n        m[34] = (mulmod(proof[113], t0, q_mod));\n        t0 = (addmod(proof[116], m[4], q_mod));\n        m[34] = (mulmod(m[34], t0, q_mod));\n        m[35] = (fr_mul_add(proof[82], proof[69], m[2]));\n        m[36] = (addmod(proof[114], q_mod - proof[116], q_mod));\n        t0 = (addmod(1, q_mod - proof[112], q_mod));\n        m[37] = (mulmod(m[14], t0, q_mod));\n        t0 = (mulmod(proof[112], proof[112], q_mod));\n        t0 = (addmod(t0, q_mod - proof[112], q_mod));\n        m[38] = (mulmod(m[20], t0, q_mod));\n        t0 = (addmod(m[35], m[3], q_mod));\n        t0 = (mulmod(proof[112], t0, q_mod));\n        t0 = (mulmod(t0, m[25], q_mod));\n        t0 = (addmod(m[34], q_mod - t0, q_mod));\n        m[34] = (mulmod(t0, m[15], q_mod));\n        m[35] = (mulmod(m[14], m[36], q_mod));\n        t0 = (addmod(proof[114], q_mod - proof[115], q_mod));\n        t0 = (mulmod(m[36], t0, q_mod));\n        m[36] = (mulmod(t0, m[15], q_mod));\n        t0 = (addmod(proof[119], m[3], q_mod));\n        m[39] = (mulmod(proof[118], t0, q_mod));\n        t0 = (addmod(proof[121], m[4], q_mod));\n        m[39] = (mulmod(m[39], t0, q_mod));\n        m[40] = (fr_mul_add(proof[82], proof[70], m[2]));\n        m[41] = (addmod(proof[119], q_mod - proof[121], q_mod));\n        t0 = (addmod(1, q_mod - proof[117], q_mod));\n        m[42] = (mulmod(m[14], t0, q_mod));\n        t0 = (mulmod(proof[117], proof[117], q_mod));\n        t0 = (addmod(t0, q_mod - proof[117], q_mod));\n        m[43] = (mulmod(m[20], t0, q_mod));\n        t0 = (addmod(m[40], m[3], q_mod));\n        t0 = (mulmod(proof[117], t0, q_mod));\n        t0 = (mulmod(t0, m[25], q_mod));\n        t0 = (addmod(m[39], q_mod - t0, q_mod));\n        m[25] = (mulmod(t0, m[15], q_mod));\n        m[39] = (mulmod(m[14], m[41], q_mod));\n        t0 = (addmod(proof[119], q_mod - proof[120], q_mod));\n        t0 = (mulmod(m[41], t0, q_mod));\n        m[40] = (mulmod(t0, m[15], q_mod));\n        t0 = (addmod(proof[124], m[3], q_mod));\n        m[41] = (mulmod(proof[123], t0, q_mod));\n        t0 = (addmod(proof[126], m[4], q_mod));\n        m[41] = (mulmod(m[41], t0, q_mod));\n        m[44] = (fr_mul_add(proof[84], proof[67], m[2]));\n        m[45] = (addmod(m[2], proof[85], q_mod));\n        m[46] = (addmod(proof[124], q_mod - proof[126], q_mod));\n        t0 = (addmod(1, q_mod - proof[122], q_mod));\n        m[47] = (mulmod(m[14], t0, q_mod));\n        t0 = (mulmod(proof[122], proof[122], q_mod));\n        t0 = (addmod(t0, q_mod - proof[122], q_mod));\n        m[48] = (mulmod(m[20], t0, q_mod));\n        t0 = (addmod(m[44], m[3], q_mod));\n        m[44] = (mulmod(proof[122], t0, q_mod));\n        t0 = (addmod(m[45], m[4], q_mod));\n        t0 = (mulmod(m[44], t0, q_mod));\n        t0 = (addmod(m[41], q_mod - t0, q_mod));\n        m[41] = (mulmod(t0, m[15], q_mod));\n        m[44] = (mulmod(m[14], m[46], q_mod));\n        t0 = (addmod(proof[124], q_mod - proof[125], q_mod));\n        t0 = (mulmod(m[46], t0, q_mod));\n        m[45] = (mulmod(t0, m[15], q_mod));\n        t0 = (addmod(proof[129], m[3], q_mod));\n        m[46] = (mulmod(proof[128], t0, q_mod));\n        t0 = (addmod(proof[131], m[4], q_mod));\n        m[46] = (mulmod(m[46], t0, q_mod));\n        m[49] = (fr_mul_add(proof[86], proof[67], m[2]));\n        m[50] = (addmod(m[2], proof[87], q_mod));\n        m[51] = (addmod(proof[129], q_mod - proof[131], q_mod));\n        t0 = (addmod(1, q_mod - proof[127], q_mod));\n        m[52] = (mulmod(m[14], t0, q_mod));\n        t0 = (mulmod(proof[127], proof[127], q_mod));\n        t0 = (addmod(t0, q_mod - proof[127], q_mod));\n        m[53] = (mulmod(m[20], t0, q_mod));\n        t0 = (addmod(m[49], m[3], q_mod));\n        m[49] = (mulmod(proof[127], t0, q_mod));\n        t0 = (addmod(m[50], m[4], q_mod));\n        t0 = (mulmod(m[49], t0, q_mod));\n        t0 = (addmod(m[46], q_mod - t0, q_mod));\n        m[46] = (mulmod(t0, m[15], q_mod));\n        m[49] = (mulmod(m[14], m[51], q_mod));\n        t0 = (addmod(proof[129], q_mod - proof[130], q_mod));\n        t0 = (mulmod(m[51], t0, q_mod));\n        m[50] = (mulmod(t0, m[15], q_mod));\n        t0 = (addmod(proof[134], m[3], q_mod));\n        m[51] = (mulmod(proof[133], t0, q_mod));\n        t0 = (addmod(proof[136], m[4], q_mod));\n        m[51] = (mulmod(m[51], t0, q_mod));\n        m[54] = (fr_mul_add(proof[88], proof[67], m[2]));\n        m[2] = (addmod(m[2], proof[89], q_mod));\n        m[55] = (addmod(proof[134], q_mod - proof[136], q_mod));\n        t0 = (addmod(1, q_mod - proof[132], q_mod));\n        m[56] = (mulmod(m[14], t0, q_mod));\n        t0 = (mulmod(proof[132], proof[132], q_mod));\n        t0 = (addmod(t0, q_mod - proof[132], q_mod));\n        m[20] = (mulmod(m[20], t0, q_mod));\n        t0 = (addmod(m[54], m[3], q_mod));\n        m[3] = (mulmod(proof[132], t0, q_mod));\n        t0 = (addmod(m[2], m[4], q_mod));\n        t0 = (mulmod(m[3], t0, q_mod));\n        t0 = (addmod(m[51], q_mod - t0, q_mod));\n        m[2] = (mulmod(t0, m[15], q_mod));\n        m[3] = (mulmod(m[14], m[55], q_mod));\n        t0 = (addmod(proof[134], q_mod - proof[135], q_mod));\n        t0 = (mulmod(m[55], t0, q_mod));\n        m[4] = (mulmod(t0, m[15], q_mod));\n        t0 = (fr_mul_add(m[5], 0, m[16]));\n        t0 = (\n            fr_mul_add_mt(\n                m,\n                m[5],\n                24064768791442479290152634096194013545513974547709823832001394403118888981009,\n                t0\n            )\n        );\n        t0 = (fr_mul_add_mt(m, m[5], 4704208815882882920750, t0));\n        m[2] = (fr_div(t0, m[13]));\n        m[3] = (mulmod(m[8], m[8], q_mod));\n        m[4] = (mulmod(m[3], m[8], q_mod));\n        (t0, t1) = (ecc_mul(proof[143], proof[144], m[4]));\n        (t0, t1) = (ecc_mul_add_pm(m, proof, 281470825071501, t0, t1));\n        (m[14], m[15]) = (ecc_add(t0, t1, proof[137], proof[138]));\n        m[5] = (mulmod(m[4], m[11], q_mod));\n        m[11] = (mulmod(m[4], m[7], q_mod));\n        m[13] = (mulmod(m[11], m[7], q_mod));\n        m[16] = (mulmod(m[13], m[7], q_mod));\n        m[17] = (mulmod(m[16], m[7], q_mod));\n        m[18] = (mulmod(m[17], m[7], q_mod));\n        m[19] = (mulmod(m[18], m[7], q_mod));\n        t0 = (mulmod(m[19], proof[135], q_mod));\n        t0 = (fr_mul_add_pm(m, proof, 79227007564587019091207590530, t0));\n        m[20] = (fr_mul_add(proof[105], m[4], t0));\n        m[10] = (mulmod(m[3], m[10], q_mod));\n        m[20] = (fr_mul_add(proof[99], m[3], m[20]));\n        m[9] = (mulmod(m[8], m[9], q_mod));\n        m[21] = (mulmod(m[8], m[7], q_mod));\n        for (t0 = 0; t0 < 8; t0++) {\n            m[22 + t0 * 1] = (mulmod(m[21 + t0 * 1], m[7 + t0 * 0], q_mod));\n        }\n        t0 = (mulmod(m[29], proof[133], q_mod));\n        t0 = (fr_mul_add_pm(m, proof, 1461480058012745347196003969984389955172320353408, t0));\n        m[20] = (addmod(m[20], t0, q_mod));\n        m[3] = (addmod(m[3], m[21], q_mod));\n        m[21] = (mulmod(m[7], m[7], q_mod));\n        m[30] = (mulmod(m[21], m[7], q_mod));\n        for (t0 = 0; t0 < 50; t0++) {\n            m[31 + t0 * 1] = (mulmod(m[30 + t0 * 1], m[7 + t0 * 0], q_mod));\n        }\n        m[81] = (mulmod(m[80], proof[90], q_mod));\n        m[82] = (mulmod(m[79], m[12], q_mod));\n        m[83] = (mulmod(m[82], m[12], q_mod));\n        m[12] = (mulmod(m[83], m[12], q_mod));\n        t0 = (fr_mul_add(m[79], m[2], m[81]));\n        t0 = (\n            fr_mul_add_pm(\n                m,\n                proof,\n                28637501128329066231612878461967933875285131620580756137874852300330784214624,\n                t0\n            )\n        );\n        t0 = (\n            fr_mul_add_pm(\n                m,\n                proof,\n                21474593857386732646168474467085622855647258609351047587832868301163767676495,\n                t0\n            )\n        );\n        t0 = (\n            fr_mul_add_pm(\n                m,\n                proof,\n                14145600374170319983429588659751245017860232382696106927048396310641433325177,\n                t0\n            )\n        );\n        t0 = (fr_mul_add_pm(m, proof, 18446470583433829957, t0));\n        t0 = (addmod(t0, proof[66], q_mod));\n        m[2] = (addmod(m[20], t0, q_mod));\n        m[19] = (addmod(m[19], m[54], q_mod));\n        m[20] = (addmod(m[29], m[53], q_mod));\n        m[18] = (addmod(m[18], m[51], q_mod));\n        m[28] = (addmod(m[28], m[50], q_mod));\n        m[17] = (addmod(m[17], m[48], q_mod));\n        m[27] = (addmod(m[27], m[47], q_mod));\n        m[16] = (addmod(m[16], m[45], q_mod));\n        m[26] = (addmod(m[26], m[44], q_mod));\n        m[13] = (addmod(m[13], m[42], q_mod));\n        m[25] = (addmod(m[25], m[41], q_mod));\n        m[11] = (addmod(m[11], m[39], q_mod));\n        m[24] = (addmod(m[24], m[38], q_mod));\n        m[4] = (addmod(m[4], m[36], q_mod));\n        m[23] = (addmod(m[23], m[35], q_mod));\n        m[22] = (addmod(m[22], m[34], q_mod));\n        m[3] = (addmod(m[3], m[33], q_mod));\n        m[8] = (addmod(m[8], m[32], q_mod));\n        (t0, t1) = (ecc_mul(proof[143], proof[144], m[5]));\n        (t0, t1) = (\n            ecc_mul_add_pm(\n                m,\n                proof,\n                10933423423422768024429730621579321771439401845242250760130969989159573132066,\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add_pm(m, proof, 1461486238301980199876269201563775120819706402602, t0, t1)\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                5631304900279594708207577329069240426704954596482218502768352363602244010198,\n                3522708784500173063141023483902975800044899953785444835727269387293279274164,\n                m[78],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                21802187684970109241607258147370295120854869223732255251756328570807304721847,\n                15237269163633931881258174620167924568373193514011004489179865433808206919535,\n                m[77],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                7015312950853575733378202381101181138419420484691827111888836883656445873540,\n                13214451818073201746109373586139435072784087878230873580637116067409833253869,\n                m[76],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                8875290982126581117169476014762185676959503094457222757180266633231098422655,\n                16658612061027315784709714701528999953885073192696800907733882175438727280488,\n                m[75],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                14303253065828884214244962411774594394939730558481746554884501972871650777281,\n                20280172603254715089032054569666991389693871275337876447609795617260462684999,\n                m[74],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                16422035665163677723702082823482432069720607684573585210415303920246506093315,\n                9793393098370529162991829973981347609939343033011950481395336563485709277554,\n                m[73],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                19886509832083393598366465489701294384803664485460545523068306491024326504725,\n                3485984208124097149766319408505384162933092797198027169851040569744728509599,\n                m[72],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                14568079492644817047677751551427098532431019595548498261375782030524138591067,\n                12502254616746968379936814454120981559238220208108783117821668421140888091912,\n                m[71],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                17108853774466418779129374196319580280286578385405087585516556746536875115907,\n                19908760740801913322265695807368645417588084579607860033571444712857010186774,\n                m[70],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                11691934824011527864744948250740538231773442820806051689004692986799416351463,\n                9666173287714138315600426908471006007081642390484687282425779441148942857178,\n                m[69],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                19886509832083393598366465489701294384803664485460545523068306491024326504725,\n                3485984208124097149766319408505384162933092797198027169851040569744728509599,\n                m[68],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                11404399605615092634676309725185307113649537305429435628605347712175932434590,\n                9922502566003738014881652170048397944295358276657521480420733572890676943869,\n                m[67],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                21627166622184628562834675422084345034193467320009306763329316593023720936150,\n                2103102746100002335801212537254725041663108226492711350135413308275232360031,\n                m[66],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                568462146324925334364777509199672146609025097965130219337894326417364148474,\n                9456720619750743439311951382388531487714800707396750882568165460640095082680,\n                m[65],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                21099324456940388227241377016313463517927803983676171781194388707018806062914,\n                10584022555470528248553696389724318513725952278467058058413941607304873249933,\n                m[64],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                8774533147672308325501456546754510530790571592717557081974138688131655464225,\n                4096202454427384571014982526038961216623335062582321937980880210743353116961,\n                m[63],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                9146027543241505750404485909691156685716025315398864559563663480915468386646,\n                11319433823656605429226268420832981572537028778988368091983653592806568615385,\n                m[62],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                18056938584379853827159803002321761943878530650811253236400635790684113168538,\n                20652554130222350781815293545352317626279032395744759345425764490019681709811,\n                m[61],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                9300598433087894486351617302854566119493030210672820277878405455719667853156,\n                18918648064031626393135000647897848703191870898299288846506432677047666356245,\n                m[60],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                13121094361229530562876703845037556024850884742094426137011404517198546098525,\n                5930172537651686544351746601150315597423637135299507288242652701476729181813,\n                m[59],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                4708706208794466628682087247497451067863475998313450030914472901274160722864,\n                7969186399956530399844662649330402127389596934829186492004088041920259891200,\n                m[58],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (\n            ecc_mul_add(\n                11222474342246472762342984653360997340158616377674469557576288428879498390755,\n                6564479924915349288368971464378961986642703162010246756611090316728014770982,\n                m[57],\n                t0,\n                t1\n            )\n        );\n        (t0, t1) = (ecc_mul_add(M_56_PX_VALUE, M_56_PY_VALUE, m[56], t0, t1));\n        (t0, t1) = (\n            ecc_mul_add_pm(\n                m,\n                proof,\n                6277008573546246765208814532330797927747086570010716419876,\n                t0,\n                t1\n            )\n        );\n        (m[0], m[1]) = (ecc_add(t0, t1, m[0], m[1]));\n        (t0, t1) = (ecc_mul(1, 2, m[2]));\n        (m[0], m[1]) = (ecc_sub(m[0], m[1], t0, t1));\n        return (m[14], m[15], m[0], m[1]);\n    }\n\n    function verify(\n        uint256[] calldata proof,\n        uint256[] calldata target_circuit_final_pair,\n        bytes32 publicInputHash\n    ) public view returns (bool) {\n        uint256[6] memory instances;\n        instances[0] = target_circuit_final_pair[0] & ((1 << 136) - 1);\n        instances[1] =\n            (target_circuit_final_pair[0] >> 136) +\n            ((target_circuit_final_pair[1] & 1) << 136);\n        instances[2] = target_circuit_final_pair[2] & ((1 << 136) - 1);\n        instances[3] =\n            (target_circuit_final_pair[2] >> 136) +\n            ((target_circuit_final_pair[3] & 1) << 136);\n\n        instances[4] = uint256(publicInputHash) >> (8 * 16);\n        instances[5] = uint256(publicInputHash) & uint256(2**128 - 1);\n\n        uint256 x0 = 0;\n        uint256 x1 = 0;\n        uint256 y0 = 0;\n        uint256 y1 = 0;\n\n        G1Point[] memory g1_points = new G1Point[](2);\n        G2Point[] memory g2_points = new G2Point[](2);\n\n        (x0, y0, x1, y1) = get_wx_wg(proof, instances);\n        g1_points[0].x = x0;\n        g1_points[0].y = y0;\n        g1_points[1].x = x1;\n        g1_points[1].y = y1;\n        g2_points[0] = get_verify_circuit_g2_s();\n        g2_points[1] = get_verify_circuit_g2_n();\n\n        if (!pairing(g1_points, g2_points)) {\n            return false;\n        }\n\n        g1_points[0].x = target_circuit_final_pair[0];\n        g1_points[0].y = target_circuit_final_pair[1];\n        g1_points[1].x = target_circuit_final_pair[2];\n        g1_points[1].y = target_circuit_final_pair[3];\n        g2_points[0] = get_target_circuit_g2_s();\n        g2_points[1] = get_target_circuit_g2_n();\n\n        if (!pairing(g1_points, g2_points)) {\n            return false;\n        }\n\n        return true;\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"
      },
      "contracts/libraries/Encoding.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Hashing } from \"./Hashing.sol\";\nimport { Types } from \"./Types.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Kroma's various different encoding schemes.\n */\nlibrary Encoding {\n    /**\n     * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n     *         to the L2 system. Useful for searching for a deposit in the L2 system. The\n     *         transaction is prefixed with 0x7e to identify its EIP-2718 type.\n     *\n     * @param _tx User deposit transaction to encode.\n     *\n     * @return RLP encoded L2 deposit transaction.\n     */\n    function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n        internal\n        pure\n        returns (bytes memory)\n    {\n        bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n        bytes[] memory raw = new bytes[](7);\n        raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n        raw[1] = RLPWriter.writeAddress(_tx.from);\n        raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n        raw[3] = RLPWriter.writeUint(_tx.mint);\n        raw[4] = RLPWriter.writeUint(_tx.value);\n        raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n        raw[6] = RLPWriter.writeBytes(_tx.data);\n        return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n    }\n\n    /**\n     * @notice Encodes the cross domain message based on the version that is encoded into the\n     *         message nonce.\n     *\n     * @param _nonce    Message nonce with version encoded into the first two bytes.\n     * @param _sender   Address of the sender of the message.\n     * @param _target   Address of the target of the message.\n     * @param _value    ETH value to send to the target.\n     * @param _gasLimit Gas limit to use for the message.\n     * @param _data     Data to send with the message.\n     *\n     * @return Encoded cross domain message.\n     */\n    function encodeCrossDomainMessage(\n        uint256 _nonce,\n        address _sender,\n        address _target,\n        uint256 _value,\n        uint256 _gasLimit,\n        bytes memory _data\n    ) internal pure returns (bytes memory) {\n        (, uint16 version) = decodeVersionedNonce(_nonce);\n        if (version == 0) {\n            return encodeCrossDomainMessageV0(_nonce, _sender, _target, _value, _gasLimit, _data);\n        } else {\n            revert(\"Encoding: unknown cross domain message version\");\n        }\n    }\n\n    /**\n     * @notice Encodes a cross domain message based on the V0 (current) encoding.\n     *\n     * @param _nonce    Message nonce.\n     * @param _sender   Address of the sender of the message.\n     * @param _target   Address of the target of the message.\n     * @param _value    ETH value to send to the target.\n     * @param _gasLimit Gas limit to use for the message.\n     * @param _data     Data to send with the message.\n     *\n     * @return Encoded cross domain message.\n     */\n    function encodeCrossDomainMessageV0(\n        uint256 _nonce,\n        address _sender,\n        address _target,\n        uint256 _value,\n        uint256 _gasLimit,\n        bytes memory _data\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodeWithSignature(\n                \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n                _nonce,\n                _sender,\n                _target,\n                _value,\n                _gasLimit,\n                _data\n            );\n    }\n\n    /**\n     * @notice Adds a version number into the first two bytes of a message nonce.\n     *\n     * @param _nonce   Message nonce to encode into.\n     * @param _version Version number to encode into the message nonce.\n     *\n     * @return Message nonce with version encoded into the first two bytes.\n     */\n    function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n        uint256 nonce;\n        assembly {\n            nonce := or(shl(240, _version), _nonce)\n        }\n        return nonce;\n    }\n\n    /**\n     * @notice Pulls the version out of a version-encoded nonce.\n     *\n     * @param _nonce Message nonce with version encoded into the first two bytes.\n     *\n     * @return Nonce without encoded version.\n     * @return Version of the message.\n     */\n    function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n        uint240 nonce;\n        uint16 version;\n        assembly {\n            nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n            version := shr(240, _nonce)\n        }\n        return (nonce, version);\n    }\n}\n"
      },
      "contracts/libraries/rlp/RLPWriter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n *         RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n *         modifications to improve legibility.\n */\nlibrary RLPWriter {\n    /**\n     * @notice RLP encodes a byte string.\n     *\n     * @param _in The byte string to encode.\n     *\n     * @return The RLP encoded string in bytes.\n     */\n    function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n        bytes memory encoded;\n\n        if (_in.length == 1 && uint8(_in[0]) < 128) {\n            encoded = _in;\n        } else {\n            encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n        }\n\n        return encoded;\n    }\n\n    /**\n     * @notice RLP encodes a list of RLP encoded byte byte strings.\n     *\n     * @param _in The list of RLP encoded byte strings.\n     *\n     * @return The RLP encoded list of items in bytes.\n     */\n    function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n        bytes memory list = _flatten(_in);\n        return abi.encodePacked(_writeLength(list.length, 192), list);\n    }\n\n    /**\n     * @notice RLP encodes a string.\n     *\n     * @param _in The string to encode.\n     *\n     * @return The RLP encoded string in bytes.\n     */\n    function writeString(string memory _in) internal pure returns (bytes memory) {\n        return writeBytes(bytes(_in));\n    }\n\n    /**\n     * @notice RLP encodes an address.\n     *\n     * @param _in The address to encode.\n     *\n     * @return The RLP encoded address in bytes.\n     */\n    function writeAddress(address _in) internal pure returns (bytes memory) {\n        return writeBytes(abi.encodePacked(_in));\n    }\n\n    /**\n     * @notice RLP encodes a uint.\n     *\n     * @param _in The uint256 to encode.\n     *\n     * @return The RLP encoded uint256 in bytes.\n     */\n    function writeUint(uint256 _in) internal pure returns (bytes memory) {\n        return writeBytes(_toBinary(_in));\n    }\n\n    /**\n     * @notice RLP encodes a bool.\n     *\n     * @param _in The bool to encode.\n     *\n     * @return The RLP encoded bool in bytes.\n     */\n    function writeBool(bool _in) internal pure returns (bytes memory) {\n        bytes memory encoded = new bytes(1);\n        encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n        return encoded;\n    }\n\n    /**\n     * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n     *\n     * @param _len    The length of the string or the payload.\n     * @param _offset 128 if item is string, 192 if item is list.\n     *\n     * @return RLP encoded bytes.\n     */\n    function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n        bytes memory encoded;\n\n        if (_len < 56) {\n            encoded = new bytes(1);\n            encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n        } else {\n            uint256 lenLen;\n            uint256 i = 1;\n            while (_len / i != 0) {\n                lenLen++;\n                i *= 256;\n            }\n\n            encoded = new bytes(lenLen + 1);\n            encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n            for (i = 1; i <= lenLen; i++) {\n                encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n            }\n        }\n\n        return encoded;\n    }\n\n    /**\n     * @notice Encode integer in big endian binary form with no leading zeroes.\n     *\n     * @param _x The integer to encode.\n     *\n     * @return RLP encoded bytes.\n     */\n    function _toBinary(uint256 _x) private pure returns (bytes memory) {\n        bytes memory b = abi.encodePacked(_x);\n\n        uint256 i = 0;\n        for (; i < 32; i++) {\n            if (b[i] != 0) {\n                break;\n            }\n        }\n\n        bytes memory res = new bytes(32 - i);\n        for (uint256 j = 0; j < res.length; j++) {\n            res[j] = b[i++];\n        }\n\n        return res;\n    }\n\n    /**\n     * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n     * @notice Copies a piece of memory to another location.\n     *\n     * @param _dest Destination location.\n     * @param _src  Source location.\n     * @param _len  Length of memory to copy.\n     */\n    function _memcpy(\n        uint256 _dest,\n        uint256 _src,\n        uint256 _len\n    ) private pure {\n        uint256 dest = _dest;\n        uint256 src = _src;\n        uint256 len = _len;\n\n        for (; len >= 32; len -= 32) {\n            assembly {\n                mstore(dest, mload(src))\n            }\n            dest += 32;\n            src += 32;\n        }\n\n        uint256 mask;\n        unchecked {\n            mask = 256**(32 - len) - 1;\n        }\n        assembly {\n            let srcpart := and(mload(src), not(mask))\n            let destpart := and(mload(dest), mask)\n            mstore(dest, or(destpart, srcpart))\n        }\n    }\n\n    /**\n     * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n     * @notice Flattens a list of byte strings into one byte string.\n     *\n     * @param _list List of byte strings to flatten.\n     *\n     * @return The flattened byte string.\n     */\n    function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n        if (_list.length == 0) {\n            return new bytes(0);\n        }\n\n        uint256 len;\n        uint256 i = 0;\n        for (; i < _list.length; i++) {\n            len += _list[i].length;\n        }\n\n        bytes memory flattened = new bytes(len);\n        uint256 flattenedPtr;\n        assembly {\n            flattenedPtr := add(flattened, 0x20)\n        }\n\n        for (i = 0; i < _list.length; i++) {\n            bytes memory item = _list[i];\n\n            uint256 listPtr;\n            assembly {\n                listPtr := add(item, 0x20)\n            }\n\n            _memcpy(flattenedPtr, listPtr, item.length);\n            flattenedPtr += _list[i].length;\n        }\n\n        return flattened;\n    }\n}\n"
      },
      "contracts/libraries/Constants.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n/**\n * @title Constants\n * @notice Constants is a library for storing constants. Simple! Don't put everything in here, just\n *         the stuff used in multiple contracts. Constants that only apply to a single contract\n *         should be defined in that contract instead.\n */\nlibrary Constants {\n    /**\n     * @notice Special address to be used as the tx origin for gas estimation calls in the\n     *         KromaPortal and CrossDomainMessenger calls. You only need to use this address if\n     *         the minimum gas limit specified by the user is not actually enough to execute the\n     *         given message and you're attempting to estimate the actual necessary gas limit. We\n     *         use address(1) because it's the ecrecover precompile and therefore guaranteed to\n     *         never have any code on any EVM chain.\n     */\n    address internal constant ESTIMATION_ADDRESS = address(1);\n\n    /**\n     * @notice Value used for the L2 sender storage slot in both the KromaPortal and the\n     *         CrossDomainMessenger contracts before an actual sender is set. This value is\n     *         non-zero to reduce the gas cost of message passing transactions.\n     */\n    address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;\n\n    /**\n     * @notice Returns the default values for the ResourceConfig. These are the recommended values\n     *         for a production network.\n     */\n    function DEFAULT_RESOURCE_CONFIG()\n        internal\n        pure\n        returns (ResourceMetering.ResourceConfig memory)\n    {\n        ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n            maxResourceLimit: 20_000_000,\n            elasticityMultiplier: 10,\n            baseFeeMaxChangeDenominator: 8,\n            minimumBaseFee: 1 gwei,\n            systemTxMaxGas: 1_000_000,\n            maximumBaseFee: type(uint128).max\n        });\n        return config;\n    }\n\n    /**\n     * @notice The denominator of the validator reward.\n     *         DO NOT change this value if the L2 chain is already operational.\n     */\n    uint256 internal constant VALIDATOR_REWARD_DENOMINATOR = 10000;\n\n    /**\n     * @notice An address that identifies that current submission round is a public round.\n     */\n    address internal constant VALIDATOR_PUBLIC_ROUND_ADDRESS = address(type(uint160).max);\n}\n"
      },
      "contracts/L1/ValidatorPool.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n    ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ISemver } from \"../universal/ISemver.sol\";\nimport { ValidatorRewardVault } from \"../L2/ValidatorRewardVault.sol\";\nimport { KromaPortal } from \"./KromaPortal.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\n\n/**\n * @custom:proxied\n * @title ValidatorPool\n * @notice The ValidatorPool determines whether the validator is present and manages the validator's deposit.\n */\ncontract ValidatorPool is ReentrancyGuardUpgradeable, ISemver {\n    /**\n     * @notice The gas limit to use when rewarding validator in the ValidatorRewardVault on L2.\n     *         This value is measured through simulation.\n     */\n    uint64 public constant VAULT_REWARD_GAS_LIMIT = 100000;\n\n    /**\n     * @notice The numerator of the tax.\n     */\n    uint128 public constant TAX_NUMERATOR = 20;\n\n    /**\n     * @notice The denominator of the tax.\n     */\n    uint128 public constant TAX_DENOMINATOR = 100;\n\n    /**\n     * @notice The address of the L2OutputOracle contract. Can be updated via upgrade.\n     */\n    L2OutputOracle public immutable L2_ORACLE;\n\n    /**\n     * @notice The address of the KromaPortal contract. Can be updated via upgrade.\n     */\n    KromaPortal public immutable PORTAL;\n\n    /**\n     * @notice The address of the SecurityCouncil contract. Can be updated via upgrade.\n     */\n    address public immutable SECURITY_COUNCIL;\n\n    /**\n     * @notice The address of the trusted validator. Can be updated via upgrade.\n     */\n    address public immutable TRUSTED_VALIDATOR;\n\n    /**\n     * @notice The required bond amount. Can be updated via upgrade.\n     */\n    uint128 public immutable REQUIRED_BOND_AMOUNT;\n\n    /**\n     * @notice The max number of unbonds when trying unbond.\n     */\n    uint256 public immutable MAX_UNBOND;\n\n    /**\n     * @notice The duration of a submission round for one output (in seconds).\n     *         Note that there are two submission rounds for an output: PRIORITY ROUND and PUBLIC ROUND.\n     */\n    uint256 public immutable ROUND_DURATION;\n\n    /**\n     * @notice A mapping of balances.\n     */\n    mapping(address => uint256) internal balances;\n\n    /**\n     * @notice The bond corresponding to a specific output index.\n     */\n    mapping(uint256 => Types.Bond) internal bonds;\n\n    /**\n     * @notice The output index to unbond next.\n     */\n    uint256 internal nextUnbondOutputIndex;\n\n    /**\n     * @notice An array of validator addresses.\n     */\n    address[] internal validators;\n\n    /**\n     * @notice The index of the specific address in the validator array.\n     */\n    mapping(address => uint256) internal validatorIndexes;\n\n    /**\n     * @notice Address of the next validator with priority for submitting output.\n     */\n    address internal nextPriorityValidator;\n\n    /**\n     * @notice A mapping of pending bonds that have not yet been included in a bond.\n     */\n    mapping(uint256 => mapping(address => uint128)) internal pendingBonds;\n\n    /**\n     * @notice Emitted when a validator bonds.\n     *\n     * @param submitter   Address of submitter.\n     * @param outputIndex Index of the L2 checkpoint output index.\n     * @param amount      Amount of bonded.\n     * @param expiresAt   The expiration timestamp of bond.\n     */\n    event Bonded(\n        address indexed submitter,\n        uint256 indexed outputIndex,\n        uint128 amount,\n        uint128 expiresAt\n    );\n\n    /**\n     * @notice Emitted when the pending bond is added.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param challenger  Address of the challenger.\n     * @param amount      Amount of bond added.\n     */\n    event PendingBondAdded(uint256 indexed outputIndex, address indexed challenger, uint128 amount);\n\n    /**\n     * @notice Emitted when the bond is increased.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param challenger  Address of the challenger.\n     * @param amount      Amount of bond increased.\n     */\n    event BondIncreased(uint256 indexed outputIndex, address indexed challenger, uint128 amount);\n\n    /**\n     * @notice Emitted when the pending bond is released(refunded).\n     *\n     * @param outputIndex  Index of the L2 checkpoint output.\n     * @param challenger   Address of the challenger.\n     * @param recipient    Address to receive amount from a pending bond.\n     * @param amount       Amount of bond released.\n     */\n    event PendingBondReleased(\n        uint256 indexed outputIndex,\n        address indexed challenger,\n        address indexed recipient,\n        uint128 amount\n    );\n\n    /**\n     * @notice Emitted when a validator unbonds.\n     *\n     * @param outputIndex Index of the L2 checkpoint output.\n     * @param recipient   Address of the recipient.\n     * @param amount      Amount of unbonded.\n     */\n    event Unbonded(uint256 indexed outputIndex, address indexed recipient, uint128 amount);\n\n    /**\n     * @notice A modifier that only allows the Colosseum contract to call\n     */\n    modifier onlyColosseum() {\n        require(msg.sender == L2_ORACLE.COLOSSEUM(), \"ValidatorPool: sender is not Colosseum\");\n        _;\n    }\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.0.1\n     */\n    string public constant version = \"1.0.1\";\n\n    /**\n     * @notice Constructs the ValidatorPool contract.\n     *\n     * @param _l2OutputOracle     Address of the L2OutputOracle.\n     * @param _portal             Address of the KromaPortal.\n     * @param _securityCouncil    Address of the security council.\n     * @param _trustedValidator   Address of the trusted validator.\n     * @param _requiredBondAmount The required bond amount.\n     * @param _maxUnbond          The max number of unbonds when trying unbond.\n     * @param _roundDuration      The duration of one submission round in seconds.\n     */\n    constructor(\n        L2OutputOracle _l2OutputOracle,\n        KromaPortal _portal,\n        address _securityCouncil,\n        address _trustedValidator,\n        uint256 _requiredBondAmount,\n        uint256 _maxUnbond,\n        uint256 _roundDuration\n    ) {\n        L2_ORACLE = _l2OutputOracle;\n        PORTAL = _portal;\n        SECURITY_COUNCIL = _securityCouncil;\n        TRUSTED_VALIDATOR = _trustedValidator;\n        REQUIRED_BOND_AMOUNT = uint128(_requiredBondAmount);\n        MAX_UNBOND = _maxUnbond;\n\n        // Note that this value MUST be (SUBMISSION_INTERVAL * L2_BLOCK_TIME) / 2.\n        ROUND_DURATION = _roundDuration;\n\n        initialize();\n    }\n\n    /**\n     * @notice Initializer.\n     */\n    function initialize() public initializer {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    /**\n     * @notice Deposit ETH to be used as bond.\n     */\n    function deposit() external payable {\n        _increaseBalance(msg.sender, msg.value);\n    }\n\n    /**\n     * @notice Withdraw a given amount.\n     *\n     * @param _amount Amount to withdraw.\n     */\n    function withdraw(uint256 _amount) external nonReentrant {\n        _decreaseBalance(msg.sender, _amount);\n\n        bool success = SafeCall.call(msg.sender, gasleft(), _amount, \"\");\n        require(success, \"ValidatorPool: ETH transfer failed\");\n    }\n\n    /**\n     * @notice Withdraw a given amount.\n     *\n     * @param _to     Address to withdraw asset to.\n     * @param _amount Amount to withdraw.\n     */\n    function withdrawTo(address _to, uint256 _amount) external nonReentrant {\n        require(_to != address(0), \"ValidatorPool: cannot withdraw to the zero address\");\n\n        _decreaseBalance(msg.sender, _amount);\n\n        bool success = SafeCall.call(_to, gasleft(), _amount, \"\");\n        require(success, \"ValidatorPool: ETH transfer failed\");\n    }\n\n    /**\n     * @notice Bond asset corresponding to the given output index.\n     *         This function is called when submitting output.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _expiresAt   The expiration timestamp of bond.\n     */\n    function createBond(uint256 _outputIndex, uint128 _expiresAt) external {\n        require(msg.sender == address(L2_ORACLE), \"ValidatorPool: sender is not L2OutputOracle\");\n\n        Types.Bond storage bond = bonds[_outputIndex];\n        require(\n            bond.expiresAt == 0,\n            \"ValidatorPool: bond of the given output index already exists\"\n        );\n\n        // Unbond the bond of nextUnbondOutputIndex if available.\n        _tryUnbond();\n\n        address submitter = L2_ORACLE.getSubmitter(_outputIndex);\n        _decreaseBalance(submitter, REQUIRED_BOND_AMOUNT);\n\n        bond.amount = REQUIRED_BOND_AMOUNT;\n        bond.expiresAt = _expiresAt;\n\n        emit Bonded(submitter, _outputIndex, REQUIRED_BOND_AMOUNT, _expiresAt);\n\n        // Select the next priority validator\n        _updatePriorityValidator();\n    }\n\n    /**\n     * @notice Adds a pending bond to the challenge corresponding to the given output index and challenger address.\n     *         The pending bond is added to the bond when the challenge is proven or challenger is timed out,\n     *         or refunded when the challenge is canceled.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     */\n    function addPendingBond(uint256 _outputIndex, address _challenger) external onlyColosseum {\n        Types.Bond storage bond = bonds[_outputIndex];\n        require(\n            bond.expiresAt >= block.timestamp,\n            \"ValidatorPool: the output is already finalized\"\n        );\n\n        _decreaseBalance(_challenger, REQUIRED_BOND_AMOUNT);\n        pendingBonds[_outputIndex][_challenger] = REQUIRED_BOND_AMOUNT;\n\n        emit PendingBondAdded(_outputIndex, _challenger, REQUIRED_BOND_AMOUNT);\n    }\n\n    /**\n     * @notice Releases the corresponding pending bond to the given output index and challenger address\n     *         if a challenge is canceled.\n     *\n     * @param _outputIndex  Index of the L2 checkpoint output.\n     * @param _challenger   Address of the challenger.\n     * @param _recipient    Address to receive amount from a pending bond.\n     */\n    function releasePendingBond(\n        uint256 _outputIndex,\n        address _challenger,\n        address _recipient\n    ) external onlyColosseum {\n        uint128 bonded = pendingBonds[_outputIndex][_challenger];\n        require(bonded > 0, \"ValidatorPool: the pending bond does not exist\");\n        delete pendingBonds[_outputIndex][_challenger];\n\n        _increaseBalance(_recipient, bonded);\n        emit PendingBondReleased(_outputIndex, _challenger, _recipient, bonded);\n    }\n\n    /**\n     * @notice Increases the bond amount corresponding to the given output index by the pending bond amount.\n     *         This is when taxes are charged, and note that taxes are a means of preventing collusive attacks by\n     *         the asserter and challenger.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     */\n    function increaseBond(uint256 _outputIndex, address _challenger) external onlyColosseum {\n        Types.Bond storage bond = bonds[_outputIndex];\n        require(\n            bond.expiresAt >= block.timestamp,\n            \"ValidatorPool: the output is already finalized\"\n        );\n\n        uint128 pendingBond = pendingBonds[_outputIndex][_challenger];\n        require(pendingBond > 0, \"ValidatorPool: the pending bond does not exist\");\n        uint128 tax = (pendingBond * TAX_NUMERATOR) / TAX_DENOMINATOR;\n        uint128 increased = pendingBond - tax;\n        delete pendingBonds[_outputIndex][_challenger];\n\n        unchecked {\n            bond.amount += increased;\n            balances[SECURITY_COUNCIL] += tax;\n        }\n\n        emit BondIncreased(_outputIndex, _challenger, increased);\n    }\n\n    /**\n     * @notice Attempt to unbond. Reverts if unbond is not possible.\n     */\n    function unbond() external {\n        bool released = _tryUnbond();\n        require(released, \"ValidatorPool: no bond that can be unbond\");\n    }\n\n    /**\n     * @notice Attempts to unbond starting from nextUnbondOutputIndex and returns whether at least\n     *         one unbond is executed. Tries unbond at most MAX_UNBOND number of bonds and sends\n     *         a reward message to L2 for each unbond.\n     *\n     * @return Whether at least one unbond is executed.\n     */\n    function _tryUnbond() private returns (bool) {\n        uint256 outputIndex = nextUnbondOutputIndex;\n        uint128 bondAmount;\n        Types.Bond storage bond;\n        Types.CheckpointOutput memory output;\n\n        uint256 unbondedNum = 0;\n        for (; unbondedNum < MAX_UNBOND; ) {\n            bond = bonds[outputIndex];\n            bondAmount = bond.amount;\n\n            if (block.timestamp >= bond.expiresAt && bondAmount > 0) {\n                delete bonds[outputIndex];\n                output = L2_ORACLE.getL2Output(outputIndex);\n                _increaseBalance(output.submitter, bondAmount);\n                emit Unbonded(outputIndex, output.submitter, bondAmount);\n\n                // Send reward message to L2 ValidatorRewardVault.\n                _sendRewardMessageToL2Vault(output);\n\n                unchecked {\n                    ++unbondedNum;\n                    ++outputIndex;\n                }\n            } else {\n                break;\n            }\n        }\n\n        if (unbondedNum > 0) {\n            unchecked {\n                nextUnbondOutputIndex = outputIndex;\n            }\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * @notice Updates next priority validator address.\n     */\n    function _updatePriorityValidator() private {\n        uint256 len = validators.length;\n        if (len > 0 && nextUnbondOutputIndex > 0) {\n            // TODO(pangssu): improve next validator selection\n            Types.CheckpointOutput memory output = L2_ORACLE.getL2Output(nextUnbondOutputIndex - 1);\n            uint256 validatorIndex = uint256(\n                keccak256(\n                    abi.encodePacked(\n                        output.outputRoot,\n                        block.number,\n                        block.coinbase,\n                        block.difficulty,\n                        blockhash(block.number - 1)\n                    )\n                )\n            ) % len;\n\n            nextPriorityValidator = validators[validatorIndex];\n        } else {\n            nextPriorityValidator = address(0);\n        }\n    }\n\n    /**\n     * @notice Sends reward message to ValidatorRewardVault contract on L2 using Portal.\n     *\n     * @param _output The finalized output.\n     */\n    function _sendRewardMessageToL2Vault(Types.CheckpointOutput memory _output) private {\n        // Pay out rewards via L2 Vault now that the output is finalized.\n        PORTAL.depositTransactionByValidatorPool(\n            Predeploys.VALIDATOR_REWARD_VAULT,\n            VAULT_REWARD_GAS_LIMIT,\n            abi.encodeWithSelector(\n                ValidatorRewardVault.reward.selector,\n                _output.submitter,\n                _output.l2BlockNumber\n            )\n        );\n    }\n\n    /**\n     * @notice Increases the balance of the given address. If the balance is greater than the required bond amount,\n     *         add the given address to the validator set.\n     *\n     * @param _validator Address to increase the balance.\n     * @param _amount    Amount of balance increased.\n     */\n    function _increaseBalance(address _validator, uint256 _amount) private {\n        uint256 balance = balances[_validator] + _amount;\n\n        if (balance >= REQUIRED_BOND_AMOUNT && !isValidator(_validator)) {\n            if (_validator != SECURITY_COUNCIL) {\n                validatorIndexes[_validator] = validators.length;\n                validators.push(_validator);\n            }\n        }\n\n        balances[_validator] = balance;\n    }\n\n    /**\n     * @notice Deceases the balance of the given address. If the balance is less than the required bond amount,\n     *         remove the given address from the validator set.\n     *\n     * @param _validator Address to decrease the balance.\n     * @param _amount    Amount of balance decreased.\n     */\n    function _decreaseBalance(address _validator, uint256 _amount) private {\n        uint256 balance = balances[_validator];\n        require(balance >= _amount, \"ValidatorPool: insufficient balances\");\n        balance = balance - _amount;\n\n        if (balance < REQUIRED_BOND_AMOUNT && isValidator(_validator)) {\n            uint256 lastValidatorIndex = validators.length - 1;\n            if (lastValidatorIndex > 0) {\n                uint256 validatorIndex = validatorIndexes[_validator];\n                address lastValidator = validators[lastValidatorIndex];\n\n                validators[validatorIndex] = lastValidator;\n                validatorIndexes[lastValidator] = validatorIndex;\n            }\n            delete validatorIndexes[_validator];\n            validators.pop();\n        }\n\n        balances[_validator] = balance;\n    }\n\n    /**\n     * @notice Returns the bond corresponding to the output index. Reverts if the bond does not exist.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     *\n     * @return The bond data.\n     */\n    function getBond(uint256 _outputIndex) external view returns (Types.Bond memory) {\n        Types.Bond storage bond = bonds[_outputIndex];\n        require(bond.amount > 0 && bond.expiresAt > 0, \"ValidatorPool: the bond does not exist\");\n        return bond;\n    }\n\n    /**\n     * @notice Returns the pending bond corresponding to the output index and challenger address.\n     *         Reverts if the pending bond does not exist.\n     *\n     * @param _outputIndex Index of the L2 checkpoint output.\n     * @param _challenger  Address of the challenger.\n     *\n     * @return Amount of the pending bond.\n     */\n    function getPendingBond(uint256 _outputIndex, address _challenger)\n        external\n        view\n        returns (uint128)\n    {\n        uint128 pendingBond = pendingBonds[_outputIndex][_challenger];\n        require(pendingBond > 0, \"ValidatorPool: the pending bond does not exist\");\n        return pendingBond;\n    }\n\n    /**\n     * @notice Returns the balance of given address.\n     *\n     * @param _addr Address of validator.\n     *\n     * @return Balance of given address.\n     */\n    function balanceOf(address _addr) external view returns (uint256) {\n        return balances[_addr];\n    }\n\n    /**\n     * @notice Determines whether the given address is an active validator.\n     *\n     * @param _addr Address of validator.\n     *\n     * @return Whether the given address is an active validator.\n     */\n    function isValidator(address _addr) public view returns (bool) {\n        if (validators.length == 0) {\n            return false;\n        } else if (_addr == address(0)) {\n            return false;\n        }\n\n        uint256 index = validatorIndexes[_addr];\n        return validators[index] == _addr;\n    }\n\n    /**\n     * @notice Returns the number of validators.\n     *\n     * @return The number of validators.\n     */\n    function validatorCount() external view returns (uint256) {\n        return validators.length;\n    }\n\n    /**\n     * @notice Determines who can submit the L2 output next.\n     *\n     * @return The address of the validator.\n     */\n    function nextValidator() public view returns (address) {\n        if (nextPriorityValidator != address(0)) {\n            uint256 l2BlockNumber = L2_ORACLE.nextBlockNumber();\n            uint256 l2Timestamp = L2_ORACLE.computeL2Timestamp(l2BlockNumber + 1);\n            if (block.timestamp >= l2Timestamp) {\n                uint256 elapsed = block.timestamp - l2Timestamp;\n                // If the current time exceeds one round time, it is a public round.\n                if (elapsed > ROUND_DURATION) {\n                    return Constants.VALIDATOR_PUBLIC_ROUND_ADDRESS;\n                }\n            }\n\n            return nextPriorityValidator;\n        } else {\n            return TRUSTED_VALIDATOR;\n        }\n    }\n}\n"
      },
      "contracts/universal/TokenMultiSigWallet.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC5805Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol\";\n\nimport { UpgradeGovernor } from \"../governance/UpgradeGovernor.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ITokenMultiSigWallet } from \"./ITokenMultiSigWallet.sol\";\n\n/**\n * @custom:upgradeable\n * @title TokenMultiSigWallet\n * @notice This contract implements `ITokenMultiSigWallet`.\n *         Allows multiple parties to agree on transactions before execution.\n */\nabstract contract TokenMultiSigWallet is ITokenMultiSigWallet, ReentrancyGuardUpgradeable {\n    /**\n     * @notice The address of the governor contract. Can be updated via upgrade.\n     */\n    UpgradeGovernor public immutable GOVERNOR;\n\n    /**\n     * @notice A mapping of transactions submitted.\n     */\n    mapping(uint256 => Types.MultiSigTransaction) public transactions;\n\n    /**\n     * @notice A mapping of confirmations.\n     */\n    mapping(uint256 => Types.MultiSigConfirmation) public confirmations;\n\n    /**\n     * @notice Spacer for backwards compatibility.\n     */\n    uint256[3] private spacer_53_0_96;\n\n    /**\n     * @notice The number of transactions submitted.\n     */\n    uint256 public transactionCount;\n\n    /**\n     * @notice Only allow the owner of governance token to call the functions.\n     *         This ensures that function is only executed by governance.\n     */\n    modifier onlyTokenOwner(address _address) {\n        require(\n            getVotes(_address) > 0,\n            \"TokenMultiSigWallet: only allowed to governance token owner\"\n        );\n        _;\n    }\n\n    /**\n     * @notice Ensure that the transaction exists.\n     *\n     * @param _transactionId The ID of submitted transaction requested.\n     */\n    modifier transactionExists(uint256 _transactionId) {\n        require(\n            transactions[_transactionId].target != address(0),\n            \"TokenMultiSigWallet: transaction does not exist\"\n        );\n        _;\n    }\n\n    /**\n     * @notice Ensure that the transaction not exceuted.\n     *\n     * @param _transactionId The ID of transaction to check.\n     */\n    modifier transactionNotExcuted(uint256 _transactionId) {\n        require(!transactions[_transactionId].executed, \"TokenMultiSigWallet: already executed\");\n        _;\n    }\n\n    /**\n     * @notice Ensure that the address is not zero address.\n     *\n     * @param _address Address resource requested.\n     */\n    modifier validAddress(address _address) {\n        require(_address != address(0), \"TokenMultiSigWallet: address is not valid\");\n        _;\n    }\n\n    /**\n     * @param _governor Address of the Governor contract.\n     */\n    constructor(address payable _governor) {\n        GOVERNOR = UpgradeGovernor(_governor);\n    }\n\n    /**\n     * @inheritdoc ITokenMultiSigWallet\n     */\n    function submitTransaction(\n        address _target,\n        uint256 _value,\n        bytes memory _data\n    ) public onlyTokenOwner(msg.sender) returns (uint256) {\n        return _submitTransaction(_target, _value, _data);\n    }\n\n    function _submitTransaction(\n        address _target,\n        uint256 _value,\n        bytes memory _data\n    ) internal validAddress(_target) returns (uint256) {\n        uint256 transactionId = generateTransactionId(_target, _value, _data);\n        require(\n            transactions[transactionId].target == address(0),\n            \"TokenMultiSigWallet: transaction already exists\"\n        );\n\n        transactions[transactionId] = Types.MultiSigTransaction({\n            target: _target,\n            value: _value,\n            data: _data,\n            executed: false\n        });\n\n        unchecked {\n            ++transactionCount;\n        }\n\n        emit TransactionSubmitted(msg.sender, transactionId);\n        return transactionId;\n    }\n\n    /**\n     * @inheritdoc ITokenMultiSigWallet\n     */\n    function confirmTransaction(uint256 _transactionId)\n        public\n        onlyTokenOwner(msg.sender)\n        transactionExists(_transactionId)\n    {\n        Types.MultiSigConfirmation storage confirms = confirmations[_transactionId];\n        require(!confirms.confirmedBy[msg.sender], \"TokenMultiSigWallet: already confirmed\");\n        confirms.confirmedBy[msg.sender] = true;\n        confirms.confirmationCount += getVotes(msg.sender);\n        emit TransactionConfirmed(msg.sender, _transactionId);\n\n        // execute transaction if condition is met.\n        if (confirmations[_transactionId].confirmationCount >= quorum()) {\n            executeTransaction(_transactionId);\n        }\n    }\n\n    /**\n     * @inheritdoc ITokenMultiSigWallet\n     */\n    function revokeConfirmation(uint256 _transactionId)\n        public\n        onlyTokenOwner(msg.sender)\n        transactionExists(_transactionId)\n        transactionNotExcuted(_transactionId)\n    {\n        require(\n            isConfirmedBy(_transactionId, msg.sender),\n            \"TokenMultiSigWallet: not confirmed yet\"\n        );\n\n        Types.MultiSigConfirmation storage confirms = confirmations[_transactionId];\n        confirms.confirmedBy[msg.sender] = false;\n        confirms.confirmationCount -= getVotes(msg.sender);\n        emit ConfirmationRevoked(msg.sender, _transactionId);\n    }\n\n    /**\n     * @inheritdoc ITokenMultiSigWallet\n     */\n    function executeTransaction(uint256 _transactionId)\n        public\n        nonReentrant\n        transactionExists(_transactionId)\n        transactionNotExcuted(_transactionId)\n    {\n        require(isConfirmed(_transactionId), \"TokenMultiSigWallet: quorum not reached\");\n\n        Types.MultiSigTransaction storage txn = transactions[_transactionId];\n        txn.executed = true;\n        bool success = SafeCall.call(txn.target, gasleft(), txn.value, txn.data);\n        require(success, \"TokenMultiSigWallet: call transaction failed\");\n        emit TransactionExecuted(msg.sender, _transactionId);\n    }\n\n    /**\n     * @inheritdoc ITokenMultiSigWallet\n     */\n    function isConfirmed(uint256 _transactionId) public view returns (bool) {\n        return confirmations[_transactionId].confirmationCount >= quorum();\n    }\n\n    /**\n     * @inheritdoc ITokenMultiSigWallet\n     */\n    function quorum() public view returns (uint256) {\n        uint256 currentTimepoint = clock() - 1;\n        return\n            (IERC5805Upgradeable(address(GOVERNOR.token())).getPastTotalSupply(currentTimepoint) *\n                GOVERNOR.quorumNumerator(currentTimepoint)) / GOVERNOR.quorumDenominator();\n    }\n\n    /**\n     * @inheritdoc ITokenMultiSigWallet\n     */\n    function getVotes(address account) public view returns (uint256) {\n        return IERC5805Upgradeable(address(GOVERNOR.token())).getVotes(account);\n    }\n\n    /**\n     * @inheritdoc ITokenMultiSigWallet\n     */\n    function isConfirmedBy(uint256 _transactionId, address _account) public view returns (bool) {\n        return confirmations[_transactionId].confirmedBy[_account];\n    }\n\n    /**\n     * @inheritdoc ITokenMultiSigWallet\n     */\n    function getConfirmationCount(uint256 _transactionId) public view returns (uint256) {\n        return confirmations[_transactionId].confirmationCount;\n    }\n\n    /**\n     * @notice Generate id of the transaction.\n     *\n     * @param _target Transaction target address.\n     * @param _value  Transaction ether value.\n     * @param _data   Transaction data payload.\n     *\n     * @return Generated transaction id.\n     */\n    function generateTransactionId(\n        address _target,\n        uint256 _value,\n        bytes memory _data\n    ) public view validAddress(_target) returns (uint256) {\n        return uint256(keccak256(abi.encode(_target, _value, _data, clock())));\n    }\n\n    /**\n     * @dev Clock (as specified in EIP-6372) is set to match the token's clock.\n     *      Fallback to block numbers if the token does not implement EIP-6372.\n     */\n    function clock() public view returns (uint48) {\n        try IERC5805Upgradeable(address(GOVERNOR.token())).clock() returns (uint48 timepoint) {\n            return timepoint;\n        } catch {\n            return SafeCastUpgradeable.toUint48(block.number);\n        }\n    }\n}\n"
      },
      "contracts/L1/ResourceMetering.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\n\n/**\n * @custom:upgradeable\n * @title ResourceMetering\n * @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing\n *         updates automatically based on current demand.\n */\nabstract contract ResourceMetering is Initializable {\n    /**\n     * @notice Represents the various parameters that control the way in which resources are\n     *         metered. Corresponds to the EIP-1559 resource metering system.\n     *\n     * @custom:field prevBaseFee   Base fee from the previous block(s).\n     * @custom:field prevBoughtGas Amount of gas bought so far in the current block.\n     * @custom:field prevBlockNum  Last block number that the base fee was updated.\n     */\n    struct ResourceParams {\n        uint128 prevBaseFee;\n        uint64 prevBoughtGas;\n        uint64 prevBlockNum;\n    }\n\n    /**\n     * @notice Represents the configuration for the EIP-1559 based curve for the deposit gas\n     *         market. These values should be set with care as it is possible to set them in\n     *         a way that breaks the deposit gas market. The target resource limit is defined as\n     *         maxResourceLimit / elasticityMultiplier. This struct was designed to fit within a\n     *         single word. There is additional space for additions in the future.\n     *\n     * @custom:field maxResourceLimit             Represents the maximum amount of deposit gas that\n     *                                            can be purchased per block.\n     * @custom:field elasticityMultiplier         Determines the target resource limit along with\n     *                                            the resource limit.\n     * @custom:field baseFeeMaxChangeDenominator  Determines max change on fee per block.\n     * @custom:field minimumBaseFee               The min deposit base fee, it is clamped to this\n     *                                            value.\n     * @custom:field systemTxMaxGas               The amount of gas supplied to the system\n     *                                            transaction. This should be set to the same number\n     *                                            that the kroma-node sets as the gas limit for the\n     *                                            system transaction.\n     * @custom:field maximumBaseFee               The max deposit base fee, it is clamped to this\n     *                                            value.\n     */\n    struct ResourceConfig {\n        uint32 maxResourceLimit;\n        uint8 elasticityMultiplier;\n        uint8 baseFeeMaxChangeDenominator;\n        uint32 minimumBaseFee;\n        uint32 systemTxMaxGas;\n        uint128 maximumBaseFee;\n    }\n\n    /**\n     * @notice EIP-1559 style gas parameters.\n     */\n    ResourceParams public params;\n\n    /**\n     * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n     */\n    uint256[48] private __gap;\n\n    /**\n     * @notice Meters access to a function based an amount of a requested resource.\n     *\n     * @param _amount Amount of the resource requested.\n     */\n    modifier metered(uint64 _amount) {\n        // Record initial gas amount so we can refund for it later.\n        uint256 initialGas = gasleft();\n\n        // Run the underlying function.\n        _;\n\n        // Run the metering function.\n        _metered(_amount, initialGas);\n    }\n\n    /**\n     * @notice An internal function that holds all of the logic for metering a resource.\n     *\n     * @param _amount     Amount of the resource requested.\n     * @param _initialGas The amount of gas before any modifier execution.\n     */\n    function _metered(uint64 _amount, uint256 _initialGas) internal {\n        // Update block number and base fee if necessary.\n        uint256 blockDiff = block.number - params.prevBlockNum;\n\n        ResourceConfig memory config = _resourceConfig();\n        int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) /\n            int256(uint256(config.elasticityMultiplier));\n\n        if (blockDiff > 0) {\n            // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate\n            // at which deposits can be created and therefore limit the potential for deposits to\n            // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.\n            int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;\n            int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /\n                (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));\n\n            // Update base fee by adding the base fee delta and clamp the resulting value between\n            // min and max.\n            int256 newBaseFee = Arithmetic.clamp({\n                _value: int256(uint256(params.prevBaseFee)) + baseFeeDelta,\n                _min: int256(uint256(config.minimumBaseFee)),\n                _max: int256(uint256(config.maximumBaseFee))\n            });\n\n            // If we skipped more than one block, we also need to account for every empty block.\n            // Empty block means there was no demand for deposits in that block, so we should\n            // reflect this lack of demand in the fee.\n            if (blockDiff > 1) {\n                // Update the base fee by repeatedly applying the exponent 1-(1/change_denominator)\n                // blockDiff - 1 times. Simulates multiple empty blocks. Clamp the resulting value\n                // between min and max.\n                newBaseFee = Arithmetic.clamp({\n                    _value: Arithmetic.cdexp({\n                        _coefficient: newBaseFee,\n                        _denominator: int256(uint256(config.baseFeeMaxChangeDenominator)),\n                        _exponent: int256(blockDiff - 1)\n                    }),\n                    _min: int256(uint256(config.minimumBaseFee)),\n                    _max: int256(uint256(config.maximumBaseFee))\n                });\n            }\n\n            // Update new base fee, reset bought gas, and update block number.\n            params.prevBaseFee = uint128(uint256(newBaseFee));\n            params.prevBoughtGas = 0;\n            params.prevBlockNum = uint64(block.number);\n        }\n\n        // Make sure we can actually buy the resource amount requested by the user.\n        params.prevBoughtGas += _amount;\n        require(\n            int256(uint256(params.prevBoughtGas)) <= int256(uint256(config.maxResourceLimit)),\n            \"ResourceMetering: cannot buy more gas than available gas limit\"\n        );\n\n        // Determine the amount of ETH to be paid.\n        uint256 resourceCost = uint256(_amount) * uint256(params.prevBaseFee);\n\n        // We currently charge for this ETH amount as an L1 gas burn, so we convert the ETH amount\n        // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid\n        // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during\n        // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei\n        // during any 1 day period in the last 5 years, so should be fine.\n        uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei);\n\n        // Give the user a refund based on the amount of gas they used to do all of the work up to\n        // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts\n        // effectively like a dynamic stipend (with a minimum value).\n        uint256 usedGas = _initialGas - gasleft();\n        if (gasCost > usedGas) {\n            Burn.gas(gasCost - usedGas);\n        }\n    }\n\n    /**\n     * @notice Virtual function that returns the resource config. Contracts that inherit this\n     *         contract must implement this function.\n     *\n     * @return ResourceConfig\n     */\n    function _resourceConfig() internal virtual returns (ResourceConfig memory);\n\n    /**\n     * @notice Sets initial resource parameter values. This function must either be called by the\n     *         initializer function of an upgradeable child contract.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function __ResourceMetering_init() internal onlyInitializing {\n        params = ResourceParams({\n            prevBaseFee: 1 gwei,\n            prevBoughtGas: 0,\n            prevBlockNum: uint64(block.number)\n        });\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == _ENTERED;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "contracts/libraries/SafeCall.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n    /**\n     * @notice Perform a low level call without copying any returndata\n     *\n     * @param _target   Address to call\n     * @param _gas      Amount of gas to pass to the call\n     * @param _value    Amount of value to pass to the call\n     * @param _calldata Calldata to pass to the call\n     */\n    function call(\n        address _target,\n        uint256 _gas,\n        uint256 _value,\n        bytes memory _calldata\n    ) internal returns (bool) {\n        bool _success;\n        assembly {\n            _success := call(\n                _gas, // gas\n                _target, // recipient\n                _value, // ether value\n                add(_calldata, 32), // inloc\n                mload(_calldata), // inlen\n                0, // outloc\n                0 // outlen\n            )\n        }\n        return _success;\n    }\n\n    /**\n     * @notice Helper function to determine if there is sufficient gas remaining within the context\n     *         to guarantee that the minimum gas requirement for a call will be met as well as\n     *         optionally reserving a specified amount of gas for after the call has concluded.\n     *\n     * @param _minGas      The minimum amount of gas that may be passed to the target context.\n     * @param _reservedGas Optional amount of gas to reserve for the caller after the execution\n     *                     of the target context.\n     *\n     * @return `true` if there is enough gas remaining to safely supply `_minGas` to the target\n     *         context as well as reserve `_reservedGas` for the caller after the execution of\n     *         the target context.\n     *\n     * @dev !!!!! FOOTGUN ALERT !!!!!\n     *      1.) The 40_000 base buffer is to account for the worst case of the dynamic cost of the\n     *          `CALL` opcode's `address_access_cost`, `positive_value_cost`, and\n     *          `value_to_empty_account_cost` factors with an added buffer of 5,700 gas. It is\n     *          still possible to self-rekt by initiating a withdrawal with a minimum gas limit\n     *          that does not account for the `memory_expansion_cost` & `code_execution_cost`\n     *          factors of the dynamic cost of the `CALL` opcode.\n     *      2.) This function should *directly* precede the external call if possible. There is an\n     *          added buffer to account for gas consumed between this check and the call, but it\n     *          is only 5,700 gas.\n     *      3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call\n     *          frame may be passed to a subcontext, we need to ensure that the gas will not be\n     *          truncated.\n     *      4.) Use wisely. This function is not a silver bullet.\n     */\n    function hasMinGas(uint256 _minGas, uint256 _reservedGas) internal view returns (bool) {\n        bool _hasMinGas;\n        assembly {\n            // Equation: gas × 63 ≥ minGas × 64 + 63(40_000 + reservedGas)\n            _hasMinGas := iszero(\n                lt(mul(gas(), 63), add(mul(_minGas, 64), mul(add(40000, _reservedGas), 63)))\n            )\n        }\n        return _hasMinGas;\n    }\n\n    /**\n     * @notice Perform a low level call without copying any returndata. This function\n     *         will revert if the call cannot be performed with the specified minimum\n     *         gas.\n     *\n     * @param _target   Address to call\n     * @param _minGas   The minimum amount of gas that may be passed to the call\n     * @param _value    Amount of value to pass to the call\n     * @param _calldata Calldata to pass to the call\n     */\n    function callWithMinGas(\n        address _target,\n        uint256 _minGas,\n        uint256 _value,\n        bytes memory _calldata\n    ) internal returns (bool) {\n        bool _success;\n        bool _hasMinGas = hasMinGas(_minGas, 0);\n        assembly {\n            // Assertion: gasleft() >= (_minGas * 64) / 63 + 40_000\n            if iszero(_hasMinGas) {\n                // Store the \"Error(string)\" selector in scratch space.\n                mstore(0, 0x08c379a0)\n                // Store the pointer to the string length in scratch space.\n                mstore(32, 32)\n                // Store the string.\n                //\n                // SAFETY:\n                // - We pad the beginning of the string with two zero bytes as well as the\n                // length (24) to ensure that we override the free memory pointer at offset\n                // 0x40. This is necessary because the free memory pointer is likely to\n                // be greater than 1 byte when this function is called, but it is incredibly\n                // unlikely that it will be greater than 3 bytes. As for the data within\n                // 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.\n                // - It's fine to clobber the free memory pointer, we're reverting.\n                mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)\n\n                // Revert with 'Error(\"SafeCall: Not enough gas\")'\n                revert(28, 100)\n            }\n\n            // The call will be supplied at least ((_minGas * 64) / 63 + 40_000 - 49) gas due to the\n            // above assertion. This ensures that, in all circumstances (except for when the\n            // `_minGas` does not account for the `memory_expansion_cost` and `code_execution_cost`\n            // factors of the dynamic cost of the `CALL` opcode), the call will receive at least\n            // the minimum amount of gas specified.\n            _success := call(\n                gas(), // gas\n                _target, // recipient\n                _value, // ether value\n                add(_calldata, 32), // inloc\n                mload(_calldata), // inlen\n                0x00, // outloc\n                0x00 // outlen\n            )\n        }\n        return _success;\n    }\n}\n"
      },
      "contracts/L2/ValidatorRewardVault.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\nimport { ISemver } from \"../universal/ISemver.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000008\n * @title ValidatorRewardVault\n * @notice The ValidatorRewardVault accumulates transaction fees and pays rewards to validators.\n */\ncontract ValidatorRewardVault is FeeVault, ISemver {\n    /**\n     * @notice Address of the ValidatorPool contract on L1.\n     */\n    address public immutable VALIDATOR_POOL;\n\n    /**\n     * @notice A value to divide the vault balance by when determining the reward amount.\n     */\n    uint256 public immutable REWARD_DIVIDER;\n\n    /**\n     * @notice The reward balance that the validator is eligible to receive.\n     */\n    mapping(address => uint256) internal rewards;\n\n    /**\n     * @notice A mapping of whether the reward corresponding to the L2 block number has been paid.\n     */\n    mapping(uint256 => bool) internal isPaid;\n\n    /**\n     * @notice The amount of determined as rewards.\n     */\n    uint256 public totalReserved;\n\n    /**\n     * @notice Emitted when the balance of a validator has increased.\n     *\n     * @param validator     Address of the validator.\n     * @param l2BlockNumber The L2 block number of the output root.\n     * @param amount        Amount of the reward.\n     */\n    event Rewarded(address indexed validator, uint256 indexed l2BlockNumber, uint256 amount);\n\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.0.0\n     */\n    string public constant version = \"1.0.0\";\n\n    /**\n     * @notice Constructs the ValidatorRewardVault contract.\n     *\n     * @param _validatorPool Address of the ValidatorPool contract on L1.\n     * @param _rewardDivider A value to divide the vault balance by when determining the reward amount.\n     */\n    constructor(address _validatorPool, uint256 _rewardDivider) FeeVault(address(0), 0) {\n        VALIDATOR_POOL = _validatorPool;\n        REWARD_DIVIDER = _rewardDivider;\n    }\n\n    /**\n     * @notice Rewards the validator for submitting the output.\n     *         ValidatorPool contract on L1 calls this function over the portal when output is finalized.\n     *\n     * @param _validator     Address of the validator.\n     * @param _l2BlockNumber The L2 block number of the output root.\n     */\n    function reward(address _validator, uint256 _l2BlockNumber) external {\n        require(\n            AddressAliasHelper.undoL1ToL2Alias(msg.sender) == VALIDATOR_POOL,\n            \"ValidatorRewardVault: function can only be called from the ValidatorPool\"\n        );\n\n        require(_validator != address(0), \"ValidatorRewardVault: validator address cannot be 0\");\n\n        require(\n            !isPaid[_l2BlockNumber],\n            \"ValidatorRewardVault: the reward has already been paid for the L2 block number\"\n        );\n\n        uint256 amount = _determineRewardAmount();\n\n        unchecked {\n            totalReserved += amount;\n            rewards[_validator] += amount;\n        }\n\n        isPaid[_l2BlockNumber] = true;\n\n        emit Rewarded(_validator, _l2BlockNumber, amount);\n    }\n\n    /**\n     * @notice Checks if the withdrawal is possible, and returns the withdrawal amount.\n     *         When a withdrawal is available, it resets the balance and updates the total processed amount.\n     */\n    function _processWithdrawal() internal override returns (uint256) {\n        uint256 amount = rewards[msg.sender];\n        require(\n            amount >= MIN_WITHDRAWAL_AMOUNT,\n            \"ValidatorRewardVault: withdrawal amount must be greater than minimum withdrawal amount\"\n        );\n\n        rewards[msg.sender] = 0;\n        unchecked {\n            totalReserved -= amount;\n            totalProcessed += amount;\n        }\n\n        emit Withdrawal(amount, msg.sender, msg.sender);\n        return amount;\n    }\n\n    /**\n     * @notice Withdraws all of the sender's balance.\n     *         Reverts if the balance is less than the minimum withdrawal amount.\n     */\n    function withdraw() external override {\n        uint256 amount = _processWithdrawal();\n\n        L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: amount }(\n            msg.sender,\n            WITHDRAWAL_MIN_GAS,\n            bytes(\"\")\n        );\n    }\n\n    /**\n     * @notice Withdraws all of the sender's balance to L2.\n     *         Reverts if the balance is less than the minimum withdrawal amount.\n     */\n    function withdrawToL2() external override {\n        uint256 amount = _processWithdrawal();\n\n        bool success = SafeCall.call(msg.sender, gasleft(), amount, bytes(\"\"));\n        require(success, \"ValidatorRewardVault: ETH transfer failed\");\n    }\n\n    /**\n     * @notice Determines the reward amount.\n     *\n     * @return Amount of the reward.\n     */\n    function _determineRewardAmount() internal view returns (uint256) {\n        return (address(this).balance - totalReserved) / REWARD_DIVIDER;\n    }\n\n    /**\n     * @notice Returns the reward balance of the given address.\n     *\n     * @param _addr Address to lookup.\n     *\n     * @return The reward balance of the given address.\n     */\n    function balanceOf(address _addr) external view returns (uint256) {\n        return rewards[_addr];\n    }\n}\n"
      },
      "contracts/L1/KromaPortal.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\n\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ISemver } from \"../universal/ISemver.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\nimport { SystemConfig } from \"./SystemConfig.sol\";\nimport { ZKMerkleTrie } from \"./ZKMerkleTrie.sol\";\n\n/**\n * @custom:proxied\n * @title KromaPortal\n * @notice The KromaPortal is a low-level contract responsible for passing messages between L1\n *         and L2. Messages sent directly to the KromaPortal have no form of replayability.\n *         Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.\n */\ncontract KromaPortal is Initializable, ResourceMetering, ISemver {\n    /**\n     * @notice Represents a proven withdrawal.\n     *\n     * @custom:field outputRoot    Root of the L2 output this was proven against.\n     * @custom:field timestamp     Timestamp at whcih the withdrawal was proven.\n     * @custom:field l2OutputIndex Index of the output this was proven against.\n     */\n    struct ProvenWithdrawal {\n        bytes32 outputRoot;\n        uint128 timestamp;\n        uint128 l2OutputIndex;\n    }\n\n    /**\n     * @notice Version of the deposit event.\n     */\n    uint256 internal constant DEPOSIT_VERSION = 0;\n\n    /**\n     * @notice The L2 gas limit set when eth is deposited using the receive() function.\n     */\n    uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n    /**\n     * @notice Address of the L2OutputOracle contract.\n     */\n    L2OutputOracle public immutable L2_ORACLE;\n\n    /**\n     * @notice Address of the ValidatorPool contract.\n     */\n    address public immutable VALIDATOR_POOL;\n\n    /**\n    /**\n     * @notice Address of the SystemConfig contract.\n     */\n    SystemConfig public immutable SYSTEM_CONFIG;\n\n    /**\n     * @notice MultiSig wallet address that has the ability to pause and unpause withdrawals.\n     */\n    address public immutable GUARDIAN;\n\n    /**\n     * @notice Address of the ZKMerkleTrie.\n     */\n    ZKMerkleTrie public immutable ZK_MERKLE_TRIE;\n\n    /**\n     * @notice Address of the L2 account which initiated a withdrawal in this transaction. If the\n     *         of this variable is the default L2 sender address, then we are NOT inside of a call\n     *         to finalizeWithdrawalTransaction.\n     */\n    address public l2Sender;\n\n    /**\n     * @notice A list of withdrawal hashes which have been successfully finalized.\n     */\n    mapping(bytes32 => bool) public finalizedWithdrawals;\n\n    /**\n     * @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data.\n     */\n    mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals;\n\n    /**\n     * @notice Determines if cross domain messaging is paused. When set to true,\n     *         withdrawals are paused. This may be removed in the future.\n     */\n    bool public paused;\n\n    /**\n     * @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event\n     *         are read by the rollup node and used to derive deposit transactions on L2.\n     *\n     * @param from       Address that triggered the deposit transaction.\n     * @param to         Address that the deposit transaction is directed to.\n     * @param version    Version of this deposit transaction event.\n     * @param opaqueData ABI encoded deposit data to be parsed off-chain.\n     */\n    event TransactionDeposited(\n        address indexed from,\n        address indexed to,\n        uint256 indexed version,\n        bytes opaqueData\n    );\n\n    /**\n     * @notice Emitted when a withdrawal transaction is proven.\n     *\n     * @param withdrawalHash Hash of the withdrawal transaction.\n     */\n    event WithdrawalProven(\n        bytes32 indexed withdrawalHash,\n        address indexed from,\n        address indexed to\n    );\n\n    /**\n     * @notice Emitted when a withdrawal transaction is finalized.\n     *\n     * @param withdrawalHash Hash of the withdrawal transaction.\n     * @param success        Whether the withdrawal transaction was successful.\n     */\n    event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n\n    /**\n     * @notice Emitted when the pause is triggered.\n     *\n     * @param account Address of the account triggering the pause.\n     */\n    event Paused(address account);\n\n    /**\n     * @notice Emitted when the pause is lifted.\n     *\n     * @param account Address of the account triggering the unpause.\n     */\n    event Unpaused(address account);\n\n    /**\n     * @notice Reverts when paused.\n     */\n    modifier whenNotPaused() {\n        require(paused == false, \"KromaPortal: paused\");\n        _;\n    }\n\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.0.0\n     */\n    string public constant version = \"1.0.0\";\n\n    /**\n     * @notice Constructs the KromaPortal contract.\n     *\n     * @param _l2Oracle                  Address of the L2OutputOracle contract.\n     * @param _validatorPool             Address of the ValidatorPool contract.\n     * @param _guardian                  MultiSig wallet address that can pause deposits and withdrawals.\n     * @param _paused                    Sets the contract's pausability state.\n     * @param _config                    Address of the SystemConfig contract.\n     * @param _zkMerkleTrie              Address of the ZKMerkleTrie contract.\n     */\n    constructor(\n        L2OutputOracle _l2Oracle,\n        address _validatorPool,\n        address _guardian,\n        bool _paused,\n        SystemConfig _config,\n        ZKMerkleTrie _zkMerkleTrie\n    ) {\n        L2_ORACLE = _l2Oracle;\n        VALIDATOR_POOL = _validatorPool;\n        GUARDIAN = _guardian;\n        SYSTEM_CONFIG = _config;\n        ZK_MERKLE_TRIE = _zkMerkleTrie;\n        initialize(_paused);\n    }\n\n    /**\n     * @notice Initializer.\n     */\n    function initialize(bool _paused) public initializer {\n        l2Sender = Constants.DEFAULT_L2_SENDER;\n        paused = _paused;\n        __ResourceMetering_init();\n    }\n\n    /**\n     * @notice Pause deposits and withdrawals.\n     */\n    function pause() external {\n        require(msg.sender == GUARDIAN, \"KromaPortal: only guardian can pause\");\n        paused = true;\n        emit Paused(msg.sender);\n    }\n\n    /**\n     * @notice Unpause deposits and withdrawals.\n     */\n    function unpause() external {\n        require(msg.sender == GUARDIAN, \"KromaPortal: only guardian can unpause\");\n        paused = false;\n        emit Unpaused(msg.sender);\n    }\n\n    /**\n     * @notice Accepts value so that users can send ETH directly to this contract and have the\n     *         funds be deposited to their address on L2. This is intended as a convenience\n     *         function for EOAs. Contracts should call the depositTransaction() function directly\n     *         otherwise any deposited funds will be lost due to address aliasing.\n     */\n    // solhint-disable-next-line ordering\n    receive() external payable {\n        depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes(\"\"));\n    }\n\n    /**\n     * @notice Getter for the resource config. Used internally by the ResourceMetering\n     *         contract. The SystemConfig is the source of truth for the resource config.\n     *\n     * @return ResourceMetering.ResourceConfig\n     */\n    function _resourceConfig()\n        internal\n        view\n        override\n        returns (ResourceMetering.ResourceConfig memory)\n    {\n        return SYSTEM_CONFIG.resourceConfig();\n    }\n\n    /**\n     * @notice Proves a withdrawal transaction.\n     *\n     * @param _tx              Withdrawal transaction to finalize.\n     * @param _l2OutputIndex   L2 output index to prove against.\n     * @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root.\n     * @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\n     */\n    function proveWithdrawalTransaction(\n        Types.WithdrawalTransaction memory _tx,\n        uint256 _l2OutputIndex,\n        Types.OutputRootProof calldata _outputRootProof,\n        bytes[] calldata _withdrawalProof\n    ) external whenNotPaused {\n        // Prevent users from creating a deposit transaction where this address is the message\n        // sender on L2. Because this is checked here, we do not need to check again in\n        // `finalizeWithdrawalTransaction`.\n        require(\n            _tx.target != address(this),\n            \"KromaPortal: you cannot send messages to the portal contract\"\n        );\n\n        // Get the output root and load onto the stack to prevent multiple mloads. This will\n        // revert if there is no output root for the given block number.\n        bytes32 outputRoot = L2_ORACLE.getL2Output(_l2OutputIndex).outputRoot;\n\n        // Verify that the output root can be generated with the elements in the proof.\n        require(\n            outputRoot == Hashing.hashOutputRootProof(_outputRootProof),\n            \"KromaPortal: invalid output root proof\"\n        );\n\n        // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.\n        bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n        ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n        // We generally want to prevent users from proving the same withdrawal multiple times\n        // because each successive proof will update the timestamp. A malicious user can take\n        // advantage of this to prevent other users from finalizing their withdrawal. However,\n        // since withdrawals are proven before an output root is finalized, we need to allow users\n        // to re-prove their withdrawal only in the case that the output root for their specified\n        // output index has been updated.\n        require(\n            provenWithdrawal.timestamp == 0 ||\n                L2_ORACLE.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot !=\n                provenWithdrawal.outputRoot,\n            \"KromaPortal: withdrawal hash has already been proven\"\n        );\n\n        // Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract.\n        // Refer to the Solidity documentation for more information on how storage layouts are\n        // computed for mappings.\n        bytes32 storageKey = keccak256(\n            abi.encode(\n                withdrawalHash,\n                uint256(0) // The withdrawals mapping is at the first slot in the layout.\n            )\n        );\n\n        // Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract\n        // on L2. If this is true, under the assumption that the ZKMerkleTrie contract does not have\n        // bugs, then we know that this withdrawal was actually triggered on L2 and can therefore\n        // be relayed on L1.\n        require(\n            ZK_MERKLE_TRIE.verifyInclusionProof(\n                storageKey,\n                hex\"0000000000000000000000000000000000000000000000000000000000000001\",\n                _withdrawalProof,\n                _outputRootProof.messagePasserStorageRoot\n            ),\n            \"KromaPortal: invalid withdrawal inclusion proof\"\n        );\n\n        // Designate the withdrawalHash as proven by storing the `outputRoot`, `timestamp`, and\n        // `l2OutputIndex` in the `provenWithdrawals` mapping. A `withdrawalHash` can only be\n        // proven once unless it is submitted again with a different outputRoot.\n        provenWithdrawals[withdrawalHash] = ProvenWithdrawal({\n            outputRoot: outputRoot,\n            timestamp: uint128(block.timestamp),\n            l2OutputIndex: uint128(_l2OutputIndex)\n        });\n\n        // Emit a `WithdrawalProven` event.\n        emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target);\n    }\n\n    /**\n     * @notice Finalizes a withdrawal transaction.\n     *\n     * @param _tx Withdrawal transaction to finalize.\n     */\n    function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx)\n        external\n        whenNotPaused\n    {\n        // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other\n        // than the default value when a withdrawal transaction is being finalized. This check is\n        // a defacto reentrancy guard.\n        require(\n            l2Sender == Constants.DEFAULT_L2_SENDER,\n            \"KromaPortal: can only trigger one withdrawal per transaction\"\n        );\n\n        // Grab the proven withdrawal from the `provenWithdrawals` map.\n        bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n        ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n        // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has\n        // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have\n        // a timestamp of zero.\n        require(provenWithdrawal.timestamp != 0, \"KromaPortal: withdrawal has not been proven yet\");\n\n        // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than\n        // starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of\n        // safety against weird bugs in the proving step.\n        require(\n            provenWithdrawal.timestamp >= L2_ORACLE.startingTimestamp(),\n            \"KromaPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n        );\n\n        // A proven withdrawal must wait at least the finalization period before it can be\n        // finalized. This waiting period can elapse in parallel with the waiting period for the\n        // output the withdrawal was proven against. In effect, this means that the minimum\n        // withdrawal time is l2 output submission time + finalization period.\n        require(\n            _isFinalizationPeriodElapsed(provenWithdrawal.timestamp),\n            \"KromaPortal: proven withdrawal finalization period has not elapsed\"\n        );\n\n        // Grab the CheckpointOutput from the L2OutputOracle, will revert if the output that\n        // corresponds to the given index has not been submitted yet.\n        Types.CheckpointOutput memory checkpointOutput = L2_ORACLE.getL2Output(\n            provenWithdrawal.l2OutputIndex\n        );\n\n        // Check that the output root that was used to prove the withdrawal is the same as the\n        // current output root for the given output index. An output root may change if it is\n        // deleted by the challenger address and then re-submitted.\n        require(\n            checkpointOutput.outputRoot == provenWithdrawal.outputRoot,\n            \"KromaPortal: output root proven is not the same as current output root\"\n        );\n\n        // Check that the checkpoint output has also been finalized.\n        require(\n            _isFinalizationPeriodElapsed(checkpointOutput.timestamp),\n            \"KromaPortal: checkpoint output finalization period has not elapsed\"\n        );\n\n        // Check that this withdrawal has not already been finalized, this is replay protection.\n        require(\n            finalizedWithdrawals[withdrawalHash] == false,\n            \"KromaPortal: withdrawal has already been finalized\"\n        );\n\n        // Mark the withdrawal as finalized so it can't be replayed.\n        finalizedWithdrawals[withdrawalHash] = true;\n\n        // Set the l2Sender so contracts know who triggered this withdrawal on L2.\n        l2Sender = _tx.sender;\n\n        // Trigger the call to the target contract. We use a custom low level method\n        // SafeCall.callWithMinGas to ensure two key properties\n        //   1. Target contracts cannot force this call to run out of gas by returning a very large\n        //      amount of data (and this is OK because we don't care about the returndata here).\n        //   2. The amount of gas provided to the execution context of the target is at least the\n        //      gas limit specified by the user. If there is not enough gas in the current context\n        //      to accomplish this, `callWithMinGas` will revert.\n        bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data);\n\n        // Reset the l2Sender back to the default value.\n        l2Sender = Constants.DEFAULT_L2_SENDER;\n\n        // All withdrawals are immediately finalized. Replayability can\n        // be achieved through contracts built on top of this contract\n        emit WithdrawalFinalized(withdrawalHash, success);\n\n        // Reverting here is useful for determining the exact gas cost to successfully execute the\n        // sub call to the target contract if the minimum gas limit specified by the user would not\n        // be sufficient to execute the sub call.\n        if (success == false && tx.origin == Constants.ESTIMATION_ADDRESS) {\n            revert(\"KromaPortal: withdrawal failed\");\n        }\n    }\n\n    /**\n     * @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in\n     *         deriving deposit transactions. Note that if a deposit is made by a contract, its\n     *         address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider\n     *         using the CrossDomainMessenger contracts for a simpler developer experience.\n     *\n     * @param _to         Target address on L2.\n     * @param _value      ETH value to send to the recipient.\n     * @param _gasLimit   Minimum L2 gas limit (can be greater than or equal to this value).\n     * @param _isCreation Whether or not the transaction is a contract creation.\n     * @param _data       Data to trigger the recipient with.\n     */\n    function depositTransaction(\n        address _to,\n        uint256 _value,\n        uint64 _gasLimit,\n        bool _isCreation,\n        bytes memory _data\n    ) public payable metered(_gasLimit) {\n        // Just to be safe, make sure that people specify address(0) as the target when doing\n        // contract creations.\n        if (_isCreation) {\n            require(\n                _to == address(0),\n                \"KromaPortal: must send to address(0) when creating a contract\"\n            );\n        }\n\n        // Prevent depositing transactions that have too small of a gas limit.\n        require(_gasLimit >= 21_000, \"KromaPortal: gas limit must cover instrinsic gas cost\");\n\n        // Transform the from-address to its alias if the caller is a contract.\n        address from = msg.sender;\n        if (msg.sender != tx.origin) {\n            from = AddressAliasHelper.applyL1ToL2Alias(msg.sender);\n        }\n\n        // Compute the opaque data that will be emitted as part of the TransactionDeposited event.\n        // We use opaque data so that we can update the TransactionDeposited event in the future\n        // without breaking the current interface.\n        bytes memory opaqueData = abi.encodePacked(\n            msg.value,\n            _value,\n            _gasLimit,\n            _isCreation,\n            _data\n        );\n\n        // Emit a TransactionDeposited event so that the rollup node can derive a deposit\n        // transaction for this deposit.\n        emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);\n    }\n\n    /**\n     * @notice Accepts deposits of data from ValidatorPool contract, and emits a TransactionDeposited event for use in\n     *         deriving deposit transactions on L2.\n     *\n     * @param _to         Target address on L2.\n     * @param _gasLimit   Minimum L2 gas limit (can be greater than or equal to this value).\n     * @param _data       Data to trigger the recipient with.\n     */\n    function depositTransactionByValidatorPool(\n        address _to,\n        uint64 _gasLimit,\n        bytes memory _data\n    ) public {\n        require(\n            msg.sender == VALIDATOR_POOL,\n            \"KromaPortal: function can only be called from the ValidatorPool\"\n        );\n\n        // Transform the from-address to its alias.\n        address from = AddressAliasHelper.applyL1ToL2Alias(msg.sender);\n\n        // Compute the opaque data that will be emitted as part of the TransactionDeposited event.\n        bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), _gasLimit, false, _data);\n\n        // Emit a TransactionDeposited event so that the rollup node can derive a deposit\n        // transaction for this deposit.\n        emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);\n    }\n\n    /**\n     * @notice Determines if the output at the given index is finalized. Reverts if the call to\n     *         L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\n     *\n     * @param _l2OutputIndex Index of the L2 output to check.\n     *\n     * @return Whether or not the output is finalized.\n     */\n    function isOutputFinalized(uint256 _l2OutputIndex) external view returns (bool) {\n        return _isFinalizationPeriodElapsed(L2_ORACLE.getL2Output(_l2OutputIndex).timestamp);\n    }\n\n    /**\n     * @notice Determines whether the finalization period has elapsed w/r/t a given timestamp.\n     *\n     * @param _timestamp Timestamp to check.\n     *\n     * @return Whether or not the finalization period has elapsed.\n     */\n    function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) {\n        return block.timestamp > _timestamp + L2_ORACLE.FINALIZATION_PERIOD_SECONDS();\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/interfaces/IERC5805Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5805.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../governance/utils/IVotesUpgradeable.sol\";\nimport \"./IERC6372Upgradeable.sol\";\n\ninterface IERC5805Upgradeable is IERC6372Upgradeable, IVotesUpgradeable {}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     *\n     * _Available since v4.2._\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     *\n     * _Available since v4.2._\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     *\n     * _Available since v3.0._\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: value must be positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     *\n     * _Available since v3.0._\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n        return int256(value);\n    }\n}\n"
      },
      "contracts/governance/UpgradeGovernor.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorCountingSimpleUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorTimelockControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\nimport { ISemver } from \"../universal/ISemver.sol\";\n\n/**\n * @custom:proxied\n * @title UpgradeGovernor\n * @notice The UpgradeGovernor is a basic ERC20, ERC721 based DAO using OpenZeppelin Governor.\n */\ncontract UpgradeGovernor is\n    Initializable,\n    GovernorUpgradeable,\n    GovernorSettingsUpgradeable,\n    GovernorCountingSimpleUpgradeable,\n    GovernorVotesUpgradeable,\n    GovernorVotesQuorumFractionUpgradeable,\n    GovernorTimelockControlUpgradeable,\n    ISemver\n{\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.0.0\n     */\n    string private constant _version = \"1.0.0\";\n\n    /**\n     * @notice Constructs the UpgradeGovernor contract.\n     */\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Initializer.\n     *\n     * @param _token                    Address of the token(ERC20 or ERC721).\n     * @param _timelock                 Address of the timelock controller.\n     * @param _initialVotingDelay       Voting delay.(unit: 1 block = 12 seconds on L1)\n     * @param _initialVotingPeriod      Voting period.(unit: 1 block = 12 seconds on L1)\n     * @param _initialProposalThreshold Proposal threshold.\n     * @param _votesQuorumFraction      Quorum as a fraction of the token's total supply.\n     */\n    function initialize(\n        address _token,\n        address payable _timelock,\n        uint256 _initialVotingDelay,\n        uint256 _initialVotingPeriod,\n        uint256 _initialProposalThreshold,\n        uint256 _votesQuorumFraction\n    ) public initializer {\n        __Governor_init(\"UpgradeGovernor\");\n        __GovernorSettings_init(\n            _initialVotingDelay,\n            _initialVotingPeriod,\n            _initialProposalThreshold\n        );\n        __GovernorCountingSimple_init();\n        __GovernorVotes_init(IVotesUpgradeable(_token));\n        __GovernorVotesQuorumFraction_init(_votesQuorumFraction);\n        __GovernorTimelockControl_init(TimelockControllerUpgradeable(_timelock));\n    }\n\n    // The following functions are overridden cause required by Solidity.\n\n    function votingDelay()\n        public\n        view\n        override(IGovernorUpgradeable, GovernorSettingsUpgradeable)\n        returns (uint256)\n    {\n        return super.votingDelay();\n    }\n\n    function votingPeriod()\n        public\n        view\n        override(IGovernorUpgradeable, GovernorSettingsUpgradeable)\n        returns (uint256)\n    {\n        return super.votingPeriod();\n    }\n\n    function quorum(uint256 blockNumber)\n        public\n        view\n        override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable)\n        returns (uint256)\n    {\n        return super.quorum(blockNumber);\n    }\n\n    function state(uint256 proposalId)\n        public\n        view\n        override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)\n        returns (ProposalState)\n    {\n        return super.state(proposalId);\n    }\n\n    function propose(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        string memory description\n    ) public override(GovernorUpgradeable, IGovernorUpgradeable) returns (uint256) {\n        return super.propose(targets, values, calldatas, description);\n    }\n\n    function proposalThreshold()\n        public\n        view\n        override(GovernorUpgradeable, GovernorSettingsUpgradeable)\n        returns (uint256)\n    {\n        return super.proposalThreshold();\n    }\n\n    /**\n     * @notice Returns the full contract version.\n     *\n     * @return contract version as a string.\n     */\n    function version()\n        public\n        pure\n        override(IGovernorUpgradeable, GovernorUpgradeable, ISemver)\n        returns (string memory)\n    {\n        return _version;\n    }\n\n    function _execute(\n        uint256 proposalId,\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) {\n        super._execute(proposalId, targets, values, calldatas, descriptionHash);\n    }\n\n    function _cancel(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256) {\n        return super._cancel(targets, values, calldatas, descriptionHash);\n    }\n\n    function _executor()\n        internal\n        view\n        override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)\n        returns (address)\n    {\n        return super._executor();\n    }\n\n    function supportsInterface(bytes4 interfaceId)\n        public\n        view\n        override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)\n        returns (bool)\n    {\n        return super.supportsInterface(interfaceId);\n    }\n}\n"
      },
      "contracts/universal/ITokenMultiSigWallet.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title ITokenMultiSigWallet\n * @notice Interface for contracts of a token based multi-signature wallet.\n */\ninterface ITokenMultiSigWallet {\n    /**\n     * @notice Emitted when anyone submit a transaction.\n     *\n     * @param sender        Address of submitter.\n     * @param transactionId The ID of transaction submitted.\n     */\n    event TransactionSubmitted(address indexed sender, uint256 indexed transactionId);\n\n    /**\n     * @notice Emitted when anyone confirm a transaction.\n     *\n     * @param sender        Owner of address that confirm a transaction.\n     * @param transactionId The ID of transaction confirmed.\n     */\n    event TransactionConfirmed(address indexed sender, uint256 indexed transactionId);\n\n    /**\n     * @notice Emitted when transaction is executed.\n     *\n     * @param sender        Owner of address that execute a transaction.\n     * @param transactionId The ID of transaction executed.\n     */\n    event TransactionExecuted(address indexed sender, uint256 indexed transactionId);\n\n    /**\n     * @notice Emitted when anyone revoke a confirmation.\n     *\n     * @param sender        Owner of address that revoke a transaction.\n     * @param transactionId The ID of transaction to revoke.\n     */\n    event ConfirmationRevoked(address indexed sender, uint256 indexed transactionId);\n\n    /**\n     * @notice Allows an owner to submit and confirm a transaction.\n     *\n     * @param _target Transaction target address.\n     * @param _value  Transaction ether value.\n     * @param _data   Transaction data payload.\n     *\n     * @return Returns transaction ID.\n     */\n    function submitTransaction(\n        address _target,\n        uint256 _value,\n        bytes memory _data\n    ) external returns (uint256);\n\n    /**\n     * @notice Allows an owner to confirm a transaction.\n     *\n     * @param _transactionId Transaction ID.\n     */\n    function confirmTransaction(uint256 _transactionId) external;\n\n    /**\n     * @notice Allows an owner to revoke a transaction.\n     *\n     * @param _transactionId Transaction ID.\n     */\n    function revokeConfirmation(uint256 _transactionId) external;\n\n    /**\n     * @notice Allows anyone to execute a confirmed transaction.\n     *\n     * @param _transactionId Transaction ID.\n     */\n    function executeTransaction(uint256 _transactionId) external;\n\n    /**\n     * @notice Returns the confirmation status of a transaction.\n     *\n     * @param _transactionId Transaction ID.\n     *\n     * @return Confirmation status.\n     */\n    function isConfirmed(uint256 _transactionId) external view returns (bool);\n\n    /**\n     * @notice Returns the current quorum, in terms of number of votes.\n     *\n     * @return Current quorum, in terms of number of votes: `supply * quorumNumerator / quorumDenominator`.\n     */\n    function quorum() external view returns (uint256);\n\n    /**\n     * @notice Returns the number of votes.\n     *\n     * @param _account Account to check votes.\n     *\n     * @return Number of votes.\n     */\n    function getVotes(address _account) external view returns (uint256);\n\n    /**\n     * @notice Returns the number of confirmations that account has confirmed.\n     *\n     * @param _transactionId Transaction id to check.\n     *\n     * @return The number of confirmations.\n     */\n    function getConfirmationCount(uint256 _transactionId) external view returns (uint256);\n\n    /**\n     * @notice Returns whether the account has confirmed the transaction.\n     *\n     * @param _transactionId Transaction id to check.\n     * @param _account       Address to check.\n     *\n     * @return Confirmed status.\n     */\n    function isConfirmedBy(uint256 _transactionId, address _account) external view returns (bool);\n}\n"
      },
      "contracts/libraries/Arithmetic.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { FixedPointMathLib } from \"@rari-capital/solmate/src/utils/FixedPointMathLib.sol\";\n\n/**\n * @title Arithmetic\n * @notice Even more math than before.\n */\nlibrary Arithmetic {\n    /**\n     * @notice Clamps a value between a minimum and maximum.\n     *\n     * @param _value The value to clamp.\n     * @param _min   The minimum value.\n     * @param _max   The maximum value.\n     *\n     * @return The clamped value.\n     */\n    function clamp(\n        int256 _value,\n        int256 _min,\n        int256 _max\n    ) internal pure returns (int256) {\n        return SignedMath.min(SignedMath.max(_value, _min), _max);\n    }\n\n    /**\n     * @notice Clamps a value between a minimum and maximum.\n     *\n     * @param _value The value to clamp.\n     * @param _min   The minimum value.\n     * @param _max   The maximum value.\n     *\n     * @return The clamped value.\n     */\n    function clamp(\n        uint256 _value,\n        uint256 _min,\n        uint256 _max\n    ) internal pure returns (uint256) {\n        return Math.min(Math.max(_value, _min), _max);\n    }\n\n    /**\n     * @notice (c)oefficient (d)enominator (exp)onentiation function.\n     *         Returns the result of: c * (1 - 1/d)^exp.\n     *\n     * @param _coefficient Coefficient of the function.\n     * @param _denominator Fractional denominator.\n     * @param _exponent    Power function exponent.\n     *\n     * @return Result of c * (1 - 1/d)^exp.\n     */\n    function cdexp(\n        int256 _coefficient,\n        int256 _denominator,\n        int256 _exponent\n    ) internal pure returns (int256) {\n        return\n            (_coefficient *\n                (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;\n    }\n}\n"
      },
      "contracts/libraries/Burn.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { SafeCall } from \"./SafeCall.sol\";\n\n/**\n * @title Burn\n * @notice Utilities for burning stuff.\n */\nlibrary Burn {\n    /**\n     * Burns a given amount of ETH.\n     * Note that execution engine of Kroma does not support SELFDESTRUCT opcode, so it sends ETH to zero address.\n     *\n     * @param _amount Amount of ETH to burn.\n     */\n    function eth(uint256 _amount) internal {\n        SafeCall.call(address(0), gasleft(), _amount, \"\");\n    }\n\n    /**\n     * Burns a given amount of gas.\n     *\n     * @param _amount Amount of gas to burn.\n     */\n    function gas(uint256 _amount) internal view {\n        uint256 i = 0;\n        uint256 initialGas = gasleft();\n        while (initialGas - gasleft() < _amount) {\n            ++i;\n        }\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: setting the version to 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _initializing;\n    }\n}\n"
      },
      "contracts/L2/L2StandardBridge.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { ISemver } from \"../universal/ISemver.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000009\n * @title L2StandardBridge\n * @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n *         L2. In the case that an ERC20 token is native to L2, it will be escrowed within this\n *         contract. If the ERC20 token is native to L1, it will be burnt.\n *         NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n *         of some token types that may not be properly supported by this contract include, but are\n *         not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L2StandardBridge is StandardBridge, ISemver {\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.0.0\n     */\n    string public constant version = \"1.0.0\";\n\n    /**\n     * @notice Constructs the L2StandardBridge contract.\n     *\n     * @param _otherBridge Address of the L1StandardBridge.\n     */\n    constructor(\n        address payable _otherBridge\n    ) StandardBridge(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge) {}\n\n    /**\n     * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n     */\n    receive() external payable override onlyEOA {\n        _initiateBridgeETH(\n            msg.sender,\n            msg.sender,\n            msg.value,\n            RECEIVE_DEFAULT_GAS_LIMIT,\n            bytes(\"\")\n        );\n    }\n}\n"
      },
      "contracts/universal/FeeVault.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\n/**\n * @title FeeVault\n * @notice The FeeVault contract contains the basic logic for the various different vault contracts\n *         used to hold fee revenue generated by the L2 system.\n */\nabstract contract FeeVault {\n    /**\n     * @notice Emits each time that a withdrawal occurs.\n     *\n     * @param value Amount that was withdrawn (in wei).\n     * @param to    Address that the funds were sent to.\n     * @param from  Address that triggered the withdrawal.\n     */\n    event Withdrawal(uint256 value, address to, address from);\n\n    /**\n     * @notice Minimum balance before a withdrawal can be triggered.\n     */\n    uint256 public immutable MIN_WITHDRAWAL_AMOUNT;\n\n    /**\n     * @notice Wallet that will receive the fees on L1.\n     */\n    address public immutable RECIPIENT;\n\n    /**\n     * @notice The minimum gas limit for the FeeVault withdrawal transaction.\n     */\n    uint32 internal constant WITHDRAWAL_MIN_GAS = 35_000;\n\n    /**\n     * @notice Total amount of wei processed by the contract.\n     */\n    uint256 public totalProcessed;\n\n    modifier onlyRecipient() {\n        require(msg.sender == RECIPIENT, \"FeeVault: the only recipient can call\");\n        _;\n    }\n\n    /**\n     * @param _recipient           Wallet that will receive the fees on L1.\n     * @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered.\n     */\n    constructor(address _recipient, uint256 _minWithdrawalAmount) {\n        MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;\n        RECIPIENT = _recipient;\n    }\n\n    /**\n     * @notice Allow the contract to receive ETH.\n     */\n    receive() external payable {}\n\n    /**\n     * @notice Checks if the withdrawal is possible, and returns the withdrawal amount.\n     *         When a withdrawal is available, it resets the balance and updates the total processed amount.\n     */\n    function _processWithdrawal() internal virtual returns (uint256) {\n        require(\n            address(this).balance >= MIN_WITHDRAWAL_AMOUNT,\n            \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n        );\n\n        uint256 amount = address(this).balance;\n        totalProcessed += amount;\n\n        emit Withdrawal(amount, RECIPIENT, msg.sender);\n        return amount;\n    }\n\n    /**\n     * @notice Triggers a withdrawal of funds to the recipient on L1.\n     */\n    function withdraw() external virtual onlyRecipient {\n        uint256 amount = _processWithdrawal();\n\n        L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: amount }(\n            RECIPIENT,\n            WITHDRAWAL_MIN_GAS,\n            bytes(\"\")\n        );\n    }\n\n    /**\n     * @notice Triggers a withdrawal of funds to the recipient on L2.\n     */\n    function withdrawToL2() external virtual onlyRecipient {\n        uint256 amount = _processWithdrawal();\n\n        bool success = SafeCall.call(RECIPIENT, gasleft(), amount, bytes(\"\"));\n        require(success, \"FeeVault: ETH transfer failed\");\n    }\n}\n"
      },
      "contracts/vendor/AddressAliasHelper.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.0;\n\nlibrary AddressAliasHelper {\n    uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n    /// @notice Utility function that converts the address in the L1 that submitted a tx to\n    /// the inbox to the msg.sender viewed in the L2\n    /// @param l1Address the address in the L1 that triggered the tx to L2\n    /// @return l2Address L2 address as viewed in msg.sender\n    function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {\n        unchecked {\n            l2Address = address(uint160(l1Address) + offset);\n        }\n    }\n\n    /// @notice Utility function that converts the msg.sender viewed in the L2 to the\n    /// address in the L1 that submitted a tx to the inbox\n    /// @param l2Address L2 address as viewed in msg.sender\n    /// @return l1Address the address in the L1 that triggered the tx to L2\n    function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {\n        unchecked {\n            l1Address = address(uint160(l2Address) - offset);\n        }\n    }\n}\n"
      },
      "contracts/L1/SystemConfig.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n    OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { ISemver } from \"../universal/ISemver.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\n\n/**\n * @title SystemConfig\n * @notice The SystemConfig contract is used to manage configuration of a Kroma network. All\n *         configuration is stored on L1 and picked up by L2 as part of the derivation of the L2\n *         chain.\n */\ncontract SystemConfig is OwnableUpgradeable, ISemver {\n    /**\n     * @notice Enum representing different types of updates.\n     *\n     * @custom:value BATCHER                 Represents an update to the batcher hash.\n     * @custom:value GAS_CONFIG              Represents an update to txn fee config on L2.\n     * @custom:value GAS_LIMIT               Represents an update to gas limit on L2.\n     * @custom:value UNSAFE_BLOCK_SIGNER     Represents an update to the signer key for unsafe\n     *                                       block distribution.\n     * @custom:value VALIDATOR_REWARD_SCALAR Represents an update to validator reward scalar.\n     */\n    enum UpdateType {\n        BATCHER,\n        GAS_CONFIG,\n        GAS_LIMIT,\n        UNSAFE_BLOCK_SIGNER,\n        VALIDATOR_REWARD_SCALAR\n    }\n\n    /**\n     * @notice Version identifier, used for upgrades.\n     */\n    uint256 public constant VERSION = 0;\n\n    /**\n     * @notice Storage slot that the unsafe block signer is stored at. Storing it at this\n     *         deterministic storage slot allows for decoupling the storage layout from the way\n     *         that `solc` lays out storage. The `kroma-node` uses a storage proof to fetch this value.\n     */\n    bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256(\"systemconfig.unsafeblocksigner\");\n\n    /**\n     * @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation.\n     */\n    uint256 public overhead;\n\n    /**\n     * @notice Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\n     */\n    uint256 public scalar;\n\n    /**\n     * @notice Identifier for the batcher. For version 1 of this configuration, this is represented\n     *         as an address left-padded with zeros to 32 bytes.\n     */\n    bytes32 public batcherHash;\n\n    /**\n     * @notice L2 block gas limit.\n     */\n    uint64 public gasLimit;\n\n    /**\n     * @notice The configuration for the deposit fee market. Used by the KromaPortal\n     *         to meter the cost of buying L2 gas on L1. Set as internal and wrapped with a getter\n     *         so that the struct is returned instead of a tuple.\n     */\n    ResourceMetering.ResourceConfig internal _resourceConfig;\n\n    /**\n     * @notice The scalar value to distribute transaction fees as validator reward.\n     *         The denominator is 10000, so the ratio is expressed in 4 decimal places.\n     */\n    uint256 public validatorRewardScalar;\n\n    /**\n     * @notice Emitted when configuration is updated\n     *\n     * @param version    SystemConfig version.\n     * @param updateType Type of update.\n     * @param data       Encoded update data.\n     */\n    event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);\n\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.0.0\n     */\n    string public constant version = \"1.0.0\";\n\n    /**\n     * @notice Constructs the SystemConfig contract.\n     *\n     * @param _owner                 Initial owner of the contract.\n     * @param _overhead              Initial overhead value.\n     * @param _scalar                Initial scalar value.\n     * @param _batcherHash           Initial batcher hash.\n     * @param _gasLimit              Initial gas limit.\n     * @param _unsafeBlockSigner     Initial unsafe block signer address.\n     * @param _config                Initial resource config.\n     * @param _validatorRewardScalar Initial validator reward scalar.\n     */\n    constructor(\n        address _owner,\n        uint256 _overhead,\n        uint256 _scalar,\n        bytes32 _batcherHash,\n        uint64 _gasLimit,\n        address _unsafeBlockSigner,\n        ResourceMetering.ResourceConfig memory _config,\n        uint256 _validatorRewardScalar\n    ) {\n        initialize(\n            _owner,\n            _overhead,\n            _scalar,\n            _batcherHash,\n            _gasLimit,\n            _unsafeBlockSigner,\n            _config,\n            _validatorRewardScalar\n        );\n    }\n\n    /**\n     * @notice Initializer. The resource config must be set before the\n     *         require check.\n     *\n     * @param _owner                 Initial owner of the contract.\n     * @param _overhead              Initial overhead value.\n     * @param _scalar                Initial scalar value.\n     * @param _batcherHash           Initial batcher hash.\n     * @param _gasLimit              Initial gas limit.\n     * @param _unsafeBlockSigner     Initial unsafe block signer address.\n     * @param _config                Initial ResourceConfig.\n     * @param _validatorRewardScalar Initial validator reward scalar.\n     */\n    function initialize(\n        address _owner,\n        uint256 _overhead,\n        uint256 _scalar,\n        bytes32 _batcherHash,\n        uint64 _gasLimit,\n        address _unsafeBlockSigner,\n        ResourceMetering.ResourceConfig memory _config,\n        uint256 _validatorRewardScalar\n    ) public initializer {\n        __Ownable_init();\n        transferOwnership(_owner);\n        overhead = _overhead;\n        scalar = _scalar;\n        batcherHash = _batcherHash;\n        gasLimit = _gasLimit;\n        _setUnsafeBlockSigner(_unsafeBlockSigner);\n        _setResourceConfig(_config);\n        require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n        validatorRewardScalar = _validatorRewardScalar;\n    }\n\n    /**\n     * @notice Returns the minimum L2 gas limit that can be safely set for the system to\n     *         operate. The L2 gas limit must be larger than or equal to the amount of\n     *         gas that is allocated for deposits per block plus the amount of gas that\n     *         is allocated for the system transaction.\n     *         This function is used to determine if changes to parameters are safe.\n     *\n     * @return uint64\n     */\n    function minimumGasLimit() public view returns (uint64) {\n        return uint64(_resourceConfig.maxResourceLimit) + uint64(_resourceConfig.systemTxMaxGas);\n    }\n\n    /**\n     * @notice High level getter for the unsafe block signer address. Unsafe blocks can be\n     *         propagated across the p2p network if they are signed by the key corresponding to\n     *         this address.\n     *\n     * @return Address of the unsafe block signer.\n     */\n    // solhint-disable-next-line ordering\n    function unsafeBlockSigner() external view returns (address) {\n        address addr;\n        bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n        assembly {\n            addr := sload(slot)\n        }\n        return addr;\n    }\n\n    /**\n     * @notice Updates the unsafe block signer address.\n     *\n     * @param _unsafeBlockSigner New unsafe block signer address.\n     */\n    function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner {\n        _setUnsafeBlockSigner(_unsafeBlockSigner);\n\n        bytes memory data = abi.encode(_unsafeBlockSigner);\n        emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data);\n    }\n\n    /**\n     * @notice Updates the batcher hash.\n     *\n     * @param _batcherHash New batcher hash.\n     */\n    function setBatcherHash(bytes32 _batcherHash) external onlyOwner {\n        batcherHash = _batcherHash;\n\n        bytes memory data = abi.encode(_batcherHash);\n        emit ConfigUpdate(VERSION, UpdateType.BATCHER, data);\n    }\n\n    /**\n     * @notice Updates gas config.\n     *\n     * @param _overhead New overhead value.\n     * @param _scalar   New scalar value.\n     */\n    function setGasConfig(uint256 _overhead, uint256 _scalar) external onlyOwner {\n        overhead = _overhead;\n        scalar = _scalar;\n\n        bytes memory data = abi.encode(_overhead, _scalar);\n        emit ConfigUpdate(VERSION, UpdateType.GAS_CONFIG, data);\n    }\n\n    /**\n     * @notice Updates the L2 gas limit.\n     *\n     * @param _gasLimit New gas limit.\n     */\n    function setGasLimit(uint64 _gasLimit) external onlyOwner {\n        require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n        gasLimit = _gasLimit;\n\n        bytes memory data = abi.encode(_gasLimit);\n        emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data);\n    }\n\n    /**\n     * @notice Low level setter for the unsafe block signer address. This function exists to\n     *         deduplicate code around storing the unsafeBlockSigner address in storage.\n     *\n     * @param _unsafeBlockSigner New unsafeBlockSigner value.\n     */\n    function _setUnsafeBlockSigner(address _unsafeBlockSigner) internal {\n        bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n        assembly {\n            sstore(slot, _unsafeBlockSigner)\n        }\n    }\n\n    /**\n     * @notice A getter for the resource config. Ensures that the struct is\n     *         returned instead of a tuple.\n     *\n     * @return ResourceConfig\n     */\n    function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory) {\n        return _resourceConfig;\n    }\n\n    /**\n     * @notice An external setter for the resource config. In the future, this\n     *         method may emit an event that the `kroma-node` picks up for when the\n     *         resource config is changed.\n     *\n     * @param _config The new resource config values.\n     */\n    function setResourceConfig(ResourceMetering.ResourceConfig memory _config) external onlyOwner {\n        _setResourceConfig(_config);\n    }\n\n    /**\n     * @notice An internal setter for the resource config. Ensures that the\n     *         config is sane before storing it by checking for invariants.\n     *\n     * @param _config The new resource config.\n     */\n    function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal {\n        // Min base fee must be less than or equal to max base fee.\n        require(\n            _config.minimumBaseFee <= _config.maximumBaseFee,\n            \"SystemConfig: min base fee must be less than max base\"\n        );\n        // Base fee change denominator must be greater than 1.\n        require(\n            _config.baseFeeMaxChangeDenominator > 1,\n            \"SystemConfig: denominator must be larger than 1\"\n        );\n        // Max resource limit plus system tx gas must be less than or equal to the L2 gas limit.\n        // The gas limit must be increased before these values can be increased.\n        require(\n            _config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit,\n            \"SystemConfig: gas limit too low\"\n        );\n        // Elasticity multiplier must be greater than 0.\n        require(\n            _config.elasticityMultiplier > 0,\n            \"SystemConfig: elasticity multiplier cannot be 0\"\n        );\n        // No precision loss when computing target resource limit.\n        require(\n            ((_config.maxResourceLimit / _config.elasticityMultiplier) *\n                _config.elasticityMultiplier) == _config.maxResourceLimit,\n            \"SystemConfig: precision loss with target resource limit\"\n        );\n\n        _resourceConfig = _config;\n    }\n\n    /**\n     * @notice Updates the validator reward scalar.\n     *\n     * @param _validatorRewardScalar New validator reward scalar.\n     */\n    function setValidatorRewardScalar(uint256 _validatorRewardScalar) external onlyOwner {\n        require(\n            _validatorRewardScalar <= Constants.VALIDATOR_REWARD_DENOMINATOR,\n            \"SystemConfig: the max value of validator reward scalar has been exceeded\"\n        );\n\n        validatorRewardScalar = _validatorRewardScalar;\n\n        bytes memory data = abi.encode(_validatorRewardScalar);\n        emit ConfigUpdate(VERSION, UpdateType.VALIDATOR_REWARD_SCALAR, data);\n    }\n}\n"
      },
      "contracts/L1/ZKMerkleTrie.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes } from \"../libraries/Bytes.sol\";\nimport { NodeReader } from \"../libraries/NodeReader.sol\";\nimport { IZKMerkleTrie } from \"./IZKMerkleTrie.sol\";\nimport { ZKTrieHasher } from \"./ZKTrieHasher.sol\";\n\n/**\n * @custom:proxied\n * @title ZKMerkleTrie\n * @notice The ZKMerkleTrie is contract which can produce a hash according to ZKTrie.\n *         This owns an interface of Poseidon2 that is required to compute hash used by ZKTrie.\n */\ncontract ZKMerkleTrie is IZKMerkleTrie, ZKTrieHasher {\n    /**\n     * @notice Struct representing a node in the trie.\n     */\n    struct TrieNode {\n        bytes encoded;\n        NodeReader.Node decoded;\n    }\n\n    /**\n     * @notice Magic hash which indicates\n     *         See https://github.com/kroma-network/zktrie/blob/main/trie/zk_trie_proof.go.\n     */\n    bytes32 private constant MAGIC_SMT_BYTES_HASH =\n        keccak256(\n            hex\"5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449\"\n        );\n\n    /**\n     * @param _poseidon2 The address of poseidon2 contract.\n     */\n    constructor(address _poseidon2) ZKTrieHasher(_poseidon2) {}\n\n    /**\n     * @notice Checks if a given bytes is MAGIC_SMT_BYTES_HASH.\n     *\n     * @param _value Bytes to be compared.\n     */\n    function isMagicSmtBytesHash(bytes memory _value) private pure returns (bool) {\n        return keccak256(_value) == MAGIC_SMT_BYTES_HASH;\n    }\n\n    /**\n     * @inheritdoc IZKMerkleTrie\n     */\n    function verifyInclusionProof(\n        bytes32 _key,\n        bytes memory _value,\n        bytes[] memory _proofs,\n        bytes32 _root\n    ) external view returns (bool) {\n        (bool exists, bytes memory value) = this.get(_key, _proofs, _root);\n        return (exists && Bytes.equal(_value, value));\n    }\n\n    /**\n     * @notice Retrieves the value associated with a given key.\n     *\n     * @param _key    Key to search for, as hex bytes.\n     * @param _proofs Merkle trie inclusion proof for the key.\n     * @param _root   Known root of the Merkle trie.\n     *\n     * @return Whether or not the key exists.\n     * @return Value of the key if it exists.\n     */\n    function get(\n        bytes32 _key,\n        bytes[] memory _proofs,\n        bytes32 _root\n    ) external view returns (bool, bytes memory) {\n        require(_proofs.length >= 2, \"ZKMerkleTrie: provided proof is too short\");\n        require(\n            isMagicSmtBytesHash(_proofs[_proofs.length - 1]),\n            \"ZKMerkleTrie: the last item is not magic hash\"\n        );\n        bytes32 key = _hashElem(_key);\n        TrieNode[] memory nodes = _parseProofs(_proofs);\n        NodeReader.Node memory currentNode;\n        bytes32 computedKey = bytes32(0);\n        bool exists = false;\n        bool empty = false;\n        bytes memory value = bytes(\"\");\n        for (uint256 i = nodes.length - 2; i >= 0; ) {\n            currentNode = nodes[i].decoded;\n            if (currentNode.nodeType == NodeReader.NodeType.MIDDLE) {\n                bool isLeft = _isLeft(key, i);\n                if (isLeft) {\n                    require(computedKey == currentNode.childL, \"ZKMerkleTrie: invalid key L\");\n                } else {\n                    require(computedKey == currentNode.childR, \"ZKMerkleTrie: invalid key R\");\n                }\n                computedKey = _hashFixed2Elems(\n                    currentNode.childL,\n                    currentNode.childR\n                );\n            } else if (currentNode.nodeType == NodeReader.NodeType.LEAF) {\n                require(!exists && !empty, \"ZKMerkleTrie: duplicated terminal node\");\n                exists = currentNode.nodeKey == key;\n                if (!exists) {\n                    break;\n                }\n                computedKey = _hashFixed3Elems(\n                    bytes32(uint256(1)),\n                    currentNode.nodeKey,\n                    _valueHash(currentNode.compressedFlags, currentNode.valuePreimage)\n                );\n                bytes32[] memory valuePreimage = currentNode.valuePreimage;\n                uint256 len = valuePreimage.length;\n                assembly {\n                    value := valuePreimage\n                    mstore(value, mul(len, 32))\n                }\n                if (currentNode.keyPreimage != bytes32(0)) {\n                    // NOTE(chokobole): The comparison order is important, because in this setting,\n                    // first condition is mostly evaluted to be true. When we're sure about\n                    // database preimage, then we need to enable just one of check below!\n                    require(\n                        currentNode.keyPreimage == _key || currentNode.keyPreimage == key,\n                        \"ZKMerkleTrie: invalid key preimage\"\n                    );\n                }\n            } else if (currentNode.nodeType == NodeReader.NodeType.EMPTY) {\n                require(!exists && !empty, \"ZKMerkleTrie: duplicated terminal node\");\n                empty = true;\n            }\n            if (i == 0) {\n                require(computedKey == _root, \"ZKMerkeTrie: invalid root\");\n                break;\n            }\n            unchecked {\n                --i;\n            }\n        }\n        return (exists, value);\n    }\n\n    /**\n     * @notice Parses an array of proof elements into a new array that contains both the original\n     *         encoded element and the decoded element.\n     *\n     * @param _proofs Array of proof elements to parse.\n     *\n     * @return TrieNode parsed into easily accessible structs.\n     */\n    function _parseProofs(bytes[] memory _proofs) private pure returns (TrieNode[] memory) {\n        uint256 length = _proofs.length;\n        TrieNode[] memory nodes = new TrieNode[](length);\n        // NOTE(chokobole): Last proof is MAGIC_SMT_BYTES_HASH!\n        for (uint256 i = 0; i < length - 1; ) {\n            NodeReader.Node memory node = NodeReader.readNode(_proofs[i]);\n            nodes[i] = TrieNode({ encoded: _proofs[i], decoded: node });\n            unchecked {\n                ++i;\n            }\n        }\n        return nodes;\n    }\n\n    /**\n     * @notice Computes merkle path at index n based on a given keyPreimage.\n     *\n     * @param _keyPreimage Keypreimage.\n     * @param _n           Bit to mask.\n     *\n     * @return Whether merkle path is left or not.\n     */\n    function _isLeft(bytes32 _keyPreimage, uint256 _n) private pure returns (bool) {\n        require(_n < 256, \"ZKMerkleTrie: too long depth\");\n        return _keyPreimage & bytes32(1 << _n) == 0;\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotesUpgradeable {\n    /**\n     * @dev Emitted when an account changes their delegate.\n     */\n    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n    /**\n     * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n     */\n    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n    /**\n     * @dev Returns the current amount of votes that `account` has.\n     */\n    function getVotes(address account) external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is\n     * configured to use block numbers, this will return the value at the end of the corresponding block.\n     */\n    function getPastVotes(address account, uint256 timepoint) external view returns (uint256);\n\n    /**\n     * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is\n     * configured to use block numbers, this will return the value at the end of the corresponding block.\n     *\n     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n     * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n     * vote.\n     */\n    function getPastTotalSupply(uint256 timepoint) external view returns (uint256);\n\n    /**\n     * @dev Returns the delegate that `account` has chosen.\n     */\n    function delegates(address account) external view returns (address);\n\n    /**\n     * @dev Delegates votes from the sender to `delegatee`.\n     */\n    function delegate(address delegatee) external;\n\n    /**\n     * @dev Delegates votes from signer to `delegatee`.\n     */\n    function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/interfaces/IERC6372Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC6372.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC6372Upgradeable {\n    /**\n     * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).\n     */\n    function clock() external view returns (uint48);\n\n    /**\n     * @dev Description of the clock\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function CLOCK_MODE() external view returns (string memory);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.1) (governance/Governor.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"../token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../utils/cryptography/EIP712Upgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../utils/math/SafeCastUpgradeable.sol\";\nimport \"../utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"../utils/AddressUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"./IGovernorUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Core of the governance system, designed to be extended though various modules.\n *\n * This contract is abstract and requires several functions to be implemented in various modules:\n *\n * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote}\n * - A voting module must implement {_getVotes}\n * - Additionally, {votingPeriod} must also be implemented\n *\n * _Available since v4.3._\n */\nabstract contract GovernorUpgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, EIP712Upgradeable, IGovernorUpgradeable, IERC721ReceiverUpgradeable, IERC1155ReceiverUpgradeable {\n    using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n\n    bytes32 public constant BALLOT_TYPEHASH = keccak256(\"Ballot(uint256 proposalId,uint8 support)\");\n    bytes32 public constant EXTENDED_BALLOT_TYPEHASH =\n        keccak256(\"ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)\");\n\n    // solhint-disable var-name-mixedcase\n    struct ProposalCore {\n        // --- start retyped from Timers.BlockNumber at offset 0x00 ---\n        uint64 voteStart;\n        address proposer;\n        bytes4 __gap_unused0;\n        // --- start retyped from Timers.BlockNumber at offset 0x20 ---\n        uint64 voteEnd;\n        bytes24 __gap_unused1;\n        // --- Remaining fields starting at offset 0x40 ---------------\n        bool executed;\n        bool canceled;\n    }\n    // solhint-enable var-name-mixedcase\n\n    string private _name;\n\n    /// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore)\n    mapping(uint256 => ProposalCore) private _proposals;\n\n    // This queue keeps track of the governor operating on itself. Calls to functions protected by the\n    // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute},\n    // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the\n    // execution of {onlyGovernance} protected calls can only be achieved through successful proposals.\n    DoubleEndedQueueUpgradeable.Bytes32Deque private _governanceCall;\n\n    /**\n     * @dev Restricts a function so it can only be executed through governance proposals. For example, governance\n     * parameter setters in {GovernorSettings} are protected using this modifier.\n     *\n     * The governance executing address may be different from the Governor's own address, for example it could be a\n     * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these\n     * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus,\n     * for example, additional timelock proposers are not able to change governance parameters without going through the\n     * governance protocol (since v4.6).\n     */\n    modifier onlyGovernance() {\n        require(_msgSender() == _executor(), \"Governor: onlyGovernance\");\n        if (_executor() != address(this)) {\n            bytes32 msgDataHash = keccak256(_msgData());\n            // loop until popping the expected operation - throw if deque is empty (operation not authorized)\n            while (_governanceCall.popFront() != msgDataHash) {}\n        }\n        _;\n    }\n\n    /**\n     * @dev Sets the value for {name} and {version}\n     */\n    function __Governor_init(string memory name_) internal onlyInitializing {\n        __EIP712_init_unchained(name_, version());\n        __Governor_init_unchained(name_);\n    }\n\n    function __Governor_init_unchained(string memory name_) internal onlyInitializing {\n        _name = name_;\n    }\n\n    /**\n     * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract)\n     */\n    receive() external payable virtual {\n        require(_executor() == address(this), \"Governor: must send to executor\");\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n        bytes4 governorCancelId = this.cancel.selector ^ this.proposalProposer.selector;\n\n        bytes4 governorParamsId = this.castVoteWithReasonAndParams.selector ^\n            this.castVoteWithReasonAndParamsBySig.selector ^\n            this.getVotesWithParams.selector;\n\n        // The original interface id in v4.3.\n        bytes4 governor43Id = type(IGovernorUpgradeable).interfaceId ^\n            type(IERC6372Upgradeable).interfaceId ^\n            governorCancelId ^\n            governorParamsId;\n\n        // An updated interface id in v4.6, with params added.\n        bytes4 governor46Id = type(IGovernorUpgradeable).interfaceId ^ type(IERC6372Upgradeable).interfaceId ^ governorCancelId;\n\n        // For the updated interface id in v4.9, we use governorCancelId directly.\n\n        return\n            interfaceId == governor43Id ||\n            interfaceId == governor46Id ||\n            interfaceId == governorCancelId ||\n            interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IGovernor-name}.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev See {IGovernor-version}.\n     */\n    function version() public view virtual override returns (string memory) {\n        return \"1\";\n    }\n\n    /**\n     * @dev See {IGovernor-hashProposal}.\n     *\n     * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array\n     * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id\n     * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in\n     * advance, before the proposal is submitted.\n     *\n     * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the\n     * same proposal (with same operation and same description) will have the same id if submitted on multiple governors\n     * across multiple networks. This also means that in order to execute the same operation twice (on the same\n     * governor) the proposer will have to change the description in order to avoid proposal id conflicts.\n     */\n    function hashProposal(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) public pure virtual override returns (uint256) {\n        return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash)));\n    }\n\n    /**\n     * @dev See {IGovernor-state}.\n     */\n    function state(uint256 proposalId) public view virtual override returns (ProposalState) {\n        ProposalCore storage proposal = _proposals[proposalId];\n\n        if (proposal.executed) {\n            return ProposalState.Executed;\n        }\n\n        if (proposal.canceled) {\n            return ProposalState.Canceled;\n        }\n\n        uint256 snapshot = proposalSnapshot(proposalId);\n\n        if (snapshot == 0) {\n            revert(\"Governor: unknown proposal id\");\n        }\n\n        uint256 currentTimepoint = clock();\n\n        if (snapshot >= currentTimepoint) {\n            return ProposalState.Pending;\n        }\n\n        uint256 deadline = proposalDeadline(proposalId);\n\n        if (deadline >= currentTimepoint) {\n            return ProposalState.Active;\n        }\n\n        if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) {\n            return ProposalState.Succeeded;\n        } else {\n            return ProposalState.Defeated;\n        }\n    }\n\n    /**\n     * @dev Part of the Governor Bravo's interface: _\"The number of votes required in order for a voter to become a proposer\"_.\n     */\n    function proposalThreshold() public view virtual returns (uint256) {\n        return 0;\n    }\n\n    /**\n     * @dev See {IGovernor-proposalSnapshot}.\n     */\n    function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) {\n        return _proposals[proposalId].voteStart;\n    }\n\n    /**\n     * @dev See {IGovernor-proposalDeadline}.\n     */\n    function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) {\n        return _proposals[proposalId].voteEnd;\n    }\n\n    /**\n     * @dev Returns the account that created a given proposal.\n     */\n    function proposalProposer(uint256 proposalId) public view virtual override returns (address) {\n        return _proposals[proposalId].proposer;\n    }\n\n    /**\n     * @dev Amount of votes already cast passes the threshold limit.\n     */\n    function _quorumReached(uint256 proposalId) internal view virtual returns (bool);\n\n    /**\n     * @dev Is the proposal successful or not.\n     */\n    function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool);\n\n    /**\n     * @dev Get the voting weight of `account` at a specific `timepoint`, for a vote as described by `params`.\n     */\n    function _getVotes(address account, uint256 timepoint, bytes memory params) internal view virtual returns (uint256);\n\n    /**\n     * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`.\n     *\n     * Note: Support is generic and can represent various things depending on the voting system used.\n     */\n    function _countVote(\n        uint256 proposalId,\n        address account,\n        uint8 support,\n        uint256 weight,\n        bytes memory params\n    ) internal virtual;\n\n    /**\n     * @dev Default additional encoded parameters used by castVote methods that don't include them\n     *\n     * Note: Should be overridden by specific implementations to use an appropriate value, the\n     * meaning of the additional params, in the context of that implementation\n     */\n    function _defaultParams() internal view virtual returns (bytes memory) {\n        return \"\";\n    }\n\n    /**\n     * @dev See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}.\n     */\n    function propose(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        string memory description\n    ) public virtual override returns (uint256) {\n        address proposer = _msgSender();\n        require(_isValidDescriptionForProposer(proposer, description), \"Governor: proposer restricted\");\n\n        uint256 currentTimepoint = clock();\n        require(\n            getVotes(proposer, currentTimepoint - 1) >= proposalThreshold(),\n            \"Governor: proposer votes below proposal threshold\"\n        );\n\n        uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));\n\n        require(targets.length == values.length, \"Governor: invalid proposal length\");\n        require(targets.length == calldatas.length, \"Governor: invalid proposal length\");\n        require(targets.length > 0, \"Governor: empty proposal\");\n        require(_proposals[proposalId].voteStart == 0, \"Governor: proposal already exists\");\n\n        uint256 snapshot = currentTimepoint + votingDelay();\n        uint256 deadline = snapshot + votingPeriod();\n\n        _proposals[proposalId] = ProposalCore({\n            proposer: proposer,\n            voteStart: SafeCastUpgradeable.toUint64(snapshot),\n            voteEnd: SafeCastUpgradeable.toUint64(deadline),\n            executed: false,\n            canceled: false,\n            __gap_unused0: 0,\n            __gap_unused1: 0\n        });\n\n        emit ProposalCreated(\n            proposalId,\n            proposer,\n            targets,\n            values,\n            new string[](targets.length),\n            calldatas,\n            snapshot,\n            deadline,\n            description\n        );\n\n        return proposalId;\n    }\n\n    /**\n     * @dev See {IGovernor-execute}.\n     */\n    function execute(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) public payable virtual override returns (uint256) {\n        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);\n\n        ProposalState currentState = state(proposalId);\n        require(\n            currentState == ProposalState.Succeeded || currentState == ProposalState.Queued,\n            \"Governor: proposal not successful\"\n        );\n        _proposals[proposalId].executed = true;\n\n        emit ProposalExecuted(proposalId);\n\n        _beforeExecute(proposalId, targets, values, calldatas, descriptionHash);\n        _execute(proposalId, targets, values, calldatas, descriptionHash);\n        _afterExecute(proposalId, targets, values, calldatas, descriptionHash);\n\n        return proposalId;\n    }\n\n    /**\n     * @dev See {IGovernor-cancel}.\n     */\n    function cancel(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) public virtual override returns (uint256) {\n        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);\n        require(state(proposalId) == ProposalState.Pending, \"Governor: too late to cancel\");\n        require(_msgSender() == _proposals[proposalId].proposer, \"Governor: only proposer can cancel\");\n        return _cancel(targets, values, calldatas, descriptionHash);\n    }\n\n    /**\n     * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism\n     */\n    function _execute(\n        uint256 /* proposalId */,\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 /*descriptionHash*/\n    ) internal virtual {\n        string memory errorMessage = \"Governor: call reverted without message\";\n        for (uint256 i = 0; i < targets.length; ++i) {\n            (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]);\n            AddressUpgradeable.verifyCallResult(success, returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Hook before execution is triggered.\n     */\n    function _beforeExecute(\n        uint256 /* proposalId */,\n        address[] memory targets,\n        uint256[] memory /* values */,\n        bytes[] memory calldatas,\n        bytes32 /*descriptionHash*/\n    ) internal virtual {\n        if (_executor() != address(this)) {\n            for (uint256 i = 0; i < targets.length; ++i) {\n                if (targets[i] == address(this)) {\n                    _governanceCall.pushBack(keccak256(calldatas[i]));\n                }\n            }\n        }\n    }\n\n    /**\n     * @dev Hook after execution is triggered.\n     */\n    function _afterExecute(\n        uint256 /* proposalId */,\n        address[] memory /* targets */,\n        uint256[] memory /* values */,\n        bytes[] memory /* calldatas */,\n        bytes32 /*descriptionHash*/\n    ) internal virtual {\n        if (_executor() != address(this)) {\n            if (!_governanceCall.empty()) {\n                _governanceCall.clear();\n            }\n        }\n    }\n\n    /**\n     * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as\n     * canceled to allow distinguishing it from executed proposals.\n     *\n     * Emits a {IGovernor-ProposalCanceled} event.\n     */\n    function _cancel(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) internal virtual returns (uint256) {\n        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);\n\n        ProposalState currentState = state(proposalId);\n\n        require(\n            currentState != ProposalState.Canceled &&\n                currentState != ProposalState.Expired &&\n                currentState != ProposalState.Executed,\n            \"Governor: proposal not active\"\n        );\n        _proposals[proposalId].canceled = true;\n\n        emit ProposalCanceled(proposalId);\n\n        return proposalId;\n    }\n\n    /**\n     * @dev See {IGovernor-getVotes}.\n     */\n    function getVotes(address account, uint256 timepoint) public view virtual override returns (uint256) {\n        return _getVotes(account, timepoint, _defaultParams());\n    }\n\n    /**\n     * @dev See {IGovernor-getVotesWithParams}.\n     */\n    function getVotesWithParams(\n        address account,\n        uint256 timepoint,\n        bytes memory params\n    ) public view virtual override returns (uint256) {\n        return _getVotes(account, timepoint, params);\n    }\n\n    /**\n     * @dev See {IGovernor-castVote}.\n     */\n    function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) {\n        address voter = _msgSender();\n        return _castVote(proposalId, voter, support, \"\");\n    }\n\n    /**\n     * @dev See {IGovernor-castVoteWithReason}.\n     */\n    function castVoteWithReason(\n        uint256 proposalId,\n        uint8 support,\n        string calldata reason\n    ) public virtual override returns (uint256) {\n        address voter = _msgSender();\n        return _castVote(proposalId, voter, support, reason);\n    }\n\n    /**\n     * @dev See {IGovernor-castVoteWithReasonAndParams}.\n     */\n    function castVoteWithReasonAndParams(\n        uint256 proposalId,\n        uint8 support,\n        string calldata reason,\n        bytes memory params\n    ) public virtual override returns (uint256) {\n        address voter = _msgSender();\n        return _castVote(proposalId, voter, support, reason, params);\n    }\n\n    /**\n     * @dev See {IGovernor-castVoteBySig}.\n     */\n    function castVoteBySig(\n        uint256 proposalId,\n        uint8 support,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual override returns (uint256) {\n        address voter = ECDSAUpgradeable.recover(\n            _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))),\n            v,\n            r,\n            s\n        );\n        return _castVote(proposalId, voter, support, \"\");\n    }\n\n    /**\n     * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}.\n     */\n    function castVoteWithReasonAndParamsBySig(\n        uint256 proposalId,\n        uint8 support,\n        string calldata reason,\n        bytes memory params,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual override returns (uint256) {\n        address voter = ECDSAUpgradeable.recover(\n            _hashTypedDataV4(\n                keccak256(\n                    abi.encode(\n                        EXTENDED_BALLOT_TYPEHASH,\n                        proposalId,\n                        support,\n                        keccak256(bytes(reason)),\n                        keccak256(params)\n                    )\n                )\n            ),\n            v,\n            r,\n            s\n        );\n\n        return _castVote(proposalId, voter, support, reason, params);\n    }\n\n    /**\n     * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve\n     * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams().\n     *\n     * Emits a {IGovernor-VoteCast} event.\n     */\n    function _castVote(\n        uint256 proposalId,\n        address account,\n        uint8 support,\n        string memory reason\n    ) internal virtual returns (uint256) {\n        return _castVote(proposalId, account, support, reason, _defaultParams());\n    }\n\n    /**\n     * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve\n     * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function.\n     *\n     * Emits a {IGovernor-VoteCast} event.\n     */\n    function _castVote(\n        uint256 proposalId,\n        address account,\n        uint8 support,\n        string memory reason,\n        bytes memory params\n    ) internal virtual returns (uint256) {\n        ProposalCore storage proposal = _proposals[proposalId];\n        require(state(proposalId) == ProposalState.Active, \"Governor: vote not currently active\");\n\n        uint256 weight = _getVotes(account, proposal.voteStart, params);\n        _countVote(proposalId, account, support, weight, params);\n\n        if (params.length == 0) {\n            emit VoteCast(account, proposalId, support, weight, reason);\n        } else {\n            emit VoteCastWithParams(account, proposalId, support, weight, reason, params);\n        }\n\n        return weight;\n    }\n\n    /**\n     * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor\n     * is some contract other than the governor itself, like when using a timelock, this function can be invoked\n     * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake.\n     * Note that if the executor is simply the governor itself, use of `relay` is redundant.\n     */\n    function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance {\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        AddressUpgradeable.verifyCallResult(success, returndata, \"Governor: relay reverted without message\");\n    }\n\n    /**\n     * @dev Address through which the governor executes action. Will be overloaded by module that execute actions\n     * through another contract such as a timelock.\n     */\n    function _executor() internal view virtual returns (address) {\n        return address(this);\n    }\n\n    /**\n     * @dev See {IERC721Receiver-onERC721Received}.\n     */\n    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n        return this.onERC721Received.selector;\n    }\n\n    /**\n     * @dev See {IERC1155Receiver-onERC1155Received}.\n     */\n    function onERC1155Received(\n        address,\n        address,\n        uint256,\n        uint256,\n        bytes memory\n    ) public virtual override returns (bytes4) {\n        return this.onERC1155Received.selector;\n    }\n\n    /**\n     * @dev See {IERC1155Receiver-onERC1155BatchReceived}.\n     */\n    function onERC1155BatchReceived(\n        address,\n        address,\n        uint256[] memory,\n        uint256[] memory,\n        bytes memory\n    ) public virtual override returns (bytes4) {\n        return this.onERC1155BatchReceived.selector;\n    }\n\n    /**\n     * @dev Check if the proposer is authorized to submit a proposal with the given description.\n     *\n     * If the proposal description ends with `#proposer=0x???`, where `0x???` is an address written as a hex string\n     * (case insensitive), then the submission of this proposal will only be authorized to said address.\n     *\n     * This is used for frontrunning protection. By adding this pattern at the end of their proposal, one can ensure\n     * that no other address can submit the same proposal. An attacker would have to either remove or change that part,\n     * which would result in a different proposal id.\n     *\n     * If the description does not match this pattern, it is unrestricted and anyone can submit it. This includes:\n     * - If the `0x???` part is not a valid hex string.\n     * - If the `0x???` part is a valid hex string, but does not contain exactly 40 hex digits.\n     * - If it ends with the expected suffix followed by newlines or other whitespace.\n     * - If it ends with some other similar suffix, e.g. `#other=abc`.\n     * - If it does not end with any such suffix.\n     */\n    function _isValidDescriptionForProposer(\n        address proposer,\n        string memory description\n    ) internal view virtual returns (bool) {\n        uint256 len = bytes(description).length;\n\n        // Length is too short to contain a valid proposer suffix\n        if (len < 52) {\n            return true;\n        }\n\n        // Extract what would be the `#proposer=0x` marker beginning the suffix\n        bytes12 marker;\n        assembly {\n            // - Start of the string contents in memory = description + 32\n            // - First character of the marker = len - 52\n            //   - Length of \"#proposer=0x0000000000000000000000000000000000000000\" = 52\n            // - We read the memory word starting at the first character of the marker:\n            //   - (description + 32) + (len - 52) = description + (len - 20)\n            // - Note: Solidity will ignore anything past the first 12 bytes\n            marker := mload(add(description, sub(len, 20)))\n        }\n\n        // If the marker is not found, there is no proposer suffix to check\n        if (marker != bytes12(\"#proposer=0x\")) {\n            return true;\n        }\n\n        // Parse the 40 characters following the marker as uint160\n        uint160 recovered = 0;\n        for (uint256 i = len - 40; i < len; ++i) {\n            (bool isHex, uint8 value) = _tryHexToUint(bytes(description)[i]);\n            // If any of the characters is not a hex digit, ignore the suffix entirely\n            if (!isHex) {\n                return true;\n            }\n            recovered = (recovered << 4) | value;\n        }\n\n        return recovered == uint160(proposer);\n    }\n\n    /**\n     * @dev Try to parse a character from a string as a hex value. Returns `(true, value)` if the char is in\n     * `[0-9a-fA-F]` and `(false, 0)` otherwise. Value is guaranteed to be in the range `0 <= value < 16`\n     */\n    function _tryHexToUint(bytes1 char) private pure returns (bool, uint8) {\n        uint8 c = uint8(char);\n        unchecked {\n            // Case 0-9\n            if (47 < c && c < 58) {\n                return (true, c - 48);\n            }\n            // Case A-F\n            else if (64 < c && c < 71) {\n                return (true, c - 55);\n            }\n            // Case a-f\n            else if (96 < c && c < 103) {\n                return (true, c - 87);\n            }\n            // Else: not a hex char\n            else {\n                return (false, 0);\n            }\n        }\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[46] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorSettings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../GovernorUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {Governor} for settings updatable through governance.\n *\n * _Available since v4.4._\n */\nabstract contract GovernorSettingsUpgradeable is Initializable, GovernorUpgradeable {\n    uint256 private _votingDelay;\n    uint256 private _votingPeriod;\n    uint256 private _proposalThreshold;\n\n    event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);\n    event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);\n    event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);\n\n    /**\n     * @dev Initialize the governance parameters.\n     */\n    function __GovernorSettings_init(uint256 initialVotingDelay, uint256 initialVotingPeriod, uint256 initialProposalThreshold) internal onlyInitializing {\n        __GovernorSettings_init_unchained(initialVotingDelay, initialVotingPeriod, initialProposalThreshold);\n    }\n\n    function __GovernorSettings_init_unchained(uint256 initialVotingDelay, uint256 initialVotingPeriod, uint256 initialProposalThreshold) internal onlyInitializing {\n        _setVotingDelay(initialVotingDelay);\n        _setVotingPeriod(initialVotingPeriod);\n        _setProposalThreshold(initialProposalThreshold);\n    }\n\n    /**\n     * @dev See {IGovernor-votingDelay}.\n     */\n    function votingDelay() public view virtual override returns (uint256) {\n        return _votingDelay;\n    }\n\n    /**\n     * @dev See {IGovernor-votingPeriod}.\n     */\n    function votingPeriod() public view virtual override returns (uint256) {\n        return _votingPeriod;\n    }\n\n    /**\n     * @dev See {Governor-proposalThreshold}.\n     */\n    function proposalThreshold() public view virtual override returns (uint256) {\n        return _proposalThreshold;\n    }\n\n    /**\n     * @dev Update the voting delay. This operation can only be performed through a governance proposal.\n     *\n     * Emits a {VotingDelaySet} event.\n     */\n    function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance {\n        _setVotingDelay(newVotingDelay);\n    }\n\n    /**\n     * @dev Update the voting period. This operation can only be performed through a governance proposal.\n     *\n     * Emits a {VotingPeriodSet} event.\n     */\n    function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance {\n        _setVotingPeriod(newVotingPeriod);\n    }\n\n    /**\n     * @dev Update the proposal threshold. This operation can only be performed through a governance proposal.\n     *\n     * Emits a {ProposalThresholdSet} event.\n     */\n    function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance {\n        _setProposalThreshold(newProposalThreshold);\n    }\n\n    /**\n     * @dev Internal setter for the voting delay.\n     *\n     * Emits a {VotingDelaySet} event.\n     */\n    function _setVotingDelay(uint256 newVotingDelay) internal virtual {\n        emit VotingDelaySet(_votingDelay, newVotingDelay);\n        _votingDelay = newVotingDelay;\n    }\n\n    /**\n     * @dev Internal setter for the voting period.\n     *\n     * Emits a {VotingPeriodSet} event.\n     */\n    function _setVotingPeriod(uint256 newVotingPeriod) internal virtual {\n        // voting period must be at least one block long\n        require(newVotingPeriod > 0, \"GovernorSettings: voting period too low\");\n        emit VotingPeriodSet(_votingPeriod, newVotingPeriod);\n        _votingPeriod = newVotingPeriod;\n    }\n\n    /**\n     * @dev Internal setter for the proposal threshold.\n     *\n     * Emits a {ProposalThresholdSet} event.\n     */\n    function _setProposalThreshold(uint256 newProposalThreshold) internal virtual {\n        emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold);\n        _proposalThreshold = newProposalThreshold;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[47] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/extensions/GovernorCountingSimpleUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorCountingSimple.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../GovernorUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {Governor} for simple, 3 options, vote counting.\n *\n * _Available since v4.3._\n */\nabstract contract GovernorCountingSimpleUpgradeable is Initializable, GovernorUpgradeable {\n    function __GovernorCountingSimple_init() internal onlyInitializing {\n    }\n\n    function __GovernorCountingSimple_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Supported vote types. Matches Governor Bravo ordering.\n     */\n    enum VoteType {\n        Against,\n        For,\n        Abstain\n    }\n\n    struct ProposalVote {\n        uint256 againstVotes;\n        uint256 forVotes;\n        uint256 abstainVotes;\n        mapping(address => bool) hasVoted;\n    }\n\n    mapping(uint256 => ProposalVote) private _proposalVotes;\n\n    /**\n     * @dev See {IGovernor-COUNTING_MODE}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function COUNTING_MODE() public pure virtual override returns (string memory) {\n        return \"support=bravo&quorum=for,abstain\";\n    }\n\n    /**\n     * @dev See {IGovernor-hasVoted}.\n     */\n    function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {\n        return _proposalVotes[proposalId].hasVoted[account];\n    }\n\n    /**\n     * @dev Accessor to the internal vote counts.\n     */\n    function proposalVotes(\n        uint256 proposalId\n    ) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) {\n        ProposalVote storage proposalVote = _proposalVotes[proposalId];\n        return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes);\n    }\n\n    /**\n     * @dev See {Governor-_quorumReached}.\n     */\n    function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {\n        ProposalVote storage proposalVote = _proposalVotes[proposalId];\n\n        return quorum(proposalSnapshot(proposalId)) <= proposalVote.forVotes + proposalVote.abstainVotes;\n    }\n\n    /**\n     * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes.\n     */\n    function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {\n        ProposalVote storage proposalVote = _proposalVotes[proposalId];\n\n        return proposalVote.forVotes > proposalVote.againstVotes;\n    }\n\n    /**\n     * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo).\n     */\n    function _countVote(\n        uint256 proposalId,\n        address account,\n        uint8 support,\n        uint256 weight,\n        bytes memory // params\n    ) internal virtual override {\n        ProposalVote storage proposalVote = _proposalVotes[proposalId];\n\n        require(!proposalVote.hasVoted[account], \"GovernorVotingSimple: vote already cast\");\n        proposalVote.hasVoted[account] = true;\n\n        if (support == uint8(VoteType.Against)) {\n            proposalVote.againstVotes += weight;\n        } else if (support == uint8(VoteType.For)) {\n            proposalVote.forVotes += weight;\n        } else if (support == uint8(VoteType.Abstain)) {\n            proposalVote.abstainVotes += weight;\n        } else {\n            revert(\"GovernorVotingSimple: invalid value for enum VoteType\");\n        }\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorVotes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../GovernorUpgradeable.sol\";\nimport \"../../interfaces/IERC5805Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token.\n *\n * _Available since v4.3._\n *\n * @custom:storage-size 51\n */\nabstract contract GovernorVotesUpgradeable is Initializable, GovernorUpgradeable {\n    IERC5805Upgradeable public token;\n\n    function __GovernorVotes_init(IVotesUpgradeable tokenAddress) internal onlyInitializing {\n        __GovernorVotes_init_unchained(tokenAddress);\n    }\n\n    function __GovernorVotes_init_unchained(IVotesUpgradeable tokenAddress) internal onlyInitializing {\n        token = IERC5805Upgradeable(address(tokenAddress));\n    }\n\n    /**\n     * @dev Clock (as specified in EIP-6372) is set to match the token's clock. Fallback to block numbers if the token\n     * does not implement EIP-6372.\n     */\n    function clock() public view virtual override returns (uint48) {\n        try token.clock() returns (uint48 timepoint) {\n            return timepoint;\n        } catch {\n            return SafeCastUpgradeable.toUint48(block.number);\n        }\n    }\n\n    /**\n     * @dev Machine-readable description of the clock as specified in EIP-6372.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function CLOCK_MODE() public view virtual override returns (string memory) {\n        try token.CLOCK_MODE() returns (string memory clockmode) {\n            return clockmode;\n        } catch {\n            return \"mode=blocknumber&from=default\";\n        }\n    }\n\n    /**\n     * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}).\n     */\n    function _getVotes(\n        address account,\n        uint256 timepoint,\n        bytes memory /*params*/\n    ) internal view virtual override returns (uint256) {\n        return token.getPastVotes(account, timepoint);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorVotesQuorumFraction.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./GovernorVotesUpgradeable.sol\";\nimport \"../../utils/CheckpointsUpgradeable.sol\";\nimport \"../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a\n * fraction of the total supply.\n *\n * _Available since v4.3._\n */\nabstract contract GovernorVotesQuorumFractionUpgradeable is Initializable, GovernorVotesUpgradeable {\n    using CheckpointsUpgradeable for CheckpointsUpgradeable.Trace224;\n\n    uint256 private _quorumNumerator; // DEPRECATED in favor of _quorumNumeratorHistory\n\n    /// @custom:oz-retyped-from Checkpoints.History\n    CheckpointsUpgradeable.Trace224 private _quorumNumeratorHistory;\n\n    event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);\n\n    /**\n     * @dev Initialize quorum as a fraction of the token's total supply.\n     *\n     * The fraction is specified as `numerator / denominator`. By default the denominator is 100, so quorum is\n     * specified as a percent: a numerator of 10 corresponds to quorum being 10% of total supply. The denominator can be\n     * customized by overriding {quorumDenominator}.\n     */\n    function __GovernorVotesQuorumFraction_init(uint256 quorumNumeratorValue) internal onlyInitializing {\n        __GovernorVotesQuorumFraction_init_unchained(quorumNumeratorValue);\n    }\n\n    function __GovernorVotesQuorumFraction_init_unchained(uint256 quorumNumeratorValue) internal onlyInitializing {\n        _updateQuorumNumerator(quorumNumeratorValue);\n    }\n\n    /**\n     * @dev Returns the current quorum numerator. See {quorumDenominator}.\n     */\n    function quorumNumerator() public view virtual returns (uint256) {\n        return _quorumNumeratorHistory._checkpoints.length == 0 ? _quorumNumerator : _quorumNumeratorHistory.latest();\n    }\n\n    /**\n     * @dev Returns the quorum numerator at a specific timepoint. See {quorumDenominator}.\n     */\n    function quorumNumerator(uint256 timepoint) public view virtual returns (uint256) {\n        // If history is empty, fallback to old storage\n        uint256 length = _quorumNumeratorHistory._checkpoints.length;\n        if (length == 0) {\n            return _quorumNumerator;\n        }\n\n        // Optimistic search, check the latest checkpoint\n        CheckpointsUpgradeable.Checkpoint224 memory latest = _quorumNumeratorHistory._checkpoints[length - 1];\n        if (latest._key <= timepoint) {\n            return latest._value;\n        }\n\n        // Otherwise, do the binary search\n        return _quorumNumeratorHistory.upperLookupRecent(SafeCastUpgradeable.toUint32(timepoint));\n    }\n\n    /**\n     * @dev Returns the quorum denominator. Defaults to 100, but may be overridden.\n     */\n    function quorumDenominator() public view virtual returns (uint256) {\n        return 100;\n    }\n\n    /**\n     * @dev Returns the quorum for a timepoint, in terms of number of votes: `supply * numerator / denominator`.\n     */\n    function quorum(uint256 timepoint) public view virtual override returns (uint256) {\n        return (token.getPastTotalSupply(timepoint) * quorumNumerator(timepoint)) / quorumDenominator();\n    }\n\n    /**\n     * @dev Changes the quorum numerator.\n     *\n     * Emits a {QuorumNumeratorUpdated} event.\n     *\n     * Requirements:\n     *\n     * - Must be called through a governance proposal.\n     * - New numerator must be smaller or equal to the denominator.\n     */\n    function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance {\n        _updateQuorumNumerator(newQuorumNumerator);\n    }\n\n    /**\n     * @dev Changes the quorum numerator.\n     *\n     * Emits a {QuorumNumeratorUpdated} event.\n     *\n     * Requirements:\n     *\n     * - New numerator must be smaller or equal to the denominator.\n     */\n    function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual {\n        require(\n            newQuorumNumerator <= quorumDenominator(),\n            \"GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator\"\n        );\n\n        uint256 oldQuorumNumerator = quorumNumerator();\n\n        // Make sure we keep track of the original numerator in contracts upgraded from a version without checkpoints.\n        if (oldQuorumNumerator != 0 && _quorumNumeratorHistory._checkpoints.length == 0) {\n            _quorumNumeratorHistory._checkpoints.push(\n                CheckpointsUpgradeable.Checkpoint224({_key: 0, _value: SafeCastUpgradeable.toUint224(oldQuorumNumerator)})\n            );\n        }\n\n        // Set new quorum for future proposals\n        _quorumNumeratorHistory.push(SafeCastUpgradeable.toUint32(clock()), SafeCastUpgradeable.toUint224(newQuorumNumerator));\n\n        emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[48] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/extensions/GovernorTimelockControlUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorTimelockControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IGovernorTimelockUpgradeable.sol\";\nimport \"../GovernorUpgradeable.sol\";\nimport \"../TimelockControllerUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {Governor} that binds the execution process to an instance of {TimelockController}. This adds a\n * delay, enforced by the {TimelockController} to all successful proposal (in addition to the voting duration). The\n * {Governor} needs the proposer (and ideally the executor) roles for the {Governor} to work properly.\n *\n * Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus,\n * the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be\n * inaccessible.\n *\n * WARNING: Setting up the TimelockController to have additional proposers besides the governor is very risky, as it\n * grants them powers that they must be trusted or known not to use: 1) {onlyGovernance} functions like {relay} are\n * available to them through the timelock, and 2) approved governance proposals can be blocked by them, effectively\n * executing a Denial of Service attack. This risk will be mitigated in a future release.\n *\n * _Available since v4.3._\n */\nabstract contract GovernorTimelockControlUpgradeable is Initializable, IGovernorTimelockUpgradeable, GovernorUpgradeable {\n    TimelockControllerUpgradeable private _timelock;\n    mapping(uint256 => bytes32) private _timelockIds;\n\n    /**\n     * @dev Emitted when the timelock controller used for proposal execution is modified.\n     */\n    event TimelockChange(address oldTimelock, address newTimelock);\n\n    /**\n     * @dev Set the timelock.\n     */\n    function __GovernorTimelockControl_init(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing {\n        __GovernorTimelockControl_init_unchained(timelockAddress);\n    }\n\n    function __GovernorTimelockControl_init_unchained(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing {\n        _updateTimelock(timelockAddress);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, GovernorUpgradeable) returns (bool) {\n        return interfaceId == type(IGovernorTimelockUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Overridden version of the {Governor-state} function with added support for the `Queued` state.\n     */\n    function state(uint256 proposalId) public view virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (ProposalState) {\n        ProposalState currentState = super.state(proposalId);\n\n        if (currentState != ProposalState.Succeeded) {\n            return currentState;\n        }\n\n        // core tracks execution, so we just have to check if successful proposal have been queued.\n        bytes32 queueid = _timelockIds[proposalId];\n        if (queueid == bytes32(0)) {\n            return currentState;\n        } else if (_timelock.isOperationDone(queueid)) {\n            return ProposalState.Executed;\n        } else if (_timelock.isOperationPending(queueid)) {\n            return ProposalState.Queued;\n        } else {\n            return ProposalState.Canceled;\n        }\n    }\n\n    /**\n     * @dev Public accessor to check the address of the timelock\n     */\n    function timelock() public view virtual override returns (address) {\n        return address(_timelock);\n    }\n\n    /**\n     * @dev Public accessor to check the eta of a queued proposal\n     */\n    function proposalEta(uint256 proposalId) public view virtual override returns (uint256) {\n        uint256 eta = _timelock.getTimestamp(_timelockIds[proposalId]);\n        return eta == 1 ? 0 : eta; // _DONE_TIMESTAMP (1) should be replaced with a 0 value\n    }\n\n    /**\n     * @dev Function to queue a proposal to the timelock.\n     */\n    function queue(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) public virtual override returns (uint256) {\n        uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);\n\n        require(state(proposalId) == ProposalState.Succeeded, \"Governor: proposal not successful\");\n\n        uint256 delay = _timelock.getMinDelay();\n        _timelockIds[proposalId] = _timelock.hashOperationBatch(targets, values, calldatas, 0, descriptionHash);\n        _timelock.scheduleBatch(targets, values, calldatas, 0, descriptionHash, delay);\n\n        emit ProposalQueued(proposalId, block.timestamp + delay);\n\n        return proposalId;\n    }\n\n    /**\n     * @dev Overridden execute function that run the already queued proposal through the timelock.\n     */\n    function _execute(\n        uint256 /* proposalId */,\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) internal virtual override {\n        _timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash);\n    }\n\n    /**\n     * @dev Overridden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already\n     * been queued.\n     */\n    // This function can reenter through the external call to the timelock, but we assume the timelock is trusted and\n    // well behaved (according to TimelockController) and this will not happen.\n    // slither-disable-next-line reentrancy-no-eth\n    function _cancel(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) internal virtual override returns (uint256) {\n        uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash);\n\n        if (_timelockIds[proposalId] != 0) {\n            _timelock.cancel(_timelockIds[proposalId]);\n            delete _timelockIds[proposalId];\n        }\n\n        return proposalId;\n    }\n\n    /**\n     * @dev Address through which the governor executes action. In this case, the timelock.\n     */\n    function _executor() internal view virtual override returns (address) {\n        return address(_timelock);\n    }\n\n    /**\n     * @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates\n     * must be proposed, scheduled, and executed through governance proposals.\n     *\n     * CAUTION: It is not recommended to change the timelock while there are other queued governance proposals.\n     */\n    function updateTimelock(TimelockControllerUpgradeable newTimelock) external virtual onlyGovernance {\n        _updateTimelock(newTimelock);\n    }\n\n    function _updateTimelock(TimelockControllerUpgradeable newTimelock) private {\n        emit TimelockChange(address(_timelock), address(newTimelock));\n        _timelock = newTimelock;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[48] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/Strings.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"
      },
      "node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n    /*//////////////////////////////////////////////////////////////\n                    SIMPLIFIED FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n    }\n\n    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n    }\n\n    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n    }\n\n    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n    }\n\n    function powWad(int256 x, int256 y) internal pure returns (int256) {\n        // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\n        return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\n    }\n\n    function expWad(int256 x) internal pure returns (int256 r) {\n        unchecked {\n            // When the result is < 0.5 we return zero. This happens when\n            // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n            if (x <= -42139678854452767551) return 0;\n\n            // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n            // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n            if (x >= 135305999368893231589) revert(\"EXP_OVERFLOW\");\n\n            // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n            // for more intermediate precision and a binary basis. This base conversion\n            // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n            x = (x << 78) / 5**18;\n\n            // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n            // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n            // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n            int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\n            x = x - k * 54916777467707473351141471128;\n\n            // k is in the range [-61, 195].\n\n            // Evaluate using a (6, 7)-term rational approximation.\n            // p is made monic, we'll multiply by a scale factor later.\n            int256 y = x + 1346386616545796478920950773328;\n            y = ((y * x) >> 96) + 57155421227552351082224309758442;\n            int256 p = y + x - 94201549194550492254356042504812;\n            p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n            p = p * x + (4385272521454847904659076985693276 << 96);\n\n            // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n            int256 q = x - 2855989394907223263936484059900;\n            q = ((q * x) >> 96) + 50020603652535783019961831881945;\n            q = ((q * x) >> 96) - 533845033583426703283633433725380;\n            q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n            q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n            q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n            assembly {\n                // Div in assembly because solidity adds a zero check despite the unchecked.\n                // The q polynomial won't have zeros in the domain as all its roots are complex.\n                // No scaling is necessary because p is already 2**96 too large.\n                r := sdiv(p, q)\n            }\n\n            // r should be in the range (0.09, 0.25) * 2**96.\n\n            // We now need to multiply r by:\n            // * the scale factor s = ~6.031367120.\n            // * the 2**k factor from the range reduction.\n            // * the 1e18 / 2**96 factor for base conversion.\n            // We do this all at once, with an intermediate result in 2**213\n            // basis, so the final right shift is always by a positive amount.\n            r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\n        }\n    }\n\n    function lnWad(int256 x) internal pure returns (int256 r) {\n        unchecked {\n            require(x > 0, \"UNDEFINED\");\n\n            // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n            // We do this by multiplying by 2**96 / 10**18. But since\n            // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n            // and add ln(2**96 / 10**18) at the end.\n\n            // Reduce range of x to (1, 2) * 2**96\n            // ln(2^k * x) = k * ln(2) + ln(x)\n            int256 k = int256(log2(uint256(x))) - 96;\n            x <<= uint256(159 - k);\n            x = int256(uint256(x) >> 159);\n\n            // Evaluate using a (8, 8)-term rational approximation.\n            // p is made monic, we will multiply by a scale factor later.\n            int256 p = x + 3273285459638523848632254066296;\n            p = ((p * x) >> 96) + 24828157081833163892658089445524;\n            p = ((p * x) >> 96) + 43456485725739037958740375743393;\n            p = ((p * x) >> 96) - 11111509109440967052023855526967;\n            p = ((p * x) >> 96) - 45023709667254063763336534515857;\n            p = ((p * x) >> 96) - 14706773417378608786704636184526;\n            p = p * x - (795164235651350426258249787498 << 96);\n\n            // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n            // q is monic by convention.\n            int256 q = x + 5573035233440673466300451813936;\n            q = ((q * x) >> 96) + 71694874799317883764090561454958;\n            q = ((q * x) >> 96) + 283447036172924575727196451306956;\n            q = ((q * x) >> 96) + 401686690394027663651624208769553;\n            q = ((q * x) >> 96) + 204048457590392012362485061816622;\n            q = ((q * x) >> 96) + 31853899698501571402653359427138;\n            q = ((q * x) >> 96) + 909429971244387300277376558375;\n            assembly {\n                // Div in assembly because solidity adds a zero check despite the unchecked.\n                // The q polynomial is known not to have zeros in the domain.\n                // No scaling required because p is already 2**96 too large.\n                r := sdiv(p, q)\n            }\n\n            // r is in the range (0, 0.125) * 2**96\n\n            // Finalization, we need to:\n            // * multiply by the scale factor s = 5.549…\n            // * add ln(2**96 / 10**18)\n            // * add k * ln(2)\n            // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n            // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n            r *= 1677202110996718588342820967067443963516166;\n            // add ln(2) * k * 5e18 * 2**192\n            r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\n            // add ln(2**96 / 10**18) * 5e18 * 2**192\n            r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n            // base conversion: mul 2**18 / 2**192\n            r >>= 174;\n        }\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                    LOW LEVEL FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function mulDivDown(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        assembly {\n            // Store x * y in z for now.\n            z := mul(x, y)\n\n            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n                revert(0, 0)\n            }\n\n            // Divide z by the denominator.\n            z := div(z, denominator)\n        }\n    }\n\n    function mulDivUp(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        assembly {\n            // Store x * y in z for now.\n            z := mul(x, y)\n\n            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n                revert(0, 0)\n            }\n\n            // First, divide z - 1 by the denominator and add 1.\n            // We allow z - 1 to underflow if z is 0, because we multiply the\n            // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n        }\n    }\n\n    function rpow(\n        uint256 x,\n        uint256 n,\n        uint256 scalar\n    ) internal pure returns (uint256 z) {\n        assembly {\n            switch x\n            case 0 {\n                switch n\n                case 0 {\n                    // 0 ** 0 = 1\n                    z := scalar\n                }\n                default {\n                    // 0 ** n = 0\n                    z := 0\n                }\n            }\n            default {\n                switch mod(n, 2)\n                case 0 {\n                    // If n is even, store scalar in z for now.\n                    z := scalar\n                }\n                default {\n                    // If n is odd, store x in z for now.\n                    z := x\n                }\n\n                // Shifting right by 1 is like dividing by 2.\n                let half := shr(1, scalar)\n\n                for {\n                    // Shift n right by 1 before looping to halve it.\n                    n := shr(1, n)\n                } n {\n                    // Shift n right by 1 each iteration to halve it.\n                    n := shr(1, n)\n                } {\n                    // Revert immediately if x ** 2 would overflow.\n                    // Equivalent to iszero(eq(div(xx, x), x)) here.\n                    if shr(128, x) {\n                        revert(0, 0)\n                    }\n\n                    // Store x squared.\n                    let xx := mul(x, x)\n\n                    // Round to the nearest number.\n                    let xxRound := add(xx, half)\n\n                    // Revert if xx + half overflowed.\n                    if lt(xxRound, xx) {\n                        revert(0, 0)\n                    }\n\n                    // Set x to scaled xxRound.\n                    x := div(xxRound, scalar)\n\n                    // If n is even:\n                    if mod(n, 2) {\n                        // Compute z * x.\n                        let zx := mul(z, x)\n\n                        // If z * x overflowed:\n                        if iszero(eq(div(zx, x), z)) {\n                            // Revert if x is non-zero.\n                            if iszero(iszero(x)) {\n                                revert(0, 0)\n                            }\n                        }\n\n                        // Round to the nearest number.\n                        let zxRound := add(zx, half)\n\n                        // Revert if zx + half overflowed.\n                        if lt(zxRound, zx) {\n                            revert(0, 0)\n                        }\n\n                        // Return properly scaled zxRound.\n                        z := div(zxRound, scalar)\n                    }\n                }\n            }\n        }\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        GENERAL NUMBER UTILITIES\n    //////////////////////////////////////////////////////////////*/\n\n    function sqrt(uint256 x) internal pure returns (uint256 z) {\n        assembly {\n            let y := x // We start y at x, which will help us make our initial estimate.\n\n            z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n            // We check y >= 2^(k + 8) but shift right by k bits\n            // each branch to ensure that if x >= 256, then y >= 256.\n            if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n                y := shr(128, y)\n                z := shl(64, z)\n            }\n            if iszero(lt(y, 0x1000000000000000000)) {\n                y := shr(64, y)\n                z := shl(32, z)\n            }\n            if iszero(lt(y, 0x10000000000)) {\n                y := shr(32, y)\n                z := shl(16, z)\n            }\n            if iszero(lt(y, 0x1000000)) {\n                y := shr(16, y)\n                z := shl(8, z)\n            }\n\n            // Goal was to get z*z*y within a small factor of x. More iterations could\n            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n            // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n            // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n            // There is no overflow risk here since y < 2^136 after the first branch above.\n            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n\n            // If x+1 is a perfect square, the Babylonian method cycles between\n            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n            z := sub(z, lt(div(x, z), z))\n        }\n    }\n\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        require(x > 0, \"UNDEFINED\");\n\n        assembly {\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n            r := or(r, shl(2, lt(0xf, shr(r, x))))\n            r := or(r, shl(1, lt(0x3, shr(r, x))))\n            r := or(r, lt(0x1, shr(r, x)))\n        }\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"
      },
      "contracts/universal/StandardBridge.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { IKromaMintableERC20 } from \"./IKromaMintableERC20.sol\";\nimport { KromaMintableERC20 } from \"./KromaMintableERC20.sol\";\n\n/**\n * @custom:upgradeable\n * @title StandardBridge\n * @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles\n *         the core bridging logic, including escrowing tokens that are native to the local chain\n *         and minting/burning tokens that are native to the remote chain.\n */\nabstract contract StandardBridge {\n    using SafeERC20 for IERC20;\n\n    /**\n     * @notice The L2 gas limit set when eth is depoisited using the receive() function.\n     */\n    uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000;\n\n    /**\n     * @notice Messenger contract on this domain.\n     */\n    CrossDomainMessenger public immutable MESSENGER;\n\n    /**\n     * @notice Corresponding bridge on the other domain.\n     */\n    StandardBridge public immutable OTHER_BRIDGE;\n\n    /**\n     * @notice Mapping that stores deposits for a given pair of local and remote tokens.\n     */\n    mapping(address => mapping(address => uint256)) public deposits;\n\n    /**\n     * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n     *         A gap size of 49 was chosen here, so that the first slot used in a child contract\n     *         would be a multiple of 50.\n     */\n    uint256[49] private __gap;\n\n    /**\n     * @notice Emitted when an ETH bridge is initiated to the other chain.\n     *\n     * @param from      Address of the sender.\n     * @param to        Address of the receiver.\n     * @param amount    Amount of ETH sent.\n     * @param extraData Extra data sent with the transaction.\n     */\n    event ETHBridgeInitiated(\n        address indexed from,\n        address indexed to,\n        uint256 amount,\n        bytes extraData\n    );\n\n    /**\n     * @notice Emitted when an ETH bridge is finalized on this chain.\n     *\n     * @param from      Address of the sender.\n     * @param to        Address of the receiver.\n     * @param amount    Amount of ETH sent.\n     * @param extraData Extra data sent with the transaction.\n     */\n    event ETHBridgeFinalized(\n        address indexed from,\n        address indexed to,\n        uint256 amount,\n        bytes extraData\n    );\n\n    /**\n     * @notice Emitted when an ERC20 bridge is initiated to the other chain.\n     *\n     * @param localToken  Address of the ERC20 on this chain.\n     * @param remoteToken Address of the ERC20 on the remote chain.\n     * @param from        Address of the sender.\n     * @param to          Address of the receiver.\n     * @param amount      Amount of the ERC20 sent.\n     * @param extraData   Extra data sent with the transaction.\n     */\n    event ERC20BridgeInitiated(\n        address indexed localToken,\n        address indexed remoteToken,\n        address indexed from,\n        address to,\n        uint256 amount,\n        bytes extraData\n    );\n\n    /**\n     * @notice Emitted when an ERC20 bridge is finalized on this chain.\n     *\n     * @param localToken  Address of the ERC20 on this chain.\n     * @param remoteToken Address of the ERC20 on the remote chain.\n     * @param from        Address of the sender.\n     * @param to          Address of the receiver.\n     * @param amount      Amount of the ERC20 sent.\n     * @param extraData   Extra data sent with the transaction.\n     */\n    event ERC20BridgeFinalized(\n        address indexed localToken,\n        address indexed remoteToken,\n        address indexed from,\n        address to,\n        uint256 amount,\n        bytes extraData\n    );\n\n    /**\n     * @notice Only allow EOAs to call the functions. Note that this is not safe against contracts\n     *         calling code within their constructors, but also doesn't really matter since we're\n     *         just trying to prevent users accidentally depositing with smart contract wallets.\n     */\n    modifier onlyEOA() {\n        require(\n            !Address.isContract(msg.sender),\n            \"StandardBridge: function can only be called from an EOA\"\n        );\n        _;\n    }\n\n    /**\n     * @notice Ensures that the caller is a cross-chain message from the other bridge.\n     */\n    modifier onlyOtherBridge() {\n        require(\n            msg.sender == address(MESSENGER) &&\n                MESSENGER.xDomainMessageSender() == address(OTHER_BRIDGE),\n            \"StandardBridge: function can only be called from the other bridge\"\n        );\n        _;\n    }\n\n    /**\n     * @param _messenger   Address of CrossDomainMessenger on this network.\n     * @param _otherBridge Address of the other StandardBridge contract.\n     */\n    constructor(address payable _messenger, address payable _otherBridge) {\n        MESSENGER = CrossDomainMessenger(_messenger);\n        OTHER_BRIDGE = StandardBridge(_otherBridge);\n    }\n\n    /**\n     * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n     *         Must be implemented by contracts that inherit.\n     */\n    receive() external payable virtual;\n\n    /**\n     * @notice Sends ETH to the sender's address on the other chain.\n     *\n     * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n     * @param _extraData   Extra data to be sent with the transaction. Note that the recipient will\n     *                     not be triggered with this data, but it will be emitted and can be used\n     *                     to identify the transaction.\n     */\n    function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) public payable onlyEOA {\n        _initiateBridgeETH(msg.sender, msg.sender, msg.value, _minGasLimit, _extraData);\n    }\n\n    /**\n     * @notice Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a\n     *         smart contract and the call fails, the ETH will be temporarily locked in the\n     *         StandardBridge on the other chain until the call is replayed. If the call cannot be\n     *         replayed with any amount of gas (call always reverts), then the ETH will be\n     *         permanently locked in the StandardBridge on the other chain. ETH will also\n     *         be locked if the receiver is the other bridge, because finalizeBridgeETH will revert\n     *         in that case.\n     *\n     * @param _to          Address of the receiver.\n     * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n     * @param _extraData   Extra data to be sent with the transaction. Note that the recipient will\n     *                     not be triggered with this data, but it will be emitted and can be used\n     *                     to identify the transaction.\n     */\n    function bridgeETHTo(\n        address _to,\n        uint32 _minGasLimit,\n        bytes calldata _extraData\n    ) public payable {\n        _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);\n    }\n\n    /**\n     * @notice Sends ERC20 tokens to the sender's address on the other chain. Note that if the\n     *         ERC20 token on the other chain does not recognize the local token as the correct\n     *         pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n     *         this chain.\n     *\n     * @param _localToken  Address of the ERC20 on this chain.\n     * @param _remoteToken Address of the corresponding token on the remote chain.\n     * @param _amount      Amount of local tokens to deposit.\n     * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n     * @param _extraData   Extra data to be sent with the transaction. Note that the recipient will\n     *                     not be triggered with this data, but it will be emitted and can be used\n     *                     to identify the transaction.\n     */\n    function bridgeERC20(\n        address _localToken,\n        address _remoteToken,\n        uint256 _amount,\n        uint32 _minGasLimit,\n        bytes calldata _extraData\n    ) public onlyEOA {\n        _initiateBridgeERC20(\n            _localToken,\n            _remoteToken,\n            msg.sender,\n            msg.sender,\n            _amount,\n            _minGasLimit,\n            _extraData\n        );\n    }\n\n    /**\n     * @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the\n     *         ERC20 token on the other chain does not recognize the local token as the correct\n     *         pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n     *         this chain.\n     *\n     * @param _localToken  Address of the ERC20 on this chain.\n     * @param _remoteToken Address of the corresponding token on the remote chain.\n     * @param _to          Address of the receiver.\n     * @param _amount      Amount of local tokens to deposit.\n     * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n     * @param _extraData   Extra data to be sent with the transaction. Note that the recipient will\n     *                     not be triggered with this data, but it will be emitted and can be used\n     *                     to identify the transaction.\n     */\n    function bridgeERC20To(\n        address _localToken,\n        address _remoteToken,\n        address _to,\n        uint256 _amount,\n        uint32 _minGasLimit,\n        bytes calldata _extraData\n    ) public {\n        _initiateBridgeERC20(\n            _localToken,\n            _remoteToken,\n            msg.sender,\n            _to,\n            _amount,\n            _minGasLimit,\n            _extraData\n        );\n    }\n\n    /**\n     * @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other\n     *         StandardBridge contract on the remote chain.\n     *\n     * @param _from      Address of the sender.\n     * @param _to        Address of the receiver.\n     * @param _amount    Amount of ETH being bridged.\n     * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n     *                   not be triggered with this data, but it will be emitted and can be used\n     *                   to identify the transaction.\n     */\n    function finalizeBridgeETH(\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes calldata _extraData\n    ) public payable onlyOtherBridge {\n        require(msg.value == _amount, \"StandardBridge: amount sent does not match amount required\");\n        require(_to != address(this), \"StandardBridge: cannot send to self\");\n        require(_to != address(MESSENGER), \"StandardBridge: cannot send to messenger\");\n\n        emit ETHBridgeFinalized(_from, _to, _amount, _extraData);\n\n        bool success = SafeCall.call(_to, gasleft(), _amount, hex\"\");\n        require(success, \"StandardBridge: ETH transfer failed\");\n    }\n\n    /**\n     * @notice Finalizes an ERC20 bridge on this chain. Can only be triggered by the other\n     *         StandardBridge contract on the remote chain.\n     *\n     * @param _localToken  Address of the ERC20 on this chain.\n     * @param _remoteToken Address of the corresponding token on the remote chain.\n     * @param _from        Address of the sender.\n     * @param _to          Address of the receiver.\n     * @param _amount      Amount of the ERC20 being bridged.\n     * @param _extraData   Extra data to be sent with the transaction. Note that the recipient will\n     *                     not be triggered with this data, but it will be emitted and can be used\n     *                     to identify the transaction.\n     */\n    function finalizeBridgeERC20(\n        address _localToken,\n        address _remoteToken,\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes calldata _extraData\n    ) public onlyOtherBridge {\n        if (_isKromaMintableERC20(_localToken)) {\n            require(\n                _isCorrectTokenPair(_localToken, _remoteToken),\n                \"StandardBridge: wrong remote token for Kroma Mintable ERC20 local token\"\n            );\n\n            KromaMintableERC20(_localToken).mint(_to, _amount);\n        } else {\n            deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;\n            IERC20(_localToken).safeTransfer(_to, _amount);\n        }\n\n        emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n    }\n\n    /**\n     * @notice Initiates a bridge of ETH through the CrossDomainMessenger.\n     *\n     * @param _from        Address of the sender.\n     * @param _to          Address of the receiver.\n     * @param _amount      Amount of ETH being bridged.\n     * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n     * @param _extraData   Extra data to be sent with the transaction. Note that the recipient will\n     *                     not be triggered with this data, but it will be emitted and can be used\n     *                     to identify the transaction.\n     */\n    function _initiateBridgeETH(\n        address _from,\n        address _to,\n        uint256 _amount,\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) internal {\n        require(\n            msg.value == _amount,\n            \"StandardBridge: bridging ETH must include sufficient ETH value\"\n        );\n\n        emit ETHBridgeInitiated(_from, _to, _amount, _extraData);\n\n        MESSENGER.sendMessage{ value: _amount }(\n            address(OTHER_BRIDGE),\n            abi.encodeWithSelector(\n                this.finalizeBridgeETH.selector,\n                _from,\n                _to,\n                _amount,\n                _extraData\n            ),\n            _minGasLimit\n        );\n    }\n\n    /**\n     * @notice Sends ERC20 tokens to a receiver's address on the other chain.\n     *\n     * @param _localToken  Address of the ERC20 on this chain.\n     * @param _remoteToken Address of the corresponding token on the remote chain.\n     * @param _to          Address of the receiver.\n     * @param _amount      Amount of local tokens to deposit.\n     * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n     * @param _extraData   Extra data to be sent with the transaction. Note that the recipient will\n     *                     not be triggered with this data, but it will be emitted and can be used\n     *                     to identify the transaction.\n     */\n    function _initiateBridgeERC20(\n        address _localToken,\n        address _remoteToken,\n        address _from,\n        address _to,\n        uint256 _amount,\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) internal {\n        if (_isKromaMintableERC20(_localToken)) {\n            require(\n                _isCorrectTokenPair(_localToken, _remoteToken),\n                \"StandardBridge: wrong remote token for Kroma Mintable ERC20 local token\"\n            );\n\n            KromaMintableERC20(_localToken).burn(_from, _amount);\n        } else {\n            IERC20(_localToken).safeTransferFrom(_from, address(this), _amount);\n            deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;\n        }\n\n        emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n\n        MESSENGER.sendMessage(\n            address(OTHER_BRIDGE),\n            abi.encodeWithSelector(\n                this.finalizeBridgeERC20.selector,\n                // Because this call will be executed on the remote chain, we reverse the order of\n                // the remote and local token addresses relative to their order in the\n                // finalizeBridgeERC20 function.\n                _remoteToken,\n                _localToken,\n                _from,\n                _to,\n                _amount,\n                _extraData\n            ),\n            _minGasLimit\n        );\n    }\n\n    /**\n     * @notice Checks if a given address is a KromaMintableERC20. Not perfect, but good enough.\n     *         Just the way we like it.\n     *\n     * @param _token Address of the token to check.\n     *\n     * @return True if the token is a KromaMintableERC20.\n     */\n    function _isKromaMintableERC20(address _token) internal view returns (bool) {\n        return ERC165Checker.supportsInterface(_token, type(IKromaMintableERC20).interfaceId);\n    }\n\n    /**\n     * @notice Checks if the \"other token\" is the correct pair token for the KromaMintableERC20.\n     *\n     * @param _mintableToken KromaMintableERC20 to check against.\n     * @param _otherToken    Pair token to check.\n     *\n     * @return True if the other token is the correct pair token for the KromaMintableERC20.\n     */\n    function _isCorrectTokenPair(address _mintableToken, address _otherToken)\n        internal\n        view\n        returns (bool)\n    {\n        return _otherToken == KromaMintableERC20(_mintableToken).REMOTE_TOKEN();\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "contracts/libraries/Bytes.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Bytes\n * @notice Bytes is a library for manipulating byte arrays.\n */\nlibrary Bytes {\n    /**\n     * @notice Compares two byte arrays by comparing their keccak256 hashes.\n     *\n     * @param _bytes First byte array to compare.\n     * @param _other Second byte array to compare.\n     *\n     * @return True if the two byte arrays are equal, false otherwise.\n     */\n    function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n        return keccak256(_bytes) == keccak256(_other);\n    }\n}\n"
      },
      "contracts/libraries/NodeReader.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title NodeReader\n * @notice NodeReader is a library for reading ZKTrie Node.\n */\nlibrary NodeReader {\n    /**\n     * @notice Node types.\n     *         See https://github.com/kroma-network/zktrie/blob/main/types/README.md.\n     *\n     * @custom:value MIDDLE Represents a middle node.\n     * @custom:value LEAF   Represents a leaf node.\n     * @custom:value EMPTY  Represents a empty node.\n     * @custom:value ROOT   Represents a root node.\n     */\n    enum NodeType {\n        MIDDLE,\n        LEAF,\n        EMPTY,\n        ROOT\n    }\n\n    /**\n     * @notice Struct representing a Node.\n     *         See https://github.com/kroma-network/zktrie/blob/main/types/README.md.\n     */\n    struct Node {\n        NodeType nodeType;\n        bytes32 childL;\n        bytes32 childR;\n        bytes32 nodeKey;\n        bytes32[] valuePreimage;\n        uint32 compressedFlags;\n        bytes32 valueHash;\n        bytes32 keyPreimage;\n    }\n\n    /**\n     * @notice Struct representing an Item.\n     */\n    struct Item {\n        bytes ptr;\n        uint256 len;\n    }\n\n    /**\n     * @notice Converts bytes to Item.\n     *\n     * @param _bytes bytes to convert.\n     *\n     * @return Item referencing _bytes.\n     */\n    function toItem(bytes memory _bytes) internal pure returns (Item memory) {\n        bytes memory ptr;\n        assembly {\n            ptr := add(_bytes, 32)\n        }\n        return Item({ ptr: ptr, len: _bytes.length });\n    }\n\n    /**\n     * @notice Reads an Item into an uint8.\n     *         Internal ptr and length is updated automatically.\n     *\n     * @param _item Item to read.\n     *\n     * @return An uint8 value.\n     */\n    function readUint8(Item memory _item) internal pure returns (uint8) {\n        require(_item.len >= 1, \"NodeReader: too short for uint8\");\n        bytes memory newPtr;\n        bytes memory ptr = _item.ptr;\n        uint8 ret;\n        assembly {\n            ret := shr(248, mload(ptr))\n            newPtr := add(ptr, 1)\n        }\n        _item.ptr = newPtr;\n        _item.len -= 1;\n        return ret;\n    }\n\n    /**\n     * @notice Reads an Item into compressed flags and length of values.\n     *         Internal ptr and length is updated automatically.\n     *\n     * @param _item Item to read.\n     *\n     * @return Compressed flags.\n     * @return Length of values.\n     */\n    function readCompressedFlags(Item memory _item) internal pure returns (uint32, uint8) {\n        require(_item.len >= 4, \"NodeReader: too short for uint32\");\n        bytes memory newPtr;\n        bytes memory ptr = _item.ptr;\n        uint32 temp;\n        uint8 flag;\n        uint8 len;\n        assembly {\n            temp := mload(ptr)\n            len := shr(248, temp)\n            flag := shr(240, temp)\n            newPtr := add(ptr, 4)\n        }\n        _item.ptr = newPtr;\n        _item.len -= 4;\n        return (flag, len);\n    }\n\n    /**\n     * @notice Reads an Item into a bytes32.\n     *         Internal ptr and length is updated automatically.\n     *\n     * @param _item Item to read.\n     *\n     * @return A bytes32 value.\n     */\n    function readBytes32(Item memory _item) internal pure returns (bytes32) {\n        require(_item.len >= 32, \"NodeReader: too short for bytes32\");\n        bytes memory newPtr;\n        bytes memory ptr = _item.ptr;\n        bytes32 ret;\n        assembly {\n            ret := mload(ptr)\n            newPtr := add(ptr, 32)\n        }\n        _item.ptr = newPtr;\n        _item.len -= 32;\n        return ret;\n    }\n\n    /**\n     * @notice Reads an Item by n bytes into a bytes32.\n     *         Internal ptr and length is updated automatically.\n     *\n     * @param _item Item to read.\n     *\n     * @return A bytes32 value.\n     */\n    function readBytesN(Item memory _item, uint256 _length) internal pure returns (bytes32) {\n        require(_item.len >= _length, \"NodeReader: too short for n bytes\");\n        bytes memory newPtr;\n        bytes memory ptr = _item.ptr;\n        bytes32 ret;\n        uint256 to = 256 - _length * 8;\n        assembly {\n            newPtr := add(ptr, _length)\n            ret := shr(to, mload(ptr))\n        }\n        _item.ptr = newPtr;\n        _item.len -= _length;\n        return ret;\n    }\n\n    /**\n     * @notice Reads bytes into a Node.\n     *\n     * @param _proof Bytes to read.\n     *\n     * @return A decoded Node.\n     */\n    function readNode(bytes memory _proof) internal pure returns (Node memory) {\n        Node memory node;\n        Item memory item = toItem(_proof);\n        uint256 nodeType = readUint8(item);\n        if (nodeType == uint256(NodeType.MIDDLE)) {\n            // TODO(chokobole): Do the length check as much as possible at once and read the bytes.\n            node.childL = readBytes32(item);\n            node.childR = readBytes32(item);\n        } else if (nodeType == uint256(NodeType.LEAF)) {\n            // TODO(chokobole): Do the length check as much as possible at once and read the bytes.\n            node.nodeKey = readBytes32(item);\n            (uint32 compressedFlags, uint256 valuePreimageLen) = readCompressedFlags(item);\n            require((compressedFlags == 1 && valuePreimageLen == 1) || (compressedFlags == 4 && valuePreimageLen == 4), \"NodeReader: invalid compressedFlags\");\n            node.compressedFlags = compressedFlags;\n            node.valuePreimage = new bytes32[](valuePreimageLen);\n            for (uint256 i = 0; i < valuePreimageLen; ) {\n                node.valuePreimage[i] = readBytes32(item);\n                unchecked {\n                    ++i;\n                }\n            }\n            uint256 keyPreimageLen = readUint8(item);\n            if (keyPreimageLen > 0) {\n                node.keyPreimage = readBytesN(item, keyPreimageLen);\n            }\n        } else if (nodeType == uint256(NodeType.EMPTY)) {\n            // Do nothing.\n        } else if (nodeType == uint256(NodeType.ROOT)) {\n            revert(\"NodeReader: unexpected root node type\");\n        } else {\n            revert(\"NodeReader: invalid node type\");\n        }\n        node.nodeType = NodeType(nodeType);\n        return node;\n    }\n}\n"
      },
      "contracts/L1/ZKTrieHasher.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport { Bytes32 } from \"../libraries/Bytes32.sol\";\n\n/**\n * @title IPoseidon2\n */\ninterface IPoseidon2 {\n    function poseidon(bytes32[2] memory inputs) external pure returns (bytes32);\n}\n\n/**\n * @custom:proxied\n * @title ZKTrieHasher\n * @notice The ZKTrieHasher is contract which can produce a hash according to ZKTrie.\n *         This owns an interface of Poseidon2 that is required to compute hash used by ZKTrie.\n */\ncontract ZKTrieHasher {\n    /**\n     * @notice Poseidon2 contract generated by circomlibjs.\n     */\n    IPoseidon2 public immutable POSEIDON2;\n\n    /**\n     * @param _poseidon2 The address of poseidon2 contract.\n     */\n    constructor(address _poseidon2) {\n        POSEIDON2 = IPoseidon2(_poseidon2);\n    }\n\n    /**\n     * @notice Computes a hash of values.\n     *\n     * @param _compressedFlags Compressed flags.\n     * @param _values          Values.\n     *\n     * @return A hash of values.\n     */\n    function _valueHash(uint32 _compressedFlags, bytes32[] memory _values)\n        internal\n        view\n        returns (bytes32)\n    {\n        require(_values.length >= 1, \"ZKTrieHasher: too few values for _valueHash\");\n        bytes32[] memory ret = new bytes32[](_values.length);\n        for (uint256 i = 0; i < _values.length; ) {\n            if ((_compressedFlags & (1 << i)) != 0) {\n                ret[i] = _hashElem(_values[i]);\n            } else {\n                ret[i] = _values[i];\n            }\n            unchecked {\n                ++i;\n            }\n        }\n        if (_values.length < 2) {\n            return ret[0];\n        }\n        return _hashElems(ret);\n    }\n\n    /**\n     * @notice Computes a hash of an element.\n     *\n     * @param _elem Bytes32 to be hashed.\n     *\n     * @return A hash of an element.\n     */\n    function _hashElem(bytes32 _elem) internal view returns (bytes32) {\n        (bytes32 high, bytes32 low) = Bytes32.split(_elem);\n        return POSEIDON2.poseidon([high, low]);\n    }\n\n    /**\n     * @notice Computes a root hash of elements tree.\n     *\n     * @param _elems Bytes32 array to be hashed.\n     *\n     * @return A hash of elements tree.\n     */\n    function _hashElems(bytes32[] memory _elems) internal view returns (bytes32) {\n        require(_elems.length >= 4, \"ZKTrieHasher: too few values for _hashElems\");\n        IPoseidon2 iposeidon = POSEIDON2;\n\n        uint256 idx;\n        uint256 adjacent_idx;\n\n        uint256 adjacent_offset = 1;\n        uint256 jump = 2;\n        uint256 length = _elems.length;\n        for (; adjacent_offset < length;) {\n            for (idx = 0; idx < length;) {\n                unchecked {\n                    adjacent_idx = idx + adjacent_offset;\n                }\n                if (adjacent_idx < length) {\n                    _elems[idx] = iposeidon.poseidon( [_elems[idx], _elems[adjacent_idx]] );\n                }\n                unchecked {\n                    idx += jump;\n                }\n            }\n            adjacent_offset = jump;\n            jump <<= 1;\n        }\n\n        return _elems[0];\n    }\n\n    /**\n     * @notice Computes a root hash of 2 elements.\n     *\n     * @param left_leaf  Bytes32 left leaf to be hashed.\n     * @param right_leaf Bytes32 right leaf to be hashed.\n     *\n     * @return A hash of 2 elements.\n     */\n    function _hashFixed2Elems(bytes32 left_leaf, bytes32 right_leaf) internal view returns (bytes32) {\n        return POSEIDON2.poseidon([left_leaf, right_leaf]);\n    }\n\n   /**\n     * @notice Computes a root hash of 3 elements.\n     *\n     * @param left_leaf  Bytes32 left leaf to be hashed.\n     * @param right_leaf Bytes32 right leaf to be hashed.\n     * @param up_leaf    Bytes32 up leaf to be hashed with left||right hash.\n     *\n     * @return A hash of 3 elements.\n     */\n    function _hashFixed3Elems(bytes32 left_leaf, bytes32 right_leaf, bytes32 up_leaf) internal view returns (bytes32) {\n        IPoseidon2 iposeidon = POSEIDON2;\n        left_leaf = iposeidon.poseidon([left_leaf, right_leaf]);\n        return iposeidon.poseidon([left_leaf, up_leaf]);\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n    /**\n     * @dev Handles the receipt of a single ERC1155 token type. This function is\n     * called at the end of a `safeTransferFrom` after the balance has been updated.\n     *\n     * NOTE: To accept the transfer, this must return\n     * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n     * (i.e. 0xf23a6e61, or its own function selector).\n     *\n     * @param operator The address which initiated the transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param id The ID of the token being transferred\n     * @param value The amount of tokens being transferred\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n     */\n    function onERC1155Received(\n        address operator,\n        address from,\n        uint256 id,\n        uint256 value,\n        bytes calldata data\n    ) external returns (bytes4);\n\n    /**\n     * @dev Handles the receipt of a multiple ERC1155 token types. This function\n     * is called at the end of a `safeBatchTransferFrom` after the balances have\n     * been updated.\n     *\n     * NOTE: To accept the transfer(s), this must return\n     * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n     * (i.e. 0xbc197c81, or its own function selector).\n     *\n     * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param ids An array containing ids of each token being transferred (order and length must match values array)\n     * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n     */\n    function onERC1155BatchReceived(\n        address operator,\n        address from,\n        uint256[] calldata ids,\n        uint256[] calldata values,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV // Deprecated in v4.8\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            /// @solidity memory-safe-assembly\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n            mstore(0x1c, hash)\n            message := keccak256(0x00, 0x3c)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, \"\\x19\\x01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            data := keccak256(ptr, 0x42)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Data with intended validator, created from a\n     * `validator` and `data` according to the version 0 of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n    bytes32 private constant _TYPE_HASH =\n        keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n    /// @custom:oz-renamed-from _HASHED_NAME\n    bytes32 private _hashedName;\n    /// @custom:oz-renamed-from _HASHED_VERSION\n    bytes32 private _hashedVersion;\n\n    string private _name;\n    string private _version;\n\n    /**\n     * @dev Initializes the domain separator and parameter caches.\n     *\n     * The meaning of `name` and `version` is specified in\n     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n     *\n     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n     * - `version`: the current major version of the signing domain.\n     *\n     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n     * contract upgrade].\n     */\n    function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n        __EIP712_init_unchained(name, version);\n    }\n\n    function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n        _name = name;\n        _version = version;\n\n        // Reset prior values in storage if upgrading\n        _hashedName = 0;\n        _hashedVersion = 0;\n    }\n\n    /**\n     * @dev Returns the domain separator for the current chain.\n     */\n    function _domainSeparatorV4() internal view returns (bytes32) {\n        return _buildDomainSeparator();\n    }\n\n    function _buildDomainSeparator() private view returns (bytes32) {\n        return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n    }\n\n    /**\n     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n     * function returns the hash of the fully encoded EIP712 message for this domain.\n     *\n     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n     *\n     * ```solidity\n     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n     *     keccak256(\"Mail(address to,string contents)\"),\n     *     mailTo,\n     *     keccak256(bytes(mailContents))\n     * )));\n     * address signer = ECDSA.recover(digest, signature);\n     * ```\n     */\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n        return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n    }\n\n    /**\n     * @dev See {EIP-5267}.\n     *\n     * _Available since v4.9._\n     */\n    function eip712Domain()\n        public\n        view\n        virtual\n        override\n        returns (\n            bytes1 fields,\n            string memory name,\n            string memory version,\n            uint256 chainId,\n            address verifyingContract,\n            bytes32 salt,\n            uint256[] memory extensions\n        )\n    {\n        // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n        // and the EIP712 domain is not reliable, as it will be missing name and version.\n        require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n        return (\n            hex\"0f\", // 01111\n            _EIP712Name(),\n            _EIP712Version(),\n            block.chainid,\n            address(this),\n            bytes32(0),\n            new uint256[](0)\n        );\n    }\n\n    /**\n     * @dev The name parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712Name() internal virtual view returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev The version parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712Version() internal virtual view returns (string memory) {\n        return _version;\n    }\n\n    /**\n     * @dev The hash of the name parameter for the EIP712 domain.\n     *\n     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n     */\n    function _EIP712NameHash() internal view returns (bytes32) {\n        string memory name = _EIP712Name();\n        if (bytes(name).length > 0) {\n            return keccak256(bytes(name));\n        } else {\n            // If the name is empty, the contract may have been upgraded without initializing the new storage.\n            // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n            bytes32 hashedName = _hashedName;\n            if (hashedName != 0) {\n                return hashedName;\n            } else {\n                return keccak256(\"\");\n            }\n        }\n    }\n\n    /**\n     * @dev The hash of the version parameter for the EIP712 domain.\n     *\n     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n     */\n    function _EIP712VersionHash() internal view returns (bytes32) {\n        string memory version = _EIP712Version();\n        if (bytes(version).length > 0) {\n            return keccak256(bytes(version));\n        } else {\n            // If the version is empty, the contract may have been upgraded without initializing the new storage.\n            // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n            bytes32 hashedVersion = _hashedVersion;\n            if (hashedVersion != 0) {\n                return hashedVersion;\n            } else {\n                return keccak256(\"\");\n            }\n        }\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[48] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165Upgradeable).interfaceId;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```solidity\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n    /**\n     * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n     */\n    error Empty();\n\n    /**\n     * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n     */\n    error OutOfBounds();\n\n    /**\n     * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n     * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n     * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n     *\n     * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n     * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n     * lead to unexpected behavior.\n     *\n     * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n     * data[end - 1].\n     */\n    struct Bytes32Deque {\n        int128 _begin;\n        int128 _end;\n        mapping(int128 => bytes32) _data;\n    }\n\n    /**\n     * @dev Inserts an item at the end of the queue.\n     */\n    function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n        int128 backIndex = deque._end;\n        deque._data[backIndex] = value;\n        unchecked {\n            deque._end = backIndex + 1;\n        }\n    }\n\n    /**\n     * @dev Removes the item at the end of the queue and returns it.\n     *\n     * Reverts with `Empty` if the queue is empty.\n     */\n    function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n        if (empty(deque)) revert Empty();\n        int128 backIndex;\n        unchecked {\n            backIndex = deque._end - 1;\n        }\n        value = deque._data[backIndex];\n        delete deque._data[backIndex];\n        deque._end = backIndex;\n    }\n\n    /**\n     * @dev Inserts an item at the beginning of the queue.\n     */\n    function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n        int128 frontIndex;\n        unchecked {\n            frontIndex = deque._begin - 1;\n        }\n        deque._data[frontIndex] = value;\n        deque._begin = frontIndex;\n    }\n\n    /**\n     * @dev Removes the item at the beginning of the queue and returns it.\n     *\n     * Reverts with `Empty` if the queue is empty.\n     */\n    function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n        if (empty(deque)) revert Empty();\n        int128 frontIndex = deque._begin;\n        value = deque._data[frontIndex];\n        delete deque._data[frontIndex];\n        unchecked {\n            deque._begin = frontIndex + 1;\n        }\n    }\n\n    /**\n     * @dev Returns the item at the beginning of the queue.\n     *\n     * Reverts with `Empty` if the queue is empty.\n     */\n    function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n        if (empty(deque)) revert Empty();\n        int128 frontIndex = deque._begin;\n        return deque._data[frontIndex];\n    }\n\n    /**\n     * @dev Returns the item at the end of the queue.\n     *\n     * Reverts with `Empty` if the queue is empty.\n     */\n    function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n        if (empty(deque)) revert Empty();\n        int128 backIndex;\n        unchecked {\n            backIndex = deque._end - 1;\n        }\n        return deque._data[backIndex];\n    }\n\n    /**\n     * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n     * `length(deque) - 1`.\n     *\n     * Reverts with `OutOfBounds` if the index is out of bounds.\n     */\n    function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n        // int256(deque._begin) is a safe upcast\n        int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n        if (idx >= deque._end) revert OutOfBounds();\n        return deque._data[idx];\n    }\n\n    /**\n     * @dev Resets the queue back to being empty.\n     *\n     * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n     * out on potential gas refunds.\n     */\n    function clear(Bytes32Deque storage deque) internal {\n        deque._begin = 0;\n        deque._end = 0;\n    }\n\n    /**\n     * @dev Returns the number of items in the queue.\n     */\n    function length(Bytes32Deque storage deque) internal view returns (uint256) {\n        // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n        // We also assume there are at most int256.max items in the queue.\n        unchecked {\n            return uint256(int256(deque._end) - int256(deque._begin));\n        }\n    }\n\n    /**\n     * @dev Returns true if the queue is empty.\n     */\n    function empty(Bytes32Deque storage deque) internal view returns (bool) {\n        return deque._end <= deque._begin;\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/IGovernorUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/IGovernor.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IERC165Upgradeable.sol\";\nimport \"../interfaces/IERC6372Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Interface of the {Governor} core.\n *\n * _Available since v4.3._\n */\nabstract contract IGovernorUpgradeable is Initializable, IERC165Upgradeable, IERC6372Upgradeable {\n    function __IGovernor_init() internal onlyInitializing {\n    }\n\n    function __IGovernor_init_unchained() internal onlyInitializing {\n    }\n    enum ProposalState {\n        Pending,\n        Active,\n        Canceled,\n        Defeated,\n        Succeeded,\n        Queued,\n        Expired,\n        Executed\n    }\n\n    /**\n     * @dev Emitted when a proposal is created.\n     */\n    event ProposalCreated(\n        uint256 proposalId,\n        address proposer,\n        address[] targets,\n        uint256[] values,\n        string[] signatures,\n        bytes[] calldatas,\n        uint256 voteStart,\n        uint256 voteEnd,\n        string description\n    );\n\n    /**\n     * @dev Emitted when a proposal is canceled.\n     */\n    event ProposalCanceled(uint256 proposalId);\n\n    /**\n     * @dev Emitted when a proposal is executed.\n     */\n    event ProposalExecuted(uint256 proposalId);\n\n    /**\n     * @dev Emitted when a vote is cast without params.\n     *\n     * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used.\n     */\n    event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);\n\n    /**\n     * @dev Emitted when a vote is cast with params.\n     *\n     * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used.\n     * `params` are additional encoded parameters. Their interpepretation also depends on the voting module used.\n     */\n    event VoteCastWithParams(\n        address indexed voter,\n        uint256 proposalId,\n        uint8 support,\n        uint256 weight,\n        string reason,\n        bytes params\n    );\n\n    /**\n     * @notice module:core\n     * @dev Name of the governor instance (used in building the ERC712 domain separator).\n     */\n    function name() public view virtual returns (string memory);\n\n    /**\n     * @notice module:core\n     * @dev Version of the governor instance (used in building the ERC712 domain separator). Default: \"1\"\n     */\n    function version() public view virtual returns (string memory);\n\n    /**\n     * @notice module:core\n     * @dev See {IERC6372}\n     */\n    function clock() public view virtual override returns (uint48);\n\n    /**\n     * @notice module:core\n     * @dev See EIP-6372.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function CLOCK_MODE() public view virtual override returns (string memory);\n\n    /**\n     * @notice module:voting\n     * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to\n     * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of\n     * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`.\n     *\n     * There are 2 standard keys: `support` and `quorum`.\n     *\n     * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`.\n     * - `quorum=bravo` means that only For votes are counted towards quorum.\n     * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum.\n     *\n     * If a counting module makes use of encoded `params`, it should  include this under a `params` key with a unique\n     * name that describes the behavior. For example:\n     *\n     * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain.\n     * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote.\n     *\n     * NOTE: The string can be decoded by the standard\n     * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`]\n     * JavaScript class.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function COUNTING_MODE() public view virtual returns (string memory);\n\n    /**\n     * @notice module:core\n     * @dev Hashing function used to (re)build the proposal id from the proposal details..\n     */\n    function hashProposal(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) public pure virtual returns (uint256);\n\n    /**\n     * @notice module:core\n     * @dev Current state of a proposal, following Compound's convention\n     */\n    function state(uint256 proposalId) public view virtual returns (ProposalState);\n\n    /**\n     * @notice module:core\n     * @dev Timepoint used to retrieve user's votes and quorum. If using block number (as per Compound's Comp), the\n     * snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the\n     * following block.\n     */\n    function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);\n\n    /**\n     * @notice module:core\n     * @dev Timepoint at which votes close. If using block number, votes close at the end of this block, so it is\n     * possible to cast a vote during this block.\n     */\n    function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);\n\n    /**\n     * @notice module:core\n     * @dev The account that created a proposal.\n     */\n    function proposalProposer(uint256 proposalId) public view virtual returns (address);\n\n    /**\n     * @notice module:user-config\n     * @dev Delay, between the proposal is created and the vote starts. The unit this duration is expressed in depends\n     * on the clock (see EIP-6372) this contract uses.\n     *\n     * This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a\n     * proposal starts.\n     */\n    function votingDelay() public view virtual returns (uint256);\n\n    /**\n     * @notice module:user-config\n     * @dev Delay between the vote start and vote end. The unit this duration is expressed in depends on the clock\n     * (see EIP-6372) this contract uses.\n     *\n     * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting\n     * duration compared to the voting delay.\n     */\n    function votingPeriod() public view virtual returns (uint256);\n\n    /**\n     * @notice module:user-config\n     * @dev Minimum number of cast voted required for a proposal to be successful.\n     *\n     * NOTE: The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows to scale the\n     * quorum depending on values such as the totalSupply of a token at this timepoint (see {ERC20Votes}).\n     */\n    function quorum(uint256 timepoint) public view virtual returns (uint256);\n\n    /**\n     * @notice module:reputation\n     * @dev Voting power of an `account` at a specific `timepoint`.\n     *\n     * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or\n     * multiple), {ERC20Votes} tokens.\n     */\n    function getVotes(address account, uint256 timepoint) public view virtual returns (uint256);\n\n    /**\n     * @notice module:reputation\n     * @dev Voting power of an `account` at a specific `timepoint` given additional encoded parameters.\n     */\n    function getVotesWithParams(\n        address account,\n        uint256 timepoint,\n        bytes memory params\n    ) public view virtual returns (uint256);\n\n    /**\n     * @notice module:voting\n     * @dev Returns whether `account` has cast a vote on `proposalId`.\n     */\n    function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);\n\n    /**\n     * @dev Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a\n     * duration specified by {IGovernor-votingPeriod}.\n     *\n     * Emits a {ProposalCreated} event.\n     */\n    function propose(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        string memory description\n    ) public virtual returns (uint256 proposalId);\n\n    /**\n     * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the\n     * deadline to be reached.\n     *\n     * Emits a {ProposalExecuted} event.\n     *\n     * Note: some module can modify the requirements for execution, for example by adding an additional timelock.\n     */\n    function execute(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) public payable virtual returns (uint256 proposalId);\n\n    /**\n     * @dev Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e.\n     * before the vote starts.\n     *\n     * Emits a {ProposalCanceled} event.\n     */\n    function cancel(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) public virtual returns (uint256 proposalId);\n\n    /**\n     * @dev Cast a vote\n     *\n     * Emits a {VoteCast} event.\n     */\n    function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance);\n\n    /**\n     * @dev Cast a vote with a reason\n     *\n     * Emits a {VoteCast} event.\n     */\n    function castVoteWithReason(\n        uint256 proposalId,\n        uint8 support,\n        string calldata reason\n    ) public virtual returns (uint256 balance);\n\n    /**\n     * @dev Cast a vote with a reason and additional encoded parameters\n     *\n     * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params.\n     */\n    function castVoteWithReasonAndParams(\n        uint256 proposalId,\n        uint8 support,\n        string calldata reason,\n        bytes memory params\n    ) public virtual returns (uint256 balance);\n\n    /**\n     * @dev Cast a vote using the user's cryptographic signature.\n     *\n     * Emits a {VoteCast} event.\n     */\n    function castVoteBySig(\n        uint256 proposalId,\n        uint8 support,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual returns (uint256 balance);\n\n    /**\n     * @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature.\n     *\n     * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params.\n     */\n    function castVoteWithReasonAndParamsBySig(\n        uint256 proposalId,\n        uint8 support,\n        string calldata reason,\n        bytes memory params,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual returns (uint256 balance);\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/CheckpointsUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Checkpoints.sol)\n// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\nimport \"./math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev This library defines the `History` struct, for checkpointing values as they change at different points in\n * time, and later looking up past values by block number. See {Votes} as an example.\n *\n * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new\n * checkpoint for the current transaction block using the {push} function.\n *\n * _Available since v4.5._\n */\nlibrary CheckpointsUpgradeable {\n    struct History {\n        Checkpoint[] _checkpoints;\n    }\n\n    struct Checkpoint {\n        uint32 _blockNumber;\n        uint224 _value;\n    }\n\n    /**\n     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one\n     * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the\n     * block, the requested block number must be in the past, excluding the current block.\n     */\n    function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {\n        require(blockNumber < block.number, \"Checkpoints: block not yet mined\");\n        uint32 key = SafeCastUpgradeable.toUint32(blockNumber);\n\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one\n     * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched\n     * checkpoint is probably \"recent\", defined as being among the last sqrt(N) checkpoints where N is the number of\n     * checkpoints.\n     */\n    function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {\n        require(blockNumber < block.number, \"Checkpoints: block not yet mined\");\n        uint32 key = SafeCastUpgradeable.toUint32(blockNumber);\n\n        uint256 len = self._checkpoints.length;\n\n        uint256 low = 0;\n        uint256 high = len;\n\n        if (len > 5) {\n            uint256 mid = len - MathUpgradeable.sqrt(len);\n            if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block.\n     *\n     * Returns previous value and new value.\n     */\n    function push(History storage self, uint256 value) internal returns (uint256, uint256) {\n        return _insert(self._checkpoints, SafeCastUpgradeable.toUint32(block.number), SafeCastUpgradeable.toUint224(value));\n    }\n\n    /**\n     * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will\n     * be set to `op(latest, delta)`.\n     *\n     * Returns previous value and new value.\n     */\n    function push(\n        History storage self,\n        function(uint256, uint256) view returns (uint256) op,\n        uint256 delta\n    ) internal returns (uint256, uint256) {\n        return push(self, op(latest(self), delta));\n    }\n\n    /**\n     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n     */\n    function latest(History storage self) internal view returns (uint224) {\n        uint256 pos = self._checkpoints.length;\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n     * in the most recent checkpoint.\n     */\n    function latestCheckpoint(\n        History storage self\n    ) internal view returns (bool exists, uint32 _blockNumber, uint224 _value) {\n        uint256 pos = self._checkpoints.length;\n        if (pos == 0) {\n            return (false, 0, 0);\n        } else {\n            Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n            return (true, ckpt._blockNumber, ckpt._value);\n        }\n    }\n\n    /**\n     * @dev Returns the number of checkpoint.\n     */\n    function length(History storage self) internal view returns (uint256) {\n        return self._checkpoints.length;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n     * or by updating the last one.\n     */\n    function _insert(Checkpoint[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {\n        uint256 pos = self.length;\n\n        if (pos > 0) {\n            // Copying to memory is important here.\n            Checkpoint memory last = _unsafeAccess(self, pos - 1);\n\n            // Checkpoint keys must be non-decreasing.\n            require(last._blockNumber <= key, \"Checkpoint: decreasing keys\");\n\n            // Update or push new checkpoint\n            if (last._blockNumber == key) {\n                _unsafeAccess(self, pos - 1)._value = value;\n            } else {\n                self.push(Checkpoint({_blockNumber: key, _value: value}));\n            }\n            return (last._value, value);\n        } else {\n            self.push(Checkpoint({_blockNumber: key, _value: value}));\n            return (0, value);\n        }\n    }\n\n    /**\n     * @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.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _upperBinaryLookup(\n        Checkpoint[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._blockNumber > key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @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.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _lowerBinaryLookup(\n        Checkpoint[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._blockNumber < key) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n     */\n    function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {\n        assembly {\n            mstore(0, self.slot)\n            result.slot := add(keccak256(0, 0x20), pos)\n        }\n    }\n\n    struct Trace224 {\n        Checkpoint224[] _checkpoints;\n    }\n\n    struct Checkpoint224 {\n        uint32 _key;\n        uint224 _value;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.\n     *\n     * Returns previous value and new value.\n     */\n    function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {\n        return _insert(self._checkpoints, key, value);\n    }\n\n    /**\n     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.\n     */\n    function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\n    }\n\n    /**\n     * @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.\n     */\n    function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @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.\n     *\n     * NOTE: This is a variant of {upperLookup} that is optimised to find \"recent\" checkpoint (checkpoints with high keys).\n     */\n    function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {\n        uint256 len = self._checkpoints.length;\n\n        uint256 low = 0;\n        uint256 high = len;\n\n        if (len > 5) {\n            uint256 mid = len - MathUpgradeable.sqrt(len);\n            if (key < _unsafeAccess(self._checkpoints, mid)._key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n     */\n    function latest(Trace224 storage self) internal view returns (uint224) {\n        uint256 pos = self._checkpoints.length;\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n     * in the most recent checkpoint.\n     */\n    function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {\n        uint256 pos = self._checkpoints.length;\n        if (pos == 0) {\n            return (false, 0, 0);\n        } else {\n            Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n            return (true, ckpt._key, ckpt._value);\n        }\n    }\n\n    /**\n     * @dev Returns the number of checkpoint.\n     */\n    function length(Trace224 storage self) internal view returns (uint256) {\n        return self._checkpoints.length;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n     * or by updating the last one.\n     */\n    function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {\n        uint256 pos = self.length;\n\n        if (pos > 0) {\n            // Copying to memory is important here.\n            Checkpoint224 memory last = _unsafeAccess(self, pos - 1);\n\n            // Checkpoint keys must be non-decreasing.\n            require(last._key <= key, \"Checkpoint: decreasing keys\");\n\n            // Update or push new checkpoint\n            if (last._key == key) {\n                _unsafeAccess(self, pos - 1)._value = value;\n            } else {\n                self.push(Checkpoint224({_key: key, _value: value}));\n            }\n            return (last._value, value);\n        } else {\n            self.push(Checkpoint224({_key: key, _value: value}));\n            return (0, value);\n        }\n    }\n\n    /**\n     * @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.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _upperBinaryLookup(\n        Checkpoint224[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._key > key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @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.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _lowerBinaryLookup(\n        Checkpoint224[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._key < key) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n     */\n    function _unsafeAccess(\n        Checkpoint224[] storage self,\n        uint256 pos\n    ) private pure returns (Checkpoint224 storage result) {\n        assembly {\n            mstore(0, self.slot)\n            result.slot := add(keccak256(0, 0x20), pos)\n        }\n    }\n\n    struct Trace160 {\n        Checkpoint160[] _checkpoints;\n    }\n\n    struct Checkpoint160 {\n        uint96 _key;\n        uint160 _value;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.\n     *\n     * Returns previous value and new value.\n     */\n    function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {\n        return _insert(self._checkpoints, key, value);\n    }\n\n    /**\n     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.\n     */\n    function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\n    }\n\n    /**\n     * @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.\n     */\n    function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @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.\n     *\n     * NOTE: This is a variant of {upperLookup} that is optimised to find \"recent\" checkpoint (checkpoints with high keys).\n     */\n    function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {\n        uint256 len = self._checkpoints.length;\n\n        uint256 low = 0;\n        uint256 high = len;\n\n        if (len > 5) {\n            uint256 mid = len - MathUpgradeable.sqrt(len);\n            if (key < _unsafeAccess(self._checkpoints, mid)._key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n     */\n    function latest(Trace160 storage self) internal view returns (uint160) {\n        uint256 pos = self._checkpoints.length;\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n     * in the most recent checkpoint.\n     */\n    function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {\n        uint256 pos = self._checkpoints.length;\n        if (pos == 0) {\n            return (false, 0, 0);\n        } else {\n            Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n            return (true, ckpt._key, ckpt._value);\n        }\n    }\n\n    /**\n     * @dev Returns the number of checkpoint.\n     */\n    function length(Trace160 storage self) internal view returns (uint256) {\n        return self._checkpoints.length;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n     * or by updating the last one.\n     */\n    function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {\n        uint256 pos = self.length;\n\n        if (pos > 0) {\n            // Copying to memory is important here.\n            Checkpoint160 memory last = _unsafeAccess(self, pos - 1);\n\n            // Checkpoint keys must be non-decreasing.\n            require(last._key <= key, \"Checkpoint: decreasing keys\");\n\n            // Update or push new checkpoint\n            if (last._key == key) {\n                _unsafeAccess(self, pos - 1)._value = value;\n            } else {\n                self.push(Checkpoint160({_key: key, _value: value}));\n            }\n            return (last._value, value);\n        } else {\n            self.push(Checkpoint160({_key: key, _value: value}));\n            return (0, value);\n        }\n    }\n\n    /**\n     * @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.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _upperBinaryLookup(\n        Checkpoint160[] storage self,\n        uint96 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._key > key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @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.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _lowerBinaryLookup(\n        Checkpoint160[] storage self,\n        uint96 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._key < key) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n     */\n    function _unsafeAccess(\n        Checkpoint160[] storage self,\n        uint256 pos\n    ) private pure returns (Checkpoint160 storage result) {\n        assembly {\n            mstore(0, self.slot)\n            result.slot := add(keccak256(0, 0x20), pos)\n        }\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/extensions/IGovernorTimelockUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (governance/extensions/IGovernorTimelock.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IGovernorUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of the {IGovernor} for timelock supporting modules.\n *\n * _Available since v4.3._\n */\nabstract contract IGovernorTimelockUpgradeable is Initializable, IGovernorUpgradeable {\n    function __IGovernorTimelock_init() internal onlyInitializing {\n    }\n\n    function __IGovernorTimelock_init_unchained() internal onlyInitializing {\n    }\n    event ProposalQueued(uint256 proposalId, uint256 eta);\n\n    function timelock() public view virtual returns (address);\n\n    function proposalEta(uint256 proposalId) public view virtual returns (uint256);\n\n    function queue(\n        address[] memory targets,\n        uint256[] memory values,\n        bytes[] memory calldatas,\n        bytes32 descriptionHash\n    ) public virtual returns (uint256 proposalId);\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/governance/TimelockControllerUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/TimelockController.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../access/AccessControlUpgradeable.sol\";\nimport \"../token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"../token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which acts as a timelocked controller. When set as the\n * owner of an `Ownable` smart contract, it enforces a timelock on all\n * `onlyOwner` maintenance operations. This gives time for users of the\n * controlled contract to exit before a potentially dangerous maintenance\n * operation is applied.\n *\n * By default, this contract is self administered, meaning administration tasks\n * have to go through the timelock process. The proposer (resp executor) role\n * is in charge of proposing (resp executing) operations. A common use case is\n * to position this {TimelockController} as the owner of a smart contract, with\n * a multisig or a DAO as the sole proposer.\n *\n * _Available since v3.3._\n */\ncontract TimelockControllerUpgradeable is Initializable, AccessControlUpgradeable, IERC721ReceiverUpgradeable, IERC1155ReceiverUpgradeable {\n    bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256(\"TIMELOCK_ADMIN_ROLE\");\n    bytes32 public constant PROPOSER_ROLE = keccak256(\"PROPOSER_ROLE\");\n    bytes32 public constant EXECUTOR_ROLE = keccak256(\"EXECUTOR_ROLE\");\n    bytes32 public constant CANCELLER_ROLE = keccak256(\"CANCELLER_ROLE\");\n    uint256 internal constant _DONE_TIMESTAMP = uint256(1);\n\n    mapping(bytes32 => uint256) private _timestamps;\n    uint256 private _minDelay;\n\n    /**\n     * @dev Emitted when a call is scheduled as part of operation `id`.\n     */\n    event CallScheduled(\n        bytes32 indexed id,\n        uint256 indexed index,\n        address target,\n        uint256 value,\n        bytes data,\n        bytes32 predecessor,\n        uint256 delay\n    );\n\n    /**\n     * @dev Emitted when a call is performed as part of operation `id`.\n     */\n    event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);\n\n    /**\n     * @dev Emitted when new proposal is scheduled with non-zero salt.\n     */\n    event CallSalt(bytes32 indexed id, bytes32 salt);\n\n    /**\n     * @dev Emitted when operation `id` is cancelled.\n     */\n    event Cancelled(bytes32 indexed id);\n\n    /**\n     * @dev Emitted when the minimum delay for future operations is modified.\n     */\n    event MinDelayChange(uint256 oldDuration, uint256 newDuration);\n\n    /**\n     * @dev Initializes the contract with the following parameters:\n     *\n     * - `minDelay`: initial minimum delay for operations\n     * - `proposers`: accounts to be granted proposer and canceller roles\n     * - `executors`: accounts to be granted executor role\n     * - `admin`: optional account to be granted admin role; disable with zero address\n     *\n     * IMPORTANT: The optional admin can aid with initial configuration of roles after deployment\n     * without being subject to delay, but this role should be subsequently renounced in favor of\n     * administration through timelocked proposals. Previous versions of this contract would assign\n     * this admin to the deployer automatically and should be renounced as well.\n     */\n    function __TimelockController_init(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) internal onlyInitializing {\n        __TimelockController_init_unchained(minDelay, proposers, executors, admin);\n    }\n\n    function __TimelockController_init_unchained(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) internal onlyInitializing {\n        _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);\n        _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);\n        _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);\n        _setRoleAdmin(CANCELLER_ROLE, TIMELOCK_ADMIN_ROLE);\n\n        // self administration\n        _setupRole(TIMELOCK_ADMIN_ROLE, address(this));\n\n        // optional admin\n        if (admin != address(0)) {\n            _setupRole(TIMELOCK_ADMIN_ROLE, admin);\n        }\n\n        // register proposers and cancellers\n        for (uint256 i = 0; i < proposers.length; ++i) {\n            _setupRole(PROPOSER_ROLE, proposers[i]);\n            _setupRole(CANCELLER_ROLE, proposers[i]);\n        }\n\n        // register executors\n        for (uint256 i = 0; i < executors.length; ++i) {\n            _setupRole(EXECUTOR_ROLE, executors[i]);\n        }\n\n        _minDelay = minDelay;\n        emit MinDelayChange(0, minDelay);\n    }\n\n    /**\n     * @dev Modifier to make a function callable only by a certain role. In\n     * addition to checking the sender's role, `address(0)` 's role is also\n     * considered. Granting a role to `address(0)` is equivalent to enabling\n     * this role for everyone.\n     */\n    modifier onlyRoleOrOpenRole(bytes32 role) {\n        if (!hasRole(role, address(0))) {\n            _checkRole(role, _msgSender());\n        }\n        _;\n    }\n\n    /**\n     * @dev Contract might receive/hold ETH as part of the maintenance process.\n     */\n    receive() external payable {}\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, AccessControlUpgradeable) returns (bool) {\n        return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns whether an id correspond to a registered operation. This\n     * includes both Pending, Ready and Done operations.\n     */\n    function isOperation(bytes32 id) public view virtual returns (bool) {\n        return getTimestamp(id) > 0;\n    }\n\n    /**\n     * @dev Returns whether an operation is pending or not. Note that a \"pending\" operation may also be \"ready\".\n     */\n    function isOperationPending(bytes32 id) public view virtual returns (bool) {\n        return getTimestamp(id) > _DONE_TIMESTAMP;\n    }\n\n    /**\n     * @dev Returns whether an operation is ready for execution. Note that a \"ready\" operation is also \"pending\".\n     */\n    function isOperationReady(bytes32 id) public view virtual returns (bool) {\n        uint256 timestamp = getTimestamp(id);\n        return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;\n    }\n\n    /**\n     * @dev Returns whether an operation is done or not.\n     */\n    function isOperationDone(bytes32 id) public view virtual returns (bool) {\n        return getTimestamp(id) == _DONE_TIMESTAMP;\n    }\n\n    /**\n     * @dev Returns the timestamp at which an operation becomes ready (0 for\n     * unset operations, 1 for done operations).\n     */\n    function getTimestamp(bytes32 id) public view virtual returns (uint256) {\n        return _timestamps[id];\n    }\n\n    /**\n     * @dev Returns the minimum delay for an operation to become valid.\n     *\n     * This value can be changed by executing an operation that calls `updateDelay`.\n     */\n    function getMinDelay() public view virtual returns (uint256) {\n        return _minDelay;\n    }\n\n    /**\n     * @dev Returns the identifier of an operation containing a single\n     * transaction.\n     */\n    function hashOperation(\n        address target,\n        uint256 value,\n        bytes calldata data,\n        bytes32 predecessor,\n        bytes32 salt\n    ) public pure virtual returns (bytes32) {\n        return keccak256(abi.encode(target, value, data, predecessor, salt));\n    }\n\n    /**\n     * @dev Returns the identifier of an operation containing a batch of\n     * transactions.\n     */\n    function hashOperationBatch(\n        address[] calldata targets,\n        uint256[] calldata values,\n        bytes[] calldata payloads,\n        bytes32 predecessor,\n        bytes32 salt\n    ) public pure virtual returns (bytes32) {\n        return keccak256(abi.encode(targets, values, payloads, predecessor, salt));\n    }\n\n    /**\n     * @dev Schedule an operation containing a single transaction.\n     *\n     * Emits {CallSalt} if salt is nonzero, and {CallScheduled}.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'proposer' role.\n     */\n    function schedule(\n        address target,\n        uint256 value,\n        bytes calldata data,\n        bytes32 predecessor,\n        bytes32 salt,\n        uint256 delay\n    ) public virtual onlyRole(PROPOSER_ROLE) {\n        bytes32 id = hashOperation(target, value, data, predecessor, salt);\n        _schedule(id, delay);\n        emit CallScheduled(id, 0, target, value, data, predecessor, delay);\n        if (salt != bytes32(0)) {\n            emit CallSalt(id, salt);\n        }\n    }\n\n    /**\n     * @dev Schedule an operation containing a batch of transactions.\n     *\n     * Emits {CallSalt} if salt is nonzero, and one {CallScheduled} event per transaction in the batch.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'proposer' role.\n     */\n    function scheduleBatch(\n        address[] calldata targets,\n        uint256[] calldata values,\n        bytes[] calldata payloads,\n        bytes32 predecessor,\n        bytes32 salt,\n        uint256 delay\n    ) public virtual onlyRole(PROPOSER_ROLE) {\n        require(targets.length == values.length, \"TimelockController: length mismatch\");\n        require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n        bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n        _schedule(id, delay);\n        for (uint256 i = 0; i < targets.length; ++i) {\n            emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay);\n        }\n        if (salt != bytes32(0)) {\n            emit CallSalt(id, salt);\n        }\n    }\n\n    /**\n     * @dev Schedule an operation that is to become valid after a given delay.\n     */\n    function _schedule(bytes32 id, uint256 delay) private {\n        require(!isOperation(id), \"TimelockController: operation already scheduled\");\n        require(delay >= getMinDelay(), \"TimelockController: insufficient delay\");\n        _timestamps[id] = block.timestamp + delay;\n    }\n\n    /**\n     * @dev Cancel an operation.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'canceller' role.\n     */\n    function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) {\n        require(isOperationPending(id), \"TimelockController: operation cannot be cancelled\");\n        delete _timestamps[id];\n\n        emit Cancelled(id);\n    }\n\n    /**\n     * @dev Execute an (ready) operation containing a single transaction.\n     *\n     * Emits a {CallExecuted} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'executor' role.\n     */\n    // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,\n    // thus any modifications to the operation during reentrancy should be caught.\n    // slither-disable-next-line reentrancy-eth\n    function execute(\n        address target,\n        uint256 value,\n        bytes calldata payload,\n        bytes32 predecessor,\n        bytes32 salt\n    ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n        bytes32 id = hashOperation(target, value, payload, predecessor, salt);\n\n        _beforeCall(id, predecessor);\n        _execute(target, value, payload);\n        emit CallExecuted(id, 0, target, value, payload);\n        _afterCall(id);\n    }\n\n    /**\n     * @dev Execute an (ready) operation containing a batch of transactions.\n     *\n     * Emits one {CallExecuted} event per transaction in the batch.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'executor' role.\n     */\n    // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,\n    // thus any modifications to the operation during reentrancy should be caught.\n    // slither-disable-next-line reentrancy-eth\n    function executeBatch(\n        address[] calldata targets,\n        uint256[] calldata values,\n        bytes[] calldata payloads,\n        bytes32 predecessor,\n        bytes32 salt\n    ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n        require(targets.length == values.length, \"TimelockController: length mismatch\");\n        require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n        bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n\n        _beforeCall(id, predecessor);\n        for (uint256 i = 0; i < targets.length; ++i) {\n            address target = targets[i];\n            uint256 value = values[i];\n            bytes calldata payload = payloads[i];\n            _execute(target, value, payload);\n            emit CallExecuted(id, i, target, value, payload);\n        }\n        _afterCall(id);\n    }\n\n    /**\n     * @dev Execute an operation's call.\n     */\n    function _execute(address target, uint256 value, bytes calldata data) internal virtual {\n        (bool success, ) = target.call{value: value}(data);\n        require(success, \"TimelockController: underlying transaction reverted\");\n    }\n\n    /**\n     * @dev Checks before execution of an operation's calls.\n     */\n    function _beforeCall(bytes32 id, bytes32 predecessor) private view {\n        require(isOperationReady(id), \"TimelockController: operation is not ready\");\n        require(predecessor == bytes32(0) || isOperationDone(predecessor), \"TimelockController: missing dependency\");\n    }\n\n    /**\n     * @dev Checks after execution of an operation's calls.\n     */\n    function _afterCall(bytes32 id) private {\n        require(isOperationReady(id), \"TimelockController: operation is not ready\");\n        _timestamps[id] = _DONE_TIMESTAMP;\n    }\n\n    /**\n     * @dev Changes the minimum timelock duration for future operations.\n     *\n     * Emits a {MinDelayChange} event.\n     *\n     * Requirements:\n     *\n     * - the caller must be the timelock itself. This can only be achieved by scheduling and later executing\n     * an operation where the timelock is the target and the data is the ABI-encoded call to this function.\n     */\n    function updateDelay(uint256 newDelay) external virtual {\n        require(msg.sender == address(this), \"TimelockController: caller must be timelock\");\n        emit MinDelayChange(_minDelay, newDelay);\n        _minDelay = newDelay;\n    }\n\n    /**\n     * @dev See {IERC721Receiver-onERC721Received}.\n     */\n    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n        return this.onERC721Received.selector;\n    }\n\n    /**\n     * @dev See {IERC1155Receiver-onERC1155Received}.\n     */\n    function onERC1155Received(\n        address,\n        address,\n        uint256,\n        uint256,\n        bytes memory\n    ) public virtual override returns (bytes4) {\n        return this.onERC1155Received.selector;\n    }\n\n    /**\n     * @dev See {IERC1155Receiver-onERC1155BatchReceived}.\n     */\n    function onERC1155BatchReceived(\n        address,\n        address,\n        uint256[] memory,\n        uint256[] memory,\n        bytes memory\n    ) public virtual override returns (bytes4) {\n        return this.onERC1155BatchReceived.selector;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[48] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n    // As per the EIP-165 spec, no interface should ever match 0xffffffff\n    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n    /**\n     * @dev Returns true if `account` supports the {IERC165} interface.\n     */\n    function supportsERC165(address account) internal view returns (bool) {\n        // Any contract that implements ERC165 must explicitly indicate support of\n        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n        return\n            supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&\n            !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);\n    }\n\n    /**\n     * @dev Returns true if `account` supports the interface defined by\n     * `interfaceId`. Support for {IERC165} itself is queried automatically.\n     *\n     * See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n        // query support of both ERC165 as per the spec and support of _interfaceId\n        return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);\n    }\n\n    /**\n     * @dev Returns a boolean array where each value corresponds to the\n     * interfaces passed in and whether they're supported or not. This allows\n     * you to batch check interfaces for a contract where your expectation\n     * is that some interfaces may not be supported.\n     *\n     * See {IERC165-supportsInterface}.\n     *\n     * _Available since v3.4._\n     */\n    function getSupportedInterfaces(\n        address account,\n        bytes4[] memory interfaceIds\n    ) internal view returns (bool[] memory) {\n        // an array of booleans corresponding to interfaceIds and whether they're supported or not\n        bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n        // query support of ERC165 itself\n        if (supportsERC165(account)) {\n            // query support of each interface in interfaceIds\n            for (uint256 i = 0; i < interfaceIds.length; i++) {\n                interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);\n            }\n        }\n\n        return interfaceIdsSupported;\n    }\n\n    /**\n     * @dev Returns true if `account` supports all the interfaces defined in\n     * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n     *\n     * Batch-querying can lead to gas savings by skipping repeated checks for\n     * {IERC165} support.\n     *\n     * See {IERC165-supportsInterface}.\n     */\n    function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n        // query support of ERC165 itself\n        if (!supportsERC165(account)) {\n            return false;\n        }\n\n        // query support of each interface in interfaceIds\n        for (uint256 i = 0; i < interfaceIds.length; i++) {\n            if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {\n                return false;\n            }\n        }\n\n        // all interfaces supported\n        return true;\n    }\n\n    /**\n     * @notice Query if a contract implements an interface, does not check ERC165 support\n     * @param account The address of the contract to query for support of an interface\n     * @param interfaceId The interface identifier, as specified in ERC-165\n     * @return true if the contract at account indicates support of the interface with\n     * identifier interfaceId, false otherwise\n     * @dev Assumes that account contains a contract that supports ERC165, otherwise\n     * the behavior of this method is undefined. This precondition can be checked\n     * with {supportsERC165}.\n     *\n     * Some precompiled contracts will falsely indicate support for a given interface, so caution\n     * should be exercised when using this function.\n     *\n     * Interface identification is specified in ERC-165.\n     */\n    function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {\n        // prepare call\n        bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n        // perform static call\n        bool success;\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly {\n            success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n            returnSize := returndatasize()\n            returnValue := mload(0x00)\n        }\n\n        return success && returnSize >= 0x20 && returnValue > 0;\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n     * Revert on invalid signature.\n     */\n    function safePermit(\n        IERC20Permit token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n    }\n}\n"
      },
      "contracts/universal/CrossDomainMessenger.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n    PausableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\n\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n *         cross-chain messenger contracts. It's designed to be a universal interface that only\n *         needs to be extended slightly to provide low-level message passing functionality on each\n *         chain it's deployed on. Currently only designed for message passing between two paired\n *         chains and does not support one-to-many interactions.\n *\n *         Any changes to this contract MUST result in a semver bump for contracts that inherit it.\n */\nabstract contract CrossDomainMessenger is PausableUpgradeable {\n    /**\n     * @notice Current message version identifier.\n     */\n    uint16 public constant MESSAGE_VERSION = 0;\n\n    /**\n     * @notice Constant overhead added to the base gas for a message.\n     */\n    uint64 public constant RELAY_CONSTANT_OVERHEAD = 200_000;\n\n    /**\n     * @notice Numerator for dynamic overhead added to the base gas for a message.\n     */\n    uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 64;\n\n    /**\n     * @notice Denominator for dynamic overhead added to the base gas for a message.\n     */\n    uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 63;\n\n    /**\n     * @notice Extra gas added to base gas for each byte of calldata in a message.\n     */\n    uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n    /**\n     * @notice Gas reserved for performing the external call in `relayMessage`.\n     */\n    uint64 public constant RELAY_CALL_OVERHEAD = 40_000;\n\n    /**\n     * @notice Gas reserved for finalizing the execution of `relayMessage` after the safe call.\n     */\n    uint64 public constant RELAY_RESERVED_GAS = 40_000;\n\n    /**\n     * @notice Gas reserved for the execution between the `hasMinGas` check and the external\n     *         call in `relayMessage`.\n     */\n    uint64 public constant RELAY_GAS_CHECK_BUFFER = 5_000;\n\n    /**\n     * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n     */\n    address public immutable OTHER_MESSENGER;\n\n    /**\n     * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n     *         be present in this mapping if it has successfully been relayed on this chain, and\n     *         can therefore not be relayed again.\n     */\n    mapping(bytes32 => bool) public successfulMessages;\n\n    /**\n     * @notice Address of the sender of the currently executing message on the other chain. If the\n     *         value of this variable is the default value (0x00000000...dead) then no message is\n     *         currently being executed. Use the xDomainMessageSender getter which will throw an\n     *         error if this is the case.\n     */\n    address internal xDomainMsgSender;\n\n    /**\n     * @notice Nonce for the next message to be sent, without the message version applied. Use the\n     *         messageNonce getter which will insert the message version into the nonce to give you\n     *         the actual nonce to be used for the message.\n     */\n    uint240 internal msgNonce;\n\n    /**\n     * @notice Mapping of message hashes to a boolean if and only if the message has failed to be\n     *         executed at least once. A message will not be present in this mapping if it\n     *         successfully executed on the first attempt.\n     */\n    mapping(bytes32 => bool) public failedMessages;\n\n    /**\n     * @notice Reserve extra slots in the storage layout for future upgrades.\n     *         A gap size of 45 was chosen here, so that the first slot used in a child contract\n     *         would be a multiple of 50.\n     */\n    uint256[45] private __gap;\n\n    /**\n     * @notice Emitted whenever a message is sent to the other chain.\n     *\n     * @param target       Address of the recipient of the message.\n     * @param sender       Address of the sender of the message.\n     * @param value        ETH value sent along with the message to the recipient.\n     * @param message      Message to trigger the recipient address with.\n     * @param messageNonce Unique nonce attached to the message.\n     * @param gasLimit     Minimum gas limit that the message can be executed with.\n     */\n    event SentMessage(\n        address indexed target,\n        address indexed sender,\n        uint256 value,\n        bytes message,\n        uint256 messageNonce,\n        uint256 gasLimit\n    );\n\n    /**\n     * @notice Emitted whenever a message is successfully relayed on this chain.\n     *\n     * @param msgHash Hash of the message that was relayed.\n     */\n    event RelayedMessage(bytes32 indexed msgHash);\n\n    /**\n     * @notice Emitted whenever a message fails to be relayed on this chain.\n     *\n     * @param msgHash Hash of the message that failed to be relayed.\n     */\n    event FailedRelayedMessage(bytes32 indexed msgHash);\n\n    /**\n     * @param _otherMessenger Address of the messenger on the paired chain.\n     */\n    constructor(address _otherMessenger) {\n        OTHER_MESSENGER = _otherMessenger;\n    }\n\n    /**\n     * @notice Sends a message to some target address on the other chain. Note that if the call\n     *         always reverts, then the message will be unrelayable, and any ETH sent will be\n     *         permanently locked. The same will occur if the target on the other chain is\n     *         considered unsafe (see the _isUnsafeTarget() function).\n     *\n     * @param _target      Target contract or wallet address.\n     * @param _message     Message to trigger the target address with.\n     * @param _minGasLimit Minimum gas limit that the message can be executed with.\n     */\n    function sendMessage(\n        address _target,\n        bytes calldata _message,\n        uint32 _minGasLimit\n    ) external payable {\n        // Triggers a message to the other messenger. Note that the amount of gas provided to the\n        // message is the amount of gas requested by the user PLUS the base gas value. We want to\n        // guarantee the property that the call to the target contract will always have at least\n        // the minimum gas limit specified by the user.\n        _sendMessage(\n            OTHER_MESSENGER,\n            baseGas(_message, _minGasLimit),\n            msg.value,\n            abi.encodeWithSelector(\n                this.relayMessage.selector,\n                messageNonce(),\n                msg.sender,\n                _target,\n                msg.value,\n                _minGasLimit,\n                _message\n            )\n        );\n\n        emit SentMessage(_target, msg.sender, msg.value, _message, messageNonce(), _minGasLimit);\n\n        unchecked {\n            ++msgNonce;\n        }\n    }\n\n    /**\n     * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n     *         be executed via cross-chain call from the other messenger OR if the message was\n     *         already received once and is currently being replayed.\n     *\n     * @param _nonce       Nonce of the message being relayed.\n     * @param _sender      Address of the user who sent the message.\n     * @param _target      Address that the message is targeted at.\n     * @param _value       ETH value to send with the message.\n     * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n     * @param _message     Message to send to the target.\n     */\n    function relayMessage(\n        uint256 _nonce,\n        address _sender,\n        address _target,\n        uint256 _value,\n        uint256 _minGasLimit,\n        bytes calldata _message\n    ) external payable {\n        (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n        require(\n            version < 1,\n            \"CrossDomainMessenger: only version 0 messages is supported at this time\"\n        );\n\n        // We use the v0 message hash as the unique identifier for the message because it commits\n        // to the value and minimum gas limit of the message.\n        bytes32 versionedHash = Hashing.hashCrossDomainMessageV0(\n            _nonce,\n            _sender,\n            _target,\n            _value,\n            _minGasLimit,\n            _message\n        );\n\n        if (_isOtherMessenger()) {\n            // These properties should always hold when the message is first submitted (as\n            // opposed to being replayed).\n            assert(msg.value == _value);\n            assert(!failedMessages[versionedHash]);\n        } else {\n            require(\n                msg.value == 0,\n                \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n            );\n\n            require(\n                failedMessages[versionedHash],\n                \"CrossDomainMessenger: message cannot be replayed\"\n            );\n        }\n\n        require(\n            _isUnsafeTarget(_target) == false,\n            \"CrossDomainMessenger: cannot send message to blocked system address\"\n        );\n\n        require(\n            successfulMessages[versionedHash] == false,\n            \"CrossDomainMessenger: message has already been relayed\"\n        );\n\n        // If there is not enough gas left to perform the external call and finish the execution,\n        // return early and assign the message to the failedMessages mapping.\n        // We are asserting that we have enough gas to:\n        // 1. Call the target contract (_minGasLimit + RELAY_CALL_OVERHEAD + RELAY_GAS_CHECK_BUFFER)\n        //   1.a. The RELAY_CALL_OVERHEAD is included in `hasMinGas`.\n        // 2. Finish the execution after the external call (RELAY_RESERVED_GAS).\n        //\n        // If `xDomainMsgSender` is not the default L2 sender, this function\n        // is being re-entered. This marks the message as failed to allow it to be replayed.\n        if (\n            !SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER) ||\n            xDomainMsgSender != Constants.DEFAULT_L2_SENDER\n        ) {\n            failedMessages[versionedHash] = true;\n            emit FailedRelayedMessage(versionedHash);\n\n            // Revert in this case if the transaction was triggered by the estimation address. This\n            // should only be possible during gas estimation or we have bigger problems. Reverting\n            // here will make the behavior of gas estimation change such that the gas limit\n            // computed will be the amount required to relay the message, even if that amount is\n            // greater than the minimum gas limit specified by the user.\n            if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n                revert(\"CrossDomainMessenger: failed to relay message\");\n            }\n\n            return;\n        }\n\n        xDomainMsgSender = _sender;\n        bool success = SafeCall.call(_target, gasleft() - RELAY_RESERVED_GAS, _value, _message);\n        xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n\n        if (success) {\n            successfulMessages[versionedHash] = true;\n            emit RelayedMessage(versionedHash);\n        } else {\n            failedMessages[versionedHash] = true;\n            emit FailedRelayedMessage(versionedHash);\n\n            // Revert in this case if the transaction was triggered by the estimation address. This\n            // should only be possible during gas estimation or we have bigger problems. Reverting\n            // here will make the behavior of gas estimation change such that the gas limit\n            // computed will be the amount required to relay the message, even if that amount is\n            // greater than the minimum gas limit specified by the user.\n            if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n                revert(\"CrossDomainMessenger: failed to relay message\");\n            }\n        }\n    }\n\n    /**\n     * @notice Retrieves the address of the contract or wallet that initiated the currently\n     *         executing message on the other chain. Will throw an error if there is no message\n     *         currently being executed. Allows the recipient of a call to see who triggered it.\n     *\n     * @return Address of the sender of the currently executing message on the other chain.\n     */\n    function xDomainMessageSender() external view returns (address) {\n        require(\n            xDomainMsgSender != Constants.DEFAULT_L2_SENDER,\n            \"CrossDomainMessenger: xDomainMessageSender is not set\"\n        );\n\n        return xDomainMsgSender;\n    }\n\n    /**\n     * @notice Retrieves the next message nonce. Message version will be added to the upper two\n     *         bytes of the message nonce. Message version allows us to treat messages as having\n     *         different structures.\n     *\n     * @return Nonce of the next message to be sent, with added message version.\n     */\n    function messageNonce() public view returns (uint256) {\n        return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n    }\n\n    /**\n     * @notice Computes the amount of gas required to guarantee that a given message will be\n     *         received on the other chain without running out of gas. Guaranteeing that a message\n     *         will not run out of gas is important because this ensures that a message can always\n     *         be replayed on the other chain if it fails to execute completely.\n     *\n     * @param _message     Message to compute the amount of required gas for.\n     * @param _minGasLimit Minimum desired gas limit when message goes to target.\n     *\n     * @return Amount of gas required to guarantee message receipt.\n     */\n    function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {\n        return\n            // Constant overhead\n            RELAY_CONSTANT_OVERHEAD +\n            // Calldata overhead\n            (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n            // Dynamic overhead (EIP-150)\n            ((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n                MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n            // Gas reserved for the worst-case cost of 3/5 of the `CALL` opcode's dynamic gas\n            // factors. (Conservative)\n            RELAY_CALL_OVERHEAD +\n            // Relay reserved gas (to ensure execution of `relayMessage` completes after the\n            // subcontext finishes executing) (Conservative)\n            RELAY_RESERVED_GAS +\n            // Gas reserved for the execution between the `hasMinGas` check and the `CALL`\n            // opcode. (Conservative)\n            RELAY_GAS_CHECK_BUFFER;\n    }\n\n    /**\n     * @notice Intializer.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function __CrossDomainMessenger_init() internal onlyInitializing {\n        xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n    }\n\n    /**\n     * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n     *         contracts because the logic for this depends on the network where the messenger is\n     *         being deployed.\n     *\n     * @param _to       Recipient of the message on the other chain.\n     * @param _gasLimit Minimum gas limit the message can be executed with.\n     * @param _value    Amount of ETH to send with the message.\n     * @param _data     Message data.\n     */\n    function _sendMessage(\n        address _to,\n        uint64 _gasLimit,\n        uint256 _value,\n        bytes memory _data\n    ) internal virtual;\n\n    /**\n     * @notice Checks whether the message is coming from the other messenger. Implemented by child\n     *         contracts because the logic for this depends on the network where the messenger is\n     *         being deployed.\n     *\n     * @return Whether the message is coming from the other messenger.\n     */\n    function _isOtherMessenger() internal view virtual returns (bool);\n\n    /**\n     * @notice Checks whether a given call target is a system address that could cause the\n     *         messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n     *         addresses. This is ONLY used to prevent the execution of messages to specific\n     *         system addresses that could cause security issues, e.g., having the\n     *         CrossDomainMessenger send messages to itself.\n     *\n     * @param _target Address of the contract to check.\n     *\n     * @return Whether or not the address is an unsafe system address.\n     */\n    function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n"
      },
      "contracts/universal/IKromaMintableERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @title IKromaMintableERC20\n * @notice This interface is available on the KromaMintableERC20 contract. We declare it as a\n *         separate interface so that it can be used in custom implementations of\n *         KromaMintableERC20.\n */\ninterface IKromaMintableERC20 {\n    function REMOTE_TOKEN() external view returns (address);\n\n    function BRIDGE() external view returns (address);\n\n    function mint(address _to, uint256 _amount) external;\n\n    function burn(address _from, uint256 _amount) external;\n}\n"
      },
      "contracts/universal/KromaMintableERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nimport { ISemver } from \"../universal/ISemver.sol\";\nimport { IKromaMintableERC20 } from \"./IKromaMintableERC20.sol\";\n\n/**\n * @title KromaMintableERC20\n * @notice KromaMintableERC20 is a standard extension of the base ERC20 token contract designed\n *         to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to\n *         use a KromaMintableRC20 as the L2 representation of an L1 token, or vice-versa.\n *         Designed to be backwards compatible with the older StandardL2ERC20 token which was only\n *         meant for use on L2.\n */\ncontract KromaMintableERC20 is IKromaMintableERC20, ERC20, ISemver {\n    /**\n     * @notice Address of the corresponding version of this token on the remote chain.\n     */\n    address public immutable REMOTE_TOKEN;\n\n    /**\n     * @notice Address of the StandardBridge on this network.\n     */\n    address public immutable BRIDGE;\n\n    /**\n     * @notice Emitted whenever tokens are minted for an account.\n     *\n     * @param account Address of the account tokens are being minted for.\n     * @param amount  Amount of tokens minted.\n     */\n    event Mint(address indexed account, uint256 amount);\n\n    /**\n     * @notice Emitted whenever tokens are burned from an account.\n     *\n     * @param account Address of the account tokens are being burned from.\n     * @param amount  Amount of tokens burned.\n     */\n    event Burn(address indexed account, uint256 amount);\n\n    /**\n     * @notice A modifier that only allows the bridge to call\n     */\n    modifier onlyBridge() {\n        require(msg.sender == BRIDGE, \"KromaMintableERC20: only bridge can mint and burn\");\n        _;\n    }\n\n    /**\n     * @notice Semantic version.\n     * @custom:semver 1.0.0\n     */\n    string public constant version = \"1.0.0\";\n\n    /**\n     * @notice Constructs the KromaMintableERC20 contract.\n     *\n     * @param _bridge      Address of the L2 standard bridge.\n     * @param _remoteToken Address of the corresponding L1 token.\n     * @param _name        ERC20 name.\n     * @param _symbol      ERC20 symbol.\n     */\n    constructor(\n        address _bridge,\n        address _remoteToken,\n        string memory _name,\n        string memory _symbol\n    ) ERC20(_name, _symbol) {\n        REMOTE_TOKEN = _remoteToken;\n        BRIDGE = _bridge;\n    }\n\n    /**\n     * @notice Allows the StandardBridge on this network to mint tokens.\n     *\n     * @param _to     Address to mint tokens to.\n     * @param _amount Amount of tokens to mint.\n     */\n    function mint(address _to, uint256 _amount)\n        external\n        virtual\n        override(IKromaMintableERC20)\n        onlyBridge\n    {\n        _mint(_to, _amount);\n        emit Mint(_to, _amount);\n    }\n\n    /**\n     * @notice Allows the StandardBridge on this network to burn tokens.\n     *\n     * @param _from   Address to burn tokens from.\n     * @param _amount Amount of tokens to burn.\n     */\n    function burn(address _from, uint256 _amount)\n        external\n        virtual\n        override(IKromaMintableERC20)\n        onlyBridge\n    {\n        _burn(_from, _amount);\n        emit Burn(_from, _amount);\n    }\n\n    /**\n     * @notice ERC165 interface check function.\n     *\n     * @param _interfaceId Interface ID to check.\n     *\n     * @return Whether or not the interface is supported by this contract.\n     */\n    function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n        bytes4 iface1 = type(IERC165).interfaceId;\n        // Interface corresponding to the updated KromaMintableERC20 (this contract).\n        bytes4 iface2 = type(IKromaMintableERC20).interfaceId;\n        return _interfaceId == iface1 || _interfaceId == iface2;\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "contracts/libraries/Bytes32.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Bytes32\n * @notice Bytes32 is a library for manipulating byte32.\n */\nlibrary Bytes32 {\n    /**\n     * @notice Splits bytes32 to high and low parts.\n     *\n     * @param _bytes Bytes32 to split.\n     *\n     * @return High part of bytes32.\n     * @return Low part of bytes32.\n     */\n    function split(bytes32 _bytes) internal pure returns (bytes32, bytes32) {\n        bytes16 high = bytes16(_bytes);\n        bytes16 low = bytes16(uint128(uint256(_bytes)));\n        return (fromBytes16(high), fromBytes16(low));\n    }\n\n    /**\n     * @notice Converts bytes16 to bytes32.\n     *\n     * @param _bytes Bytes to constrcut to bytes32.\n     *\n     * @return Bytes32 constructed from bytes16.\n     */\n    function fromBytes16(bytes16 _bytes) internal pure returns (bytes32) {\n        return bytes32(uint256(uint128(_bytes)));\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = MathUpgradeable.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMathUpgradeable.abs(value))));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, MathUpgradeable.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n    /**\n     * @dev MAY be emitted to signal that the domain could have changed.\n     */\n    event EIP712DomainChanged();\n\n    /**\n     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n     * signature.\n     */\n    function eip712Domain()\n        external\n        view\n        returns (\n            bytes1 fields,\n            string memory name,\n            string memory version,\n            uint256 chainId,\n            address verifyingContract,\n            bytes32 salt,\n            uint256[] memory extensions\n        );\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n    function __AccessControl_init() internal onlyInitializing {\n    }\n\n    function __AccessControl_init_unchained() internal onlyInitializing {\n    }\n    struct RoleData {\n        mapping(address => bool) members;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with a standardized message including the required role.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     *\n     * _Available since v4.1._\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n        return _roles[role].members[account];\n    }\n\n    /**\n     * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n     * Overriding this function changes the behavior of the {onlyRole} modifier.\n     *\n     * Format of the revert message is described in {_checkRole}.\n     *\n     * _Available since v4.6._\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Revert with a standard message if `account` is missing `role`.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"AccessControl: account \",\n                        StringsUpgradeable.toHexString(account),\n                        \" is missing role \",\n                        StringsUpgradeable.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * May emit a {RoleGranted} event.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     *\n     * NOTE: This function is deprecated in favor of {_grantRole}.\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        if (!hasRole(role, account)) {\n            _roles[role].members[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        if (hasRole(role, account)) {\n            _roles[role].members[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    function __Pausable_init() internal onlyInitializing {\n        __Pausable_init_unchained();\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n        _paused = false;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        require(!paused(), \"Pausable: paused\");\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        require(paused(), \"Pausable: not paused\");\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMathUpgradeable {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",
        "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
        "@rari-capital/solmate/=node_modules/@rari-capital/solmate/",
        "forge-std/=node_modules/forge-std/src/",
        "ds-test/=node_modules/ds-test/src/",
        "hardhat-deploy/=node_modules/hardhat-deploy/",
        "hardhat/=node_modules/hardhat/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 10000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none"
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "london",
      "viaIR": false,
      "libraries": {}
    }
  }}