ETH Price: $1,975.50 (+0.08%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Advanced mode:
Parent Transaction Hash Method Block
From
To
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ZKProofVerifier

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 10000 runs

Other Settings:
london EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

// Contracts
import { ZKVerifier } from "contracts/L1/ZKVerifier.sol";

// Libraries
import { Hashing } from "contracts/libraries/Hashing.sol";
import { Predeploys } from "contracts/libraries/Predeploys.sol";
import { Types } from "contracts/libraries/Types.sol";

// Interfaces
import { ISemver } from "contracts/universal/ISemver.sol";
import { ISP1Verifier } from "contracts/vendor/ISP1Verifier.sol";
import { IZKMerkleTrie } from "contracts/L1/interfaces/IZKMerkleTrie.sol";

/// @custom:proxied true
/// @title ZKProofVerifier
/// @notice The ZKProofVerifier contract verifies public inputs and corresponding ZK proofs.
///         Currently it verifies zkEVM proofs using ZKVerifier contract, and zkVM proofs using
///         SP1Verifier contract.
contract ZKProofVerifier is ISemver {
    /// @notice Address of the ZKVerifier contract.
    ZKVerifier internal immutable ZK_VERIFIER;

    /// @notice The dummy transaction hash for zkEVM proofs. This is used to pad if the
    ///         number of transactions is less than MAX_TXS. This is same as:
    ///         unsignedTx = {
    ///           nonce: 0,
    ///           gasLimit: 0,
    ///           gasPrice: 0,
    ///           to: address(0),
    ///           value: 0,
    ///           data: '0x',
    ///           chainId: CHAIN_ID,
    ///         }
    ///         signature = sign(unsignedTx, 0x1)
    ///         dummyHash = keccak256(rlp({
    ///           ...unsignedTx,
    ///           signature,
    ///         }))
    bytes32 internal immutable DUMMY_HASH;

    /// @notice The maximum number of transactions for zkEVM proofs.
    uint256 internal immutable MAX_TXS;

    /// @notice Address that has the ability to verify the merkle proof in ZKTrie.
    address internal immutable ZK_MERKLE_TRIE;

    /// @notice Address of the SP1VerifierGateway contract.
    ISP1Verifier internal immutable SP1_VERIFIER;

    /// @notice The verification key for the zkVM program.
    bytes32 internal immutable ZKVM_PROGRAM_V_KEY;

    /// @notice Reverts when the zkVM program verification key is invalid.
    error InvalidZkVmVKey();

    /// @notice Reverts when the public input is invalid.
    error InvalidPublicInput();

    /// @notice Reverts when the ZK proof is invalid.
    error InvalidZkProof();

    /// @notice Reverts when the inclusion proof is invalid.
    error InvalidInclusionProof();

    /// @notice Reverts when the block hash is mismatched between source and destination output root
    ///         proof. (only for zkEVM proof)
    error BlockHashMismatchedBtwSrcAndDst();

    /// @notice Reverts when the source output root is mismatched.
    error SrcOutputMismatched();

    /// @notice Reverts when the destination output root is matched. (only for fault proof)
    error DstOutputMatched();

    /// @notice Reverts when the block hash is mismatched.
    error BlockHashMismatched();

    /// @notice Reverts when the state root is mismatched.
    error StateRootMismatched();

    /// @notice Semantic version.
    /// @custom:semver 1.0.0
    string public constant version = "1.0.0";

    /// @notice Constructs the ZKProofVerifier contract.
    /// @param _zkVerifier Address of the ZKVerifier contract.
    /// @param _dummyHash Dummy hash for zkEVM proofs.
    /// @param _maxTxs Number of max transactions per block for zkEVM proofs.
    /// @param _zkMerkleTrie Address of the ZKMerkleTrie contract.
    /// @param _sp1Verifier Address of the SP1VerifierGateway contract.
    /// @param _zkVmProgramVKey The verification key for the zkVM program.
    constructor(
        ZKVerifier _zkVerifier,
        bytes32 _dummyHash,
        uint256 _maxTxs,
        address _zkMerkleTrie,
        ISP1Verifier _sp1Verifier,
        bytes32 _zkVmProgramVKey
    ) {
        ZK_VERIFIER = _zkVerifier;
        DUMMY_HASH = _dummyHash;
        MAX_TXS = _maxTxs;
        ZK_MERKLE_TRIE = _zkMerkleTrie;
        SP1_VERIFIER = _sp1Verifier;
        ZKVM_PROGRAM_V_KEY = _zkVmProgramVKey;
    }

    /// @notice Getter for the address of ZKVerifier contract.
    function zkVerifier() external view returns (ZKVerifier) {
        return ZK_VERIFIER;
    }

    /// @notice Getter for the dummy transaction hash for zkEVM proofs.
    function dummyHash() external view returns (bytes32) {
        return DUMMY_HASH;
    }

    /// @notice Getter for the maximum number of transactions for zkEVM proofs.
    function maxTxs() external view returns (uint256) {
        return MAX_TXS;
    }

    /// @notice Getter for the address of ZKMerkleTrie contract.
    function zkMerkleTrie() external view returns (address) {
        return ZK_MERKLE_TRIE;
    }

    /// @notice Getter for the address of SP1VerifierGateway contract.
    function sp1Verifier() external view returns (ISP1Verifier) {
        return SP1_VERIFIER;
    }

    /// @notice Getter for the verification key for the zkVM program.
    function zkVmProgramVKey() external view returns (bytes32) {
        return ZKVM_PROGRAM_V_KEY;
    }

    /// @notice Verifies zkEVM public inputs and proof.
    /// @param _zkEvmProof The public input and proof using zkEVM.
    /// @param _storedSrcOutput The stored source output root.
    /// @param _storedDstOutput The stored destination output root. It will only be used for fault proving.
    /// @return publicInputHash_ Hash of public input.
    function verifyZkEvmProof(
        Types.ZkEvmProof calldata _zkEvmProof,
        bytes32 _storedSrcOutput,
        bytes32 _storedDstOutput
    ) external view returns (bytes32 publicInputHash_) {
        Types.PublicInputProof calldata publicInputProof = _zkEvmProof.publicInputProof;

        if (
            publicInputProof.srcOutputRootProof.nextBlockHash !=
            publicInputProof.dstOutputRootProof.latestBlockhash
        ) revert BlockHashMismatchedBtwSrcAndDst();

        _validatePublicInputOutput(
            _storedSrcOutput,
            _storedDstOutput,
            Hashing.hashOutputRootProof(publicInputProof.srcOutputRootProof),
            Hashing.hashOutputRootProof(publicInputProof.dstOutputRootProof)
        );
        _validateZkEvmPublicInput(
            publicInputProof.dstOutputRootProof,
            publicInputProof.publicInput,
            publicInputProof.rlps
        );
        _validateWithdrawalStorageRoot(
            publicInputProof.merkleProof,
            publicInputProof.l2ToL1MessagePasserBalance,
            publicInputProof.l2ToL1MessagePasserCodeHash,
            publicInputProof.dstOutputRootProof.messagePasserStorageRoot,
            publicInputProof.dstOutputRootProof.stateRoot
        );

        publicInputHash_ = _hashZkEvmPublicInput(
            publicInputProof.srcOutputRootProof.stateRoot,
            publicInputProof.publicInput
        );

        if (!ZK_VERIFIER.verify(_zkEvmProof.proof, _zkEvmProof.pair, publicInputHash_))
            revert InvalidZkProof();
    }

    /// @notice Verifies zkVM public inputs and proof.
    /// @param _zkVmProof The public input and proof using zkVM.
    /// @param _storedSrcOutput The stored source output root.
    /// @param _storedDstOutput The stored destination output root. It will only be used for fault proving.
    /// @param _storedL1Head The stored L1 block hash.
    /// @return publicInputHash_ Hash of public input.
    function verifyZkVmProof(
        Types.ZkVmProof calldata _zkVmProof,
        bytes32 _storedSrcOutput,
        bytes32 _storedDstOutput,
        bytes32 _storedL1Head
    ) external view returns (bytes32 publicInputHash_) {
        if (_zkVmProof.zkVmProgramVKey != ZKVM_PROGRAM_V_KEY) revert InvalidZkVmVKey();

        _validatePublicInputOutput(
            _storedSrcOutput,
            _storedDstOutput,
            bytes32(_zkVmProof.publicValues[8:40]), // skip ABI-encoding prefix at publicValues[0:8].
            bytes32(_zkVmProof.publicValues[48:80]) // skip ABI-encoding prefix at publicValues[40:48].
        );

        // Check if the L1 block hash is correct.
        // Skip ABI-encoding prefix at publicValues[80:88].
        if (bytes32(_zkVmProof.publicValues[88:120]) != _storedL1Head) revert InvalidPublicInput();

        SP1_VERIFIER.verifyProof(
            ZKVM_PROGRAM_V_KEY,
            _zkVmProof.publicValues,
            _zkVmProof.proofBytes
        );

        publicInputHash_ = keccak256(_zkVmProof.publicValues);
    }

    /// @notice Checks if the public input outputs are valid. Reverts if they are invalid.
    /// @param _storedSrcOutput The stored source output root.
    /// @param _storedDstOutput The stored destination output root.
    /// @param _publicInputSrcOutput The source output root of public input.
    /// @param _publicInputDstOutput The destination output root of public input.
    function _validatePublicInputOutput(
        bytes32 _storedSrcOutput,
        bytes32 _storedDstOutput,
        bytes32 _publicInputSrcOutput,
        bytes32 _publicInputDstOutput
    ) internal pure {
        if (_storedSrcOutput != _publicInputSrcOutput) revert SrcOutputMismatched();
        // If _storedDstOutput is non-zero, it is fault proving case, not validity proving.
        // Then assert _publicInputDstOutput is different with on-chain stored destination output.
        if (_storedDstOutput != bytes32(0)) {
            if (_storedDstOutput == _publicInputDstOutput) revert DstOutputMatched();
        }
    }

    /// @notice Checks if the public input of zkEVM proof is valid. Reverts if it is invalid.
    /// @param _dstOutputRootProof Proof of the destination output root.
    /// @param _publicInput Ingredients to compute the public input used by zkEVM proof verification.
    /// @param _rlps Pre-encoded RLPs to compute the latest block hash of the destination output
    ///              root proof.
    function _validateZkEvmPublicInput(
        Types.OutputRootProof calldata _dstOutputRootProof,
        Types.PublicInput calldata _publicInput,
        Types.BlockHeaderRLP calldata _rlps
    ) internal pure {
        if (_publicInput.stateRoot != _dstOutputRootProof.stateRoot) revert StateRootMismatched();

        // parentBeaconRoot is non-zero for Cancun block
        bytes32 blockHash = _publicInput.parentBeaconRoot != bytes32(0)
            ? Hashing.hashBlockHeaderCancun(_publicInput, _rlps)
            : Hashing.hashBlockHeaderShanghai(_publicInput, _rlps);

        if (_dstOutputRootProof.latestBlockhash != blockHash) revert BlockHashMismatched();
    }

    /// @notice Checks if the L2ToL1MesagePasser account is included in the given state root.
    /// @param _merkleProof Merkle proof of L2ToL1MessagePasser account against the state root.
    /// @param _l2ToL1MessagePasserBalance Balance of the L2ToL1MessagePasser account.
    /// @param _l2ToL1MessagePasserCodeHash Codehash of the L2ToL1MessagePasser account.
    /// @param _messagePasserStorageRoot Storage root of the L2ToL1MessagePasser account.
    /// @param _stateRoot State root.
    function _validateWithdrawalStorageRoot(
        bytes[] calldata _merkleProof,
        bytes32 _l2ToL1MessagePasserBalance,
        bytes32 _l2ToL1MessagePasserCodeHash,
        bytes32 _messagePasserStorageRoot,
        bytes32 _stateRoot
    ) internal view {
        // TODO(chokobole): Can we fix the codeHash?
        bytes memory l2ToL1MessagePasserAccount = abi.encodePacked(
            uint256(0), // nonce
            _l2ToL1MessagePasserBalance, // balance,
            _l2ToL1MessagePasserCodeHash, // codeHash,
            _messagePasserStorageRoot // storage root
        );

        if (
            !IZKMerkleTrie(ZK_MERKLE_TRIE).verifyInclusionProof(
                bytes32(bytes20(Predeploys.L2_TO_L1_MESSAGE_PASSER)),
                l2ToL1MessagePasserAccount,
                _merkleProof,
                _stateRoot
            )
        ) revert InvalidInclusionProof();
    }

    /// @notice Hashes the public input for zkEVM proof with padding dummy transactions.
    /// @param _prevStateRoot Previous state root.
    /// @param _publicInput Ingredients to compute the public input used by zkEVM proof verification.
    /// @return Hash of public input for zkEVM proof.
    function _hashZkEvmPublicInput(
        bytes32 _prevStateRoot,
        Types.PublicInput calldata _publicInput
    ) internal view returns (bytes32) {
        bytes32[] memory dummyHashes;
        if (_publicInput.txHashes.length < MAX_TXS) {
            dummyHashes = Hashing.generateDummyHashes(
                DUMMY_HASH,
                MAX_TXS - _publicInput.txHashes.length
            );
        }

        // NOTE(chokobole): We cannot calculate the Ethereum transaction root solely
        // based on transaction hashes. It is necessary to have access to the original
        // transactions. Considering the imposed constraints and the difficulty
        // of providing a preimage that would generate the desired public input hash
        // from an attacker's perspective, we have decided to omit the verification
        // using the transaction root.
        return Hashing.hashZkEvmPublicInput(_prevStateRoot, _publicInput, dummyHashes);
    }
}

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.15;

import { ISemver } from "../universal/ISemver.sol";

contract ZKVerifier is ISemver {
    uint256 internal immutable HASH_SCALAR_VALUE;
    uint256 internal immutable M_56_PX_VALUE;
    uint256 internal immutable M_56_PY_VALUE;

    /**
     * @notice Semantic version.
     * @custom:semver 0.1.5
     */
    string public constant version = "0.1.5";

    constructor(uint256 _hashScalar, uint256 _m56Px, uint256 _m56Py) {
        HASH_SCALAR_VALUE = _hashScalar;
        M_56_PX_VALUE = _m56Px;
        M_56_PY_VALUE = _m56Py;
    }

    function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {
        uint256 length = p1.length * 6;
        uint256[] memory input = new uint256[](length);
        uint256[1] memory result;
        bool ret;

        require(p1.length == p2.length);

        for (uint256 i = 0; i < p1.length; i++) {
            input[0 + i * 6] = p1[i].x;
            input[1 + i * 6] = p1[i].y;
            input[2 + i * 6] = p2[i].x[0];
            input[3 + i * 6] = p2[i].x[1];
            input[4 + i * 6] = p2[i].y[0];
            input[5 + i * 6] = p2[i].y[1];
        }

        assembly {
            ret := staticcall(gas(), 8, add(input, 0x20), mul(length, 0x20), result, 0x20)
        }
        require(ret);
        return result[0] != 0;
    }

    uint256 constant q_mod =
        21888242871839275222246405745257275088548364400416034343698204186575808495617;

    function fr_invert(uint256 a) internal view returns (uint256) {
        return fr_pow(a, q_mod - 2);
    }

    function fr_pow(uint256 a, uint256 power) internal view returns (uint256) {
        uint256[6] memory input;
        uint256[1] memory result;
        bool ret;

        input[0] = 32;
        input[1] = 32;
        input[2] = 32;
        input[3] = a;
        input[4] = power;
        input[5] = q_mod;

        assembly {
            ret := staticcall(gas(), 0x05, input, 0xc0, result, 0x20)
        }
        require(ret);

        return result[0];
    }

    function fr_div(uint256 a, uint256 b) internal view returns (uint256) {
        require(b != 0);
        return mulmod(a, fr_invert(b), q_mod);
    }

    function fr_mul_add(uint256 a, uint256 b, uint256 c) internal pure returns (uint256) {
        return addmod(mulmod(a, b, q_mod), c, q_mod);
    }

    function fr_mul_add_pm(
        uint256[84] memory m,
        uint256[] calldata proof,
        uint256 opcode,
        uint256 t
    ) internal pure returns (uint256) {
        for (uint256 i = 0; i < 32; i += 2) {
            uint256 a = opcode & 0xff;
            if (a != 0xff) {
                opcode >>= 8;
                uint256 b = opcode & 0xff;
                opcode >>= 8;
                t = addmod(mulmod(proof[a], m[b], q_mod), t, q_mod);
            } else {
                break;
            }
        }

        return t;
    }

    function fr_mul_add_mt(
        uint256[84] memory m,
        uint256 base,
        uint256 opcode,
        uint256 t
    ) internal pure returns (uint256) {
        for (uint256 i = 0; i < 32; i += 1) {
            uint256 a = opcode & 0xff;
            if (a != 0xff) {
                opcode >>= 8;
                t = addmod(mulmod(base, t, q_mod), m[a], q_mod);
            } else {
                break;
            }
        }

        return t;
    }

    function fr_reverse(uint256 input) internal pure returns (uint256 v) {
        v = input;

        // swap bytes
        v =
            ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) |
            ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);

        // swap 2-byte long pairs
        v =
            ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) |
            ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);

        // swap 4-byte long pairs
        v =
            ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) |
            ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);

        // swap 8-byte long pairs
        v =
            ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) |
            ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);

        // swap 16-byte long pairs
        v = (v >> 128) | (v << 128);
    }

    uint256 constant p_mod =
        21888242871839275222246405745257275088696311157297823662689037894645226208583;

    struct G1Point {
        uint256 x;
        uint256 y;
    }

    struct G2Point {
        uint256[2] x;
        uint256[2] y;
    }

    function ecc_from(uint256 x, uint256 y) internal pure returns (G1Point memory r) {
        r.x = x;
        r.y = y;
    }

    function ecc_add(
        uint256 ax,
        uint256 ay,
        uint256 bx,
        uint256 by
    ) internal view returns (uint256, uint256) {
        bool ret = false;
        G1Point memory r;
        uint256[4] memory input_points;

        input_points[0] = ax;
        input_points[1] = ay;
        input_points[2] = bx;
        input_points[3] = by;

        assembly {
            ret := staticcall(gas(), 6, input_points, 0x80, r, 0x40)
        }
        require(ret);

        return (r.x, r.y);
    }

    function ecc_sub(
        uint256 ax,
        uint256 ay,
        uint256 bx,
        uint256 by
    ) internal view returns (uint256, uint256) {
        return ecc_add(ax, ay, bx, p_mod - by);
    }

    function ecc_mul(uint256 px, uint256 py, uint256 s) internal view returns (uint256, uint256) {
        uint256[3] memory input;
        bool ret = false;
        G1Point memory r;

        input[0] = px;
        input[1] = py;
        input[2] = s;

        assembly {
            ret := staticcall(gas(), 7, input, 0x60, r, 0x40)
        }
        require(ret);

        return (r.x, r.y);
    }

    function _ecc_mul_add(uint256[5] memory input) internal view {
        bool ret = false;

        assembly {
            ret := staticcall(gas(), 7, input, 0x60, add(input, 0x20), 0x40)
        }
        require(ret);

        assembly {
            ret := staticcall(gas(), 6, add(input, 0x20), 0x80, add(input, 0x60), 0x40)
        }
        require(ret);
    }

    function ecc_mul_add(
        uint256 px,
        uint256 py,
        uint256 s,
        uint256 qx,
        uint256 qy
    ) internal view returns (uint256, uint256) {
        uint256[5] memory input;
        input[0] = px;
        input[1] = py;
        input[2] = s;
        input[3] = qx;
        input[4] = qy;

        _ecc_mul_add(input);

        return (input[3], input[4]);
    }

    function ecc_mul_add_pm(
        uint256[84] memory m,
        uint256[] calldata proof,
        uint256 opcode,
        uint256 t0,
        uint256 t1
    ) internal view returns (uint256, uint256) {
        uint256[5] memory input;
        input[3] = t0;
        input[4] = t1;
        for (uint256 i = 0; i < 32; i += 2) {
            uint256 a = opcode & 0xff;
            if (a != 0xff) {
                opcode >>= 8;
                uint256 b = opcode & 0xff;
                opcode >>= 8;
                input[0] = proof[a];
                input[1] = proof[a + 1];
                input[2] = m[b];
                _ecc_mul_add(input);
            } else {
                break;
            }
        }

        return (input[3], input[4]);
    }

    function update_hash_scalar(
        uint256 v,
        uint256[144] memory absorbing,
        uint256 pos
    ) internal pure {
        absorbing[pos++] = 0x02;
        absorbing[pos++] = v;
    }

    function update_hash_point(
        uint256 x,
        uint256 y,
        uint256[144] memory absorbing,
        uint256 pos
    ) internal pure {
        absorbing[pos++] = 0x01;
        absorbing[pos++] = x;
        absorbing[pos++] = y;
    }

    function to_scalar(bytes32 r) private pure returns (uint256 v) {
        uint256 tmp = uint256(r);
        tmp = fr_reverse(tmp);
        v = tmp % 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001;
    }

    function hash(
        uint256[144] memory absorbing,
        uint256 length
    ) private view returns (bytes32[1] memory v) {
        bool success;
        assembly {
            success := staticcall(sub(gas(), 2000), 2, absorbing, length, v, 32)
            switch success
            case 0 {
                invalid()
            }
        }
        assert(success);
    }

    function squeeze_challenge(
        uint256[144] memory absorbing,
        uint32 length
    ) internal view returns (uint256 v) {
        absorbing[length] = 0;
        bytes32 res = hash(absorbing, length * 32 + 1)[0];
        v = to_scalar(res);
        absorbing[0] = uint256(res);
        length = 1;
    }

    function get_verify_circuit_g2_s() internal pure returns (G2Point memory s) {
        s.x[0] = uint256(
            11029560635643983818885738975758839003131865733814273016801144285524936684972
        );
        s.x[1] = uint256(
            10665153487364924395451186075663597035495902496253353881119509267933768999122
        );
        s.y[0] = uint256(
            18790173187318184075281544452912101572166071561689308149111466352378718492148
        );
        s.y[1] = uint256(
            18755874088236213082062601512863221433227017725453112019151604716957419045549
        );
    }

    function get_verify_circuit_g2_n() internal pure returns (G2Point memory n) {
        n.x[0] = uint256(
            11559732032986387107991004021392285783925812861821192530917403151452391805634
        );
        n.x[1] = uint256(
            10857046999023057135944570762232829481370756359578518086990519993285655852781
        );
        n.y[0] = uint256(
            17805874995975841540914202342111839520379459829704422454583296818431106115052
        );
        n.y[1] = uint256(
            13392588948715843804641432497768002650278120570034223513918757245338268106653
        );
    }

    function get_target_circuit_g2_s() internal pure returns (G2Point memory s) {
        s.x[0] = uint256(
            11029560635643983818885738975758839003131865733814273016801144285524936684972
        );
        s.x[1] = uint256(
            10665153487364924395451186075663597035495902496253353881119509267933768999122
        );
        s.y[0] = uint256(
            18790173187318184075281544452912101572166071561689308149111466352378718492148
        );
        s.y[1] = uint256(
            18755874088236213082062601512863221433227017725453112019151604716957419045549
        );
    }

    function get_target_circuit_g2_n() internal pure returns (G2Point memory n) {
        n.x[0] = uint256(
            11559732032986387107991004021392285783925812861821192530917403151452391805634
        );
        n.x[1] = uint256(
            10857046999023057135944570762232829481370756359578518086990519993285655852781
        );
        n.y[0] = uint256(
            17805874995975841540914202342111839520379459829704422454583296818431106115052
        );
        n.y[1] = uint256(
            13392588948715843804641432497768002650278120570034223513918757245338268106653
        );
    }

    function get_wx_wg(
        uint256[] calldata proof,
        uint256[6] memory instances
    ) internal view returns (uint256, uint256, uint256, uint256) {
        uint256[84] memory m;
        uint256[144] memory absorbing;
        uint256 t0 = 0;
        uint256 t1 = 0;

        (t0, t1) = (
            ecc_mul(
                17789833092049612098151701936050358897264906311798010005527050942756852717298,
                10895600437035740537762783734736154159991587515994553016519128117735745182853,
                instances[0]
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                10543918255196573445400399528935519333175023389167175628125725368018220699826,
                12766487347162664556283708113947771881161039794532633041152166890738441603652,
                instances[1],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                17008203783108743202559440655757700533653854901598142405028623347702668473277,
                21814804208982435371780097106882418706885400711730256673026973858149650971299,
                instances[2],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                16811698451652309858363601322080891018704447409836823044944128338389236089077,
                18899539994854832158038246139972325143494193687503547200838261777721006548399,
                instances[3],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                5494852631096636459288403096263717084869030781267238852252122493224146048270,
                15370627062079108379015892130008397963684601860044622201721093508656326957966,
                instances[4],
                t0,
                t1
            )
        );
        (m[0], m[1]) = (
            ecc_mul_add(
                15605904389647533645433956766425544672547314322654580577432084020959766066522,
                2981854610112145395053419471185791838523574193883358734299031423326998004318,
                instances[5],
                t0,
                t1
            )
        );
        update_hash_scalar(HASH_SCALAR_VALUE, absorbing, 0);
        update_hash_point(m[0], m[1], absorbing, 2);
        for (t0 = 0; t0 <= 4; t0++) {
            update_hash_point(proof[0 + t0 * 2], proof[1 + t0 * 2], absorbing, 5 + t0 * 3);
        }
        m[2] = (squeeze_challenge(absorbing, 20));
        for (t0 = 0; t0 <= 13; t0++) {
            update_hash_point(proof[10 + t0 * 2], proof[11 + t0 * 2], absorbing, 1 + t0 * 3);
        }
        m[3] = (squeeze_challenge(absorbing, 43));
        m[4] = (squeeze_challenge(absorbing, 1));
        for (t0 = 0; t0 <= 9; t0++) {
            update_hash_point(proof[38 + t0 * 2], proof[39 + t0 * 2], absorbing, 1 + t0 * 3);
        }
        m[5] = (squeeze_challenge(absorbing, 31));
        for (t0 = 0; t0 <= 3; t0++) {
            update_hash_point(proof[58 + t0 * 2], proof[59 + t0 * 2], absorbing, 1 + t0 * 3);
        }
        m[6] = (squeeze_challenge(absorbing, 13));
        for (t0 = 0; t0 <= 70; t0++) {
            update_hash_scalar(proof[66 + t0 * 1], absorbing, 1 + t0 * 2);
        }
        m[7] = (squeeze_challenge(absorbing, 143));
        for (t0 = 0; t0 <= 3; t0++) {
            update_hash_point(proof[137 + t0 * 2], proof[138 + t0 * 2], absorbing, 1 + t0 * 3);
        }
        m[8] = (squeeze_challenge(absorbing, 13));
        m[9] = (
            mulmod(
                m[6],
                13446667982376394161563610564587413125564757801019538732601045199901075958935,
                q_mod
            )
        );
        m[10] = (
            mulmod(
                m[6],
                16569469942529664681363945218228869388192121720036659574609237682362097667612,
                q_mod
            )
        );
        m[11] = (
            mulmod(
                m[6],
                14803907026430593724305438564799066516271154714737734572920456128449769927233,
                q_mod
            )
        );
        m[12] = (fr_pow(m[6], 67108864));
        m[13] = (addmod(m[12], q_mod - 1, q_mod));
        m[14] = (
            mulmod(
                21888242545679039938882419398440172875981108180010270949818755658014750055173,
                m[13],
                q_mod
            )
        );
        t0 = (addmod(m[6], q_mod - 1, q_mod));
        m[14] = (fr_div(m[14], t0));
        m[15] = (
            mulmod(
                3495999257316610708652455694658595065970881061159015347599790211259094641512,
                m[13],
                q_mod
            )
        );
        t0 = (
            addmod(
                m[6],
                q_mod -
                    14803907026430593724305438564799066516271154714737734572920456128449769927233,
                q_mod
            )
        );
        m[15] = (fr_div(m[15], t0));
        m[16] = (
            mulmod(
                12851378806584061886934576302961450669946047974813165594039554733293326536714,
                m[13],
                q_mod
            )
        );
        t0 = (
            addmod(
                m[6],
                q_mod -
                    11377606117859914088982205826922132024839443553408109299929510653283289974216,
                q_mod
            )
        );
        m[16] = (fr_div(m[16], t0));
        m[17] = (
            mulmod(
                14638077285440018490948843142723135319134576188472316769433007423695824509066,
                m[13],
                q_mod
            )
        );
        t0 = (
            addmod(
                m[6],
                q_mod -
                    3693565015985198455139889557180396682968596245011005461846595820698933079918,
                q_mod
            )
        );
        m[17] = (fr_div(m[17], t0));
        m[18] = (
            mulmod(
                18027939092386982308810165776478549635922357517986691900813373197616541191289,
                m[13],
                q_mod
            )
        );
        t0 = (
            addmod(
                m[6],
                q_mod -
                    17329448237240114492580865744088056414251735686965494637158808787419781175510,
                q_mod
            )
        );
        m[18] = (fr_div(m[18], t0));
        m[19] = (
            mulmod(
                912591536032578604421866340844550116335029274442283291811906603256731601654,
                m[13],
                q_mod
            )
        );
        t0 = (
            addmod(
                m[6],
                q_mod -
                    6047398202650739717314770882059679662647667807426525133977681644606291529311,
                q_mod
            )
        );
        m[19] = (fr_div(m[19], t0));
        m[20] = (
            mulmod(
                17248638560015646562374089181598815896736916575459528793494921668169819478628,
                m[13],
                q_mod
            )
        );
        t0 = (
            addmod(
                m[6],
                q_mod -
                    16569469942529664681363945218228869388192121720036659574609237682362097667612,
                q_mod
            )
        );
        m[20] = (fr_div(m[20], t0));
        t0 = (addmod(m[15], m[16], q_mod));
        t0 = (addmod(t0, m[17], q_mod));
        t0 = (addmod(t0, m[18], q_mod));
        m[15] = (addmod(t0, m[19], q_mod));
        t0 = (fr_mul_add(proof[74], proof[72], proof[73]));
        t0 = (fr_mul_add(proof[75], proof[67], t0));
        t0 = (fr_mul_add(proof[76], proof[68], t0));
        t0 = (fr_mul_add(proof[77], proof[69], t0));
        t0 = (fr_mul_add(proof[78], proof[70], t0));
        m[16] = (fr_mul_add(proof[79], proof[71], t0));
        t0 = (mulmod(proof[67], proof[68], q_mod));
        m[16] = (fr_mul_add(proof[80], t0, m[16]));
        t0 = (mulmod(proof[69], proof[70], q_mod));
        m[16] = (fr_mul_add(proof[81], t0, m[16]));
        t0 = (addmod(1, q_mod - proof[97], q_mod));
        m[17] = (mulmod(m[14], t0, q_mod));
        t0 = (mulmod(proof[100], proof[100], q_mod));
        t0 = (addmod(t0, q_mod - proof[100], q_mod));
        m[18] = (mulmod(m[20], t0, q_mod));
        t0 = (addmod(proof[100], q_mod - proof[99], q_mod));
        m[19] = (mulmod(t0, m[14], q_mod));
        m[21] = (mulmod(m[3], m[6], q_mod));
        t0 = (addmod(m[20], m[15], q_mod));
        m[15] = (addmod(1, q_mod - t0, q_mod));
        m[22] = (addmod(proof[67], m[4], q_mod));
        t0 = (fr_mul_add(proof[91], m[3], m[22]));
        m[23] = (mulmod(t0, proof[98], q_mod));
        t0 = (addmod(m[22], m[21], q_mod));
        m[22] = (mulmod(t0, proof[97], q_mod));
        m[24] = (
            mulmod(
                4131629893567559867359510883348571134090853742863529169391034518566172092834,
                m[21],
                q_mod
            )
        );
        m[25] = (addmod(proof[68], m[4], q_mod));
        t0 = (fr_mul_add(proof[92], m[3], m[25]));
        m[23] = (mulmod(t0, m[23], q_mod));
        t0 = (addmod(m[25], m[24], q_mod));
        m[22] = (mulmod(t0, m[22], q_mod));
        m[24] = (
            mulmod(
                4131629893567559867359510883348571134090853742863529169391034518566172092834,
                m[24],
                q_mod
            )
        );
        m[25] = (addmod(proof[69], m[4], q_mod));
        t0 = (fr_mul_add(proof[93], m[3], m[25]));
        m[23] = (mulmod(t0, m[23], q_mod));
        t0 = (addmod(m[25], m[24], q_mod));
        m[22] = (mulmod(t0, m[22], q_mod));
        m[24] = (
            mulmod(
                4131629893567559867359510883348571134090853742863529169391034518566172092834,
                m[24],
                q_mod
            )
        );
        t0 = (addmod(m[23], q_mod - m[22], q_mod));
        m[22] = (mulmod(t0, m[15], q_mod));
        m[21] = (
            mulmod(
                m[21],
                11166246659983828508719468090013646171463329086121580628794302409516816350802,
                q_mod
            )
        );
        m[23] = (addmod(proof[70], m[4], q_mod));
        t0 = (fr_mul_add(proof[94], m[3], m[23]));
        m[24] = (mulmod(t0, proof[101], q_mod));
        t0 = (addmod(m[23], m[21], q_mod));
        m[23] = (mulmod(t0, proof[100], q_mod));
        m[21] = (
            mulmod(
                4131629893567559867359510883348571134090853742863529169391034518566172092834,
                m[21],
                q_mod
            )
        );
        m[25] = (addmod(proof[71], m[4], q_mod));
        t0 = (fr_mul_add(proof[95], m[3], m[25]));
        m[24] = (mulmod(t0, m[24], q_mod));
        t0 = (addmod(m[25], m[21], q_mod));
        m[23] = (mulmod(t0, m[23], q_mod));
        m[21] = (
            mulmod(
                4131629893567559867359510883348571134090853742863529169391034518566172092834,
                m[21],
                q_mod
            )
        );
        m[25] = (addmod(proof[66], m[4], q_mod));
        t0 = (fr_mul_add(proof[96], m[3], m[25]));
        m[24] = (mulmod(t0, m[24], q_mod));
        t0 = (addmod(m[25], m[21], q_mod));
        m[23] = (mulmod(t0, m[23], q_mod));
        m[21] = (
            mulmod(
                4131629893567559867359510883348571134090853742863529169391034518566172092834,
                m[21],
                q_mod
            )
        );
        t0 = (addmod(m[24], q_mod - m[23], q_mod));
        m[21] = (mulmod(t0, m[15], q_mod));
        t0 = (addmod(proof[104], m[3], q_mod));
        m[23] = (mulmod(proof[103], t0, q_mod));
        t0 = (addmod(proof[106], m[4], q_mod));
        m[23] = (mulmod(m[23], t0, q_mod));
        m[24] = (mulmod(proof[67], proof[82], q_mod));
        m[2] = (mulmod(0, m[2], q_mod));
        m[24] = (addmod(m[2], m[24], q_mod));
        m[25] = (addmod(m[2], proof[83], q_mod));
        m[26] = (addmod(proof[104], q_mod - proof[106], q_mod));
        t0 = (addmod(1, q_mod - proof[102], q_mod));
        m[27] = (mulmod(m[14], t0, q_mod));
        t0 = (mulmod(proof[102], proof[102], q_mod));
        t0 = (addmod(t0, q_mod - proof[102], q_mod));
        m[28] = (mulmod(m[20], t0, q_mod));
        t0 = (addmod(m[24], m[3], q_mod));
        m[24] = (mulmod(proof[102], t0, q_mod));
        m[25] = (addmod(m[25], m[4], q_mod));
        t0 = (mulmod(m[24], m[25], q_mod));
        t0 = (addmod(m[23], q_mod - t0, q_mod));
        m[23] = (mulmod(t0, m[15], q_mod));
        m[24] = (mulmod(m[14], m[26], q_mod));
        t0 = (addmod(proof[104], q_mod - proof[105], q_mod));
        t0 = (mulmod(m[26], t0, q_mod));
        m[26] = (mulmod(t0, m[15], q_mod));
        t0 = (addmod(proof[109], m[3], q_mod));
        m[29] = (mulmod(proof[108], t0, q_mod));
        t0 = (addmod(proof[111], m[4], q_mod));
        m[29] = (mulmod(m[29], t0, q_mod));
        m[30] = (fr_mul_add(proof[82], proof[68], m[2]));
        m[31] = (addmod(proof[109], q_mod - proof[111], q_mod));
        t0 = (addmod(1, q_mod - proof[107], q_mod));
        m[32] = (mulmod(m[14], t0, q_mod));
        t0 = (mulmod(proof[107], proof[107], q_mod));
        t0 = (addmod(t0, q_mod - proof[107], q_mod));
        m[33] = (mulmod(m[20], t0, q_mod));
        t0 = (addmod(m[30], m[3], q_mod));
        t0 = (mulmod(proof[107], t0, q_mod));
        t0 = (mulmod(t0, m[25], q_mod));
        t0 = (addmod(m[29], q_mod - t0, q_mod));
        m[29] = (mulmod(t0, m[15], q_mod));
        m[30] = (mulmod(m[14], m[31], q_mod));
        t0 = (addmod(proof[109], q_mod - proof[110], q_mod));
        t0 = (mulmod(m[31], t0, q_mod));
        m[31] = (mulmod(t0, m[15], q_mod));
        t0 = (addmod(proof[114], m[3], q_mod));
        m[34] = (mulmod(proof[113], t0, q_mod));
        t0 = (addmod(proof[116], m[4], q_mod));
        m[34] = (mulmod(m[34], t0, q_mod));
        m[35] = (fr_mul_add(proof[82], proof[69], m[2]));
        m[36] = (addmod(proof[114], q_mod - proof[116], q_mod));
        t0 = (addmod(1, q_mod - proof[112], q_mod));
        m[37] = (mulmod(m[14], t0, q_mod));
        t0 = (mulmod(proof[112], proof[112], q_mod));
        t0 = (addmod(t0, q_mod - proof[112], q_mod));
        m[38] = (mulmod(m[20], t0, q_mod));
        t0 = (addmod(m[35], m[3], q_mod));
        t0 = (mulmod(proof[112], t0, q_mod));
        t0 = (mulmod(t0, m[25], q_mod));
        t0 = (addmod(m[34], q_mod - t0, q_mod));
        m[34] = (mulmod(t0, m[15], q_mod));
        m[35] = (mulmod(m[14], m[36], q_mod));
        t0 = (addmod(proof[114], q_mod - proof[115], q_mod));
        t0 = (mulmod(m[36], t0, q_mod));
        m[36] = (mulmod(t0, m[15], q_mod));
        t0 = (addmod(proof[119], m[3], q_mod));
        m[39] = (mulmod(proof[118], t0, q_mod));
        t0 = (addmod(proof[121], m[4], q_mod));
        m[39] = (mulmod(m[39], t0, q_mod));
        m[40] = (fr_mul_add(proof[82], proof[70], m[2]));
        m[41] = (addmod(proof[119], q_mod - proof[121], q_mod));
        t0 = (addmod(1, q_mod - proof[117], q_mod));
        m[42] = (mulmod(m[14], t0, q_mod));
        t0 = (mulmod(proof[117], proof[117], q_mod));
        t0 = (addmod(t0, q_mod - proof[117], q_mod));
        m[43] = (mulmod(m[20], t0, q_mod));
        t0 = (addmod(m[40], m[3], q_mod));
        t0 = (mulmod(proof[117], t0, q_mod));
        t0 = (mulmod(t0, m[25], q_mod));
        t0 = (addmod(m[39], q_mod - t0, q_mod));
        m[25] = (mulmod(t0, m[15], q_mod));
        m[39] = (mulmod(m[14], m[41], q_mod));
        t0 = (addmod(proof[119], q_mod - proof[120], q_mod));
        t0 = (mulmod(m[41], t0, q_mod));
        m[40] = (mulmod(t0, m[15], q_mod));
        t0 = (addmod(proof[124], m[3], q_mod));
        m[41] = (mulmod(proof[123], t0, q_mod));
        t0 = (addmod(proof[126], m[4], q_mod));
        m[41] = (mulmod(m[41], t0, q_mod));
        m[44] = (fr_mul_add(proof[84], proof[67], m[2]));
        m[45] = (addmod(m[2], proof[85], q_mod));
        m[46] = (addmod(proof[124], q_mod - proof[126], q_mod));
        t0 = (addmod(1, q_mod - proof[122], q_mod));
        m[47] = (mulmod(m[14], t0, q_mod));
        t0 = (mulmod(proof[122], proof[122], q_mod));
        t0 = (addmod(t0, q_mod - proof[122], q_mod));
        m[48] = (mulmod(m[20], t0, q_mod));
        t0 = (addmod(m[44], m[3], q_mod));
        m[44] = (mulmod(proof[122], t0, q_mod));
        t0 = (addmod(m[45], m[4], q_mod));
        t0 = (mulmod(m[44], t0, q_mod));
        t0 = (addmod(m[41], q_mod - t0, q_mod));
        m[41] = (mulmod(t0, m[15], q_mod));
        m[44] = (mulmod(m[14], m[46], q_mod));
        t0 = (addmod(proof[124], q_mod - proof[125], q_mod));
        t0 = (mulmod(m[46], t0, q_mod));
        m[45] = (mulmod(t0, m[15], q_mod));
        t0 = (addmod(proof[129], m[3], q_mod));
        m[46] = (mulmod(proof[128], t0, q_mod));
        t0 = (addmod(proof[131], m[4], q_mod));
        m[46] = (mulmod(m[46], t0, q_mod));
        m[49] = (fr_mul_add(proof[86], proof[67], m[2]));
        m[50] = (addmod(m[2], proof[87], q_mod));
        m[51] = (addmod(proof[129], q_mod - proof[131], q_mod));
        t0 = (addmod(1, q_mod - proof[127], q_mod));
        m[52] = (mulmod(m[14], t0, q_mod));
        t0 = (mulmod(proof[127], proof[127], q_mod));
        t0 = (addmod(t0, q_mod - proof[127], q_mod));
        m[53] = (mulmod(m[20], t0, q_mod));
        t0 = (addmod(m[49], m[3], q_mod));
        m[49] = (mulmod(proof[127], t0, q_mod));
        t0 = (addmod(m[50], m[4], q_mod));
        t0 = (mulmod(m[49], t0, q_mod));
        t0 = (addmod(m[46], q_mod - t0, q_mod));
        m[46] = (mulmod(t0, m[15], q_mod));
        m[49] = (mulmod(m[14], m[51], q_mod));
        t0 = (addmod(proof[129], q_mod - proof[130], q_mod));
        t0 = (mulmod(m[51], t0, q_mod));
        m[50] = (mulmod(t0, m[15], q_mod));
        t0 = (addmod(proof[134], m[3], q_mod));
        m[51] = (mulmod(proof[133], t0, q_mod));
        t0 = (addmod(proof[136], m[4], q_mod));
        m[51] = (mulmod(m[51], t0, q_mod));
        m[54] = (fr_mul_add(proof[88], proof[67], m[2]));
        m[2] = (addmod(m[2], proof[89], q_mod));
        m[55] = (addmod(proof[134], q_mod - proof[136], q_mod));
        t0 = (addmod(1, q_mod - proof[132], q_mod));
        m[56] = (mulmod(m[14], t0, q_mod));
        t0 = (mulmod(proof[132], proof[132], q_mod));
        t0 = (addmod(t0, q_mod - proof[132], q_mod));
        m[20] = (mulmod(m[20], t0, q_mod));
        t0 = (addmod(m[54], m[3], q_mod));
        m[3] = (mulmod(proof[132], t0, q_mod));
        t0 = (addmod(m[2], m[4], q_mod));
        t0 = (mulmod(m[3], t0, q_mod));
        t0 = (addmod(m[51], q_mod - t0, q_mod));
        m[2] = (mulmod(t0, m[15], q_mod));
        m[3] = (mulmod(m[14], m[55], q_mod));
        t0 = (addmod(proof[134], q_mod - proof[135], q_mod));
        t0 = (mulmod(m[55], t0, q_mod));
        m[4] = (mulmod(t0, m[15], q_mod));
        t0 = (fr_mul_add(m[5], 0, m[16]));
        t0 = (
            fr_mul_add_mt(
                m,
                m[5],
                24064768791442479290152634096194013545513974547709823832001394403118888981009,
                t0
            )
        );
        t0 = (fr_mul_add_mt(m, m[5], 4704208815882882920750, t0));
        m[2] = (fr_div(t0, m[13]));
        m[3] = (mulmod(m[8], m[8], q_mod));
        m[4] = (mulmod(m[3], m[8], q_mod));
        (t0, t1) = (ecc_mul(proof[143], proof[144], m[4]));
        (t0, t1) = (ecc_mul_add_pm(m, proof, 281470825071501, t0, t1));
        (m[14], m[15]) = (ecc_add(t0, t1, proof[137], proof[138]));
        m[5] = (mulmod(m[4], m[11], q_mod));
        m[11] = (mulmod(m[4], m[7], q_mod));
        m[13] = (mulmod(m[11], m[7], q_mod));
        m[16] = (mulmod(m[13], m[7], q_mod));
        m[17] = (mulmod(m[16], m[7], q_mod));
        m[18] = (mulmod(m[17], m[7], q_mod));
        m[19] = (mulmod(m[18], m[7], q_mod));
        t0 = (mulmod(m[19], proof[135], q_mod));
        t0 = (fr_mul_add_pm(m, proof, 79227007564587019091207590530, t0));
        m[20] = (fr_mul_add(proof[105], m[4], t0));
        m[10] = (mulmod(m[3], m[10], q_mod));
        m[20] = (fr_mul_add(proof[99], m[3], m[20]));
        m[9] = (mulmod(m[8], m[9], q_mod));
        m[21] = (mulmod(m[8], m[7], q_mod));
        for (t0 = 0; t0 < 8; t0++) {
            m[22 + t0 * 1] = (mulmod(m[21 + t0 * 1], m[7 + t0 * 0], q_mod));
        }
        t0 = (mulmod(m[29], proof[133], q_mod));
        t0 = (fr_mul_add_pm(m, proof, 1461480058012745347196003969984389955172320353408, t0));
        m[20] = (addmod(m[20], t0, q_mod));
        m[3] = (addmod(m[3], m[21], q_mod));
        m[21] = (mulmod(m[7], m[7], q_mod));
        m[30] = (mulmod(m[21], m[7], q_mod));
        for (t0 = 0; t0 < 50; t0++) {
            m[31 + t0 * 1] = (mulmod(m[30 + t0 * 1], m[7 + t0 * 0], q_mod));
        }
        m[81] = (mulmod(m[80], proof[90], q_mod));
        m[82] = (mulmod(m[79], m[12], q_mod));
        m[83] = (mulmod(m[82], m[12], q_mod));
        m[12] = (mulmod(m[83], m[12], q_mod));
        t0 = (fr_mul_add(m[79], m[2], m[81]));
        t0 = (
            fr_mul_add_pm(
                m,
                proof,
                28637501128329066231612878461967933875285131620580756137874852300330784214624,
                t0
            )
        );
        t0 = (
            fr_mul_add_pm(
                m,
                proof,
                21474593857386732646168474467085622855647258609351047587832868301163767676495,
                t0
            )
        );
        t0 = (
            fr_mul_add_pm(
                m,
                proof,
                14145600374170319983429588659751245017860232382696106927048396310641433325177,
                t0
            )
        );
        t0 = (fr_mul_add_pm(m, proof, 18446470583433829957, t0));
        t0 = (addmod(t0, proof[66], q_mod));
        m[2] = (addmod(m[20], t0, q_mod));
        m[19] = (addmod(m[19], m[54], q_mod));
        m[20] = (addmod(m[29], m[53], q_mod));
        m[18] = (addmod(m[18], m[51], q_mod));
        m[28] = (addmod(m[28], m[50], q_mod));
        m[17] = (addmod(m[17], m[48], q_mod));
        m[27] = (addmod(m[27], m[47], q_mod));
        m[16] = (addmod(m[16], m[45], q_mod));
        m[26] = (addmod(m[26], m[44], q_mod));
        m[13] = (addmod(m[13], m[42], q_mod));
        m[25] = (addmod(m[25], m[41], q_mod));
        m[11] = (addmod(m[11], m[39], q_mod));
        m[24] = (addmod(m[24], m[38], q_mod));
        m[4] = (addmod(m[4], m[36], q_mod));
        m[23] = (addmod(m[23], m[35], q_mod));
        m[22] = (addmod(m[22], m[34], q_mod));
        m[3] = (addmod(m[3], m[33], q_mod));
        m[8] = (addmod(m[8], m[32], q_mod));
        (t0, t1) = (ecc_mul(proof[143], proof[144], m[5]));
        (t0, t1) = (
            ecc_mul_add_pm(
                m,
                proof,
                10933423423422768024429730621579321771439401845242250760130969989159573132066,
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add_pm(m, proof, 1461486238301980199876269201563775120819706402602, t0, t1)
        );
        (t0, t1) = (
            ecc_mul_add(
                15738646021458965415875359585850781728243543812280308548595326491476474302955,
                11051787057691458774492360569996861082650504993138626819003221898493178050035,
                m[78],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                1475696300049442917028467159105389721116357718795651750519726871994775216295,
                8164600896470502362564790171132408561435532006283737733288998283496711243676,
                m[77],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                20037340314091442687430628478276133171639671164499869262269052470554953532798,
                8617374172579535083448320238697316576863116103559910108651404828163902641209,
                m[76],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                2590328984608469713687780064619512676013076673646564572496583030882285919986,
                638589679743187931075527957989835488430425780368511997293885082437553073995,
                m[75],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                12146901029446786042585650348552207198317726707649479980494243975966168586800,
                21004224368627752160019614542278109958896643390087793101726552507600837692403,
                m[74],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                12484898247528969713369796601188723761879994746350513864107241452597517714843,
                20710920799110457828705640996188165458350589749232606705712996851057245387342,
                m[73],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                19886509832083393598366465489701294384803664485460545523068306491024326504725,
                3485984208124097149766319408505384162933092797198027169851040569744728509599,
                m[72],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                16404659647391097455159976273992692920152024451288249273063848656492758204389,
                21408247695101639349153277734734938504956965085851869757712649884779075439039,
                m[71],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                17108853774466418779129374196319580280286578385405087585516556746536875115907,
                19908760740801913322265695807368645417588084579607860033571444712857010186774,
                m[70],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                21629254704290212852937802382494716478889797428965842728144220543246322859554,
                21658265822014679146185833630076754140073759884763957789271421091032211025157,
                m[69],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                19886509832083393598366465489701294384803664485460545523068306491024326504725,
                3485984208124097149766319408505384162933092797198027169851040569744728509599,
                m[68],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                11494485494412314036912556883437307149797432820383623637519035656794042012095,
                2410489863957456775707779378033814786966154706946761951908809676618278443068,
                m[67],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                21627166622184628562834675422084345034193467320009306763329316593023720936150,
                2103102746100002335801212537254725041663108226492711350135413308275232360031,
                m[66],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                5833003470394876828918971407337456408257193352118920119145576292426638346769,
                21517803666035190572447529780797402738873790305626876614632047398304071926756,
                m[65],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                15660369869316007654180594416910060098683972168851332428191944238046914461816,
                619475474362397505663248548997199145354664366559823796718165155533015020663,
                m[64],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                14357122501752010758022868212927876311895459359009009733271861104226260045594,
                16126281904050270224623042280467621555101638794226278850100489095734549617918,
                m[63],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                16761622113591657736617505151691036744631771696590303134292673377873890818119,
                6686562932890286592033158402117293865477246854478945021606806487507223075395,
                m[62],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                17229942418385200082062914700911519717772513320730624793493549643743556744576,
                5621800961668224347956111291579888905398405975749251495793956267512617886424,
                m[61],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                16719044151302115613031649349289232028937886588938900980773255912070590283284,
                8996560925096856479601278542730270549020210858287011041285301443498627852162,
                m[60],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                456517166543705985184166475990427022518096989415429862512544596075628104766,
                4584298690582989400824123720778697263357419965108679590688166449396561305804,
                m[59],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                8841671929736409341755876439864603183349976850407514895007839042769729845276,
                19908694064427411410925537740321794844212081049969432136633191256148570974369,
                m[58],
                t0,
                t1
            )
        );
        (t0, t1) = (
            ecc_mul_add(
                2104154327908680857716247273517715744719141711240749880794301438788948027686,
                7499686005093585017307496107151445622144347868958974916146393505438758744367,
                m[57],
                t0,
                t1
            )
        );
        (t0, t1) = (ecc_mul_add(M_56_PX_VALUE, M_56_PY_VALUE, m[56], t0, t1));
        (t0, t1) = (
            ecc_mul_add_pm(
                m,
                proof,
                6277008573546246765208814532330797927747086570010716419876,
                t0,
                t1
            )
        );
        (m[0], m[1]) = (ecc_add(t0, t1, m[0], m[1]));
        (t0, t1) = (ecc_mul(1, 2, m[2]));
        (m[0], m[1]) = (ecc_sub(m[0], m[1], t0, t1));
        return (m[14], m[15], m[0], m[1]);
    }

    function verify(
        uint256[] calldata proof,
        uint256[] calldata target_circuit_final_pair,
        bytes32 publicInputHash
    ) public view returns (bool) {
        uint256[6] memory instances;
        instances[0] = target_circuit_final_pair[0] & ((1 << 136) - 1);
        instances[1] =
            (target_circuit_final_pair[0] >> 136) +
            ((target_circuit_final_pair[1] & 1) << 136);
        instances[2] = target_circuit_final_pair[2] & ((1 << 136) - 1);
        instances[3] =
            (target_circuit_final_pair[2] >> 136) +
            ((target_circuit_final_pair[3] & 1) << 136);

        instances[4] = uint256(publicInputHash) >> (8 * 16);
        instances[5] = uint256(publicInputHash) & uint256(2 ** 128 - 1);

        uint256 x0 = 0;
        uint256 x1 = 0;
        uint256 y0 = 0;
        uint256 y1 = 0;

        G1Point[] memory g1_points = new G1Point[](2);
        G2Point[] memory g2_points = new G2Point[](2);

        (x0, y0, x1, y1) = get_wx_wg(proof, instances);
        g1_points[0].x = x0;
        g1_points[0].y = y0;
        g1_points[1].x = x1;
        g1_points[1].y = y1;
        g2_points[0] = get_verify_circuit_g2_s();
        g2_points[1] = get_verify_circuit_g2_n();

        if (!pairing(g1_points, g2_points)) {
            return false;
        }

        g1_points[0].x = target_circuit_final_pair[0];
        g1_points[0].y = target_circuit_final_pair[1];
        g1_points[1].x = target_circuit_final_pair[2];
        g1_points[1].y = target_circuit_final_pair[3];
        g2_points[0] = get_target_circuit_g2_s();
        g2_points[1] = get_target_circuit_g2_n();

        if (!pairing(g1_points, g2_points)) {
            return false;
        }

        return true;
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { Encoding } from "./Encoding.sol";
import { RLPWriter } from "./rlp/RLPWriter.sol";
import { Types } from "./Types.sol";

/**
 * @title Hashing
 * @notice Hashing handles Kroma's various different hashing schemes.
 */
library Hashing {
    /**
     * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a
     *         given deposit is sent to the L2 system. Useful for searching for a deposit in the L2
     *         system.
     *
     * @param _tx           User deposit transaction to hash.
     * @param _isKromaDepTx Whether the given transaction is a KromaDepositTx.
     *
     * @return Hash of the RLP encoded L2 deposit transaction.
     */
    function hashDepositTransaction(
        Types.UserDepositTransaction memory _tx,
        bool _isKromaDepTx
    ) internal pure returns (bytes32) {
        return keccak256(Encoding.encodeDepositTransaction(_tx, _isKromaDepTx));
    }

    /**
     * @notice Computes the deposit transaction's "source hash", a value that guarantees the hash
     *         of the L2 transaction that corresponds to a deposit is unique and is
     *         deterministically generated from L1 transaction data.
     *
     * @param _l1BlockHash Hash of the L1 block where the deposit was included.
     * @param _logIndex    The index of the log that created the deposit transaction.
     *
     * @return Hash of the deposit transaction's "source hash".
     */
    function hashDepositSource(
        bytes32 _l1BlockHash,
        uint64 _logIndex
    ) internal pure returns (bytes32) {
        bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));
        return keccak256(abi.encode(bytes32(0), depositId));
    }

    /**
     * @notice Hashes the cross domain message based on the version that is encoded into the
     *         message nonce.
     *
     * @param _nonce    Message nonce with version encoded into the first two bytes.
     * @param _sender   Address of the sender of the message.
     * @param _target   Address of the target of the message.
     * @param _value    ETH value to send to the target.
     * @param _gasLimit Gas limit to use for the message.
     * @param _data     Data to send with the message.
     *
     * @return Hashed cross domain message.
     */
    function hashCrossDomainMessage(
        uint256 _nonce,
        address _sender,
        address _target,
        uint256 _value,
        uint256 _gasLimit,
        bytes memory _data
    ) internal pure returns (bytes32) {
        (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);
        if (version == 0) {
            return hashCrossDomainMessageV0(_nonce, _sender, _target, _value, _gasLimit, _data);
        } else {
            revert("Hashing: unknown cross domain message version");
        }
    }

    /**
     * @notice Hashes a cross domain message based on the V0 (current) encoding.
     *
     * @param _nonce    Message nonce.
     * @param _sender   Address of the sender of the message.
     * @param _target   Address of the target of the message.
     * @param _value    ETH value to send to the target.
     * @param _gasLimit Gas limit to use for the message.
     * @param _data     Data to send with the message.
     *
     * @return Hashed cross domain message.
     */
    function hashCrossDomainMessageV0(
        uint256 _nonce,
        address _sender,
        address _target,
        uint256 _value,
        uint256 _gasLimit,
        bytes memory _data
    ) internal pure returns (bytes32) {
        return
            keccak256(
                Encoding.encodeCrossDomainMessageV0(
                    _nonce,
                    _sender,
                    _target,
                    _value,
                    _gasLimit,
                    _data
                )
            );
    }

    /**
     * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract
     *
     * @param _tx Withdrawal transaction to hash.
     *
     * @return Hashed withdrawal transaction.
     */
    function hashWithdrawal(
        Types.WithdrawalTransaction memory _tx
    ) internal pure returns (bytes32) {
        return
            keccak256(
                abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)
            );
    }

    /**
     * @notice Hashes the various elements of an output root proof into an output root hash which
     *         can be used to check if the proof is valid.
     *
     * @param _outputRootProof Output root proof which should hash to an output root.
     *
     * @return Hashed output root proof.
     */
    function hashOutputRootProof(
        Types.OutputRootProof memory _outputRootProof
    ) internal pure returns (bytes32) {
        // Note that output root proof will be hashed including nextBlockHash (KromaOutputV0),
        // otherwise not including (OutputV0).
        if (_outputRootProof.nextBlockHash == bytes32(0)) {
            return
                keccak256(
                    abi.encode(
                        _outputRootProof.version,
                        _outputRootProof.stateRoot,
                        _outputRootProof.messagePasserStorageRoot,
                        _outputRootProof.latestBlockhash
                    )
                );
        }
        return
            keccak256(
                abi.encode(
                    _outputRootProof.version,
                    _outputRootProof.stateRoot,
                    _outputRootProof.messagePasserStorageRoot,
                    _outputRootProof.latestBlockhash,
                    _outputRootProof.nextBlockHash
                )
            );
    }

    /**
     * @notice Fills the values of the block hash fields to a given bytes.
     *
     * @param _publicInput Public input which should be hashed to a block hash.
     * @param _rlps        Pre-RLP encoded data which should be hashed to a block hash.
     * @param _raw         An array of bytes to be populated.
     */
    function _fillBlockHashFieldsToBytes(
        Types.PublicInput memory _publicInput,
        Types.BlockHeaderRLP memory _rlps,
        bytes[] memory _raw
    ) private pure {
        _raw[0] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.parentHash));
        _raw[1] = _rlps.uncleHash;
        _raw[2] = _rlps.coinbase;
        _raw[3] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.stateRoot));
        _raw[4] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.transactionsRoot));
        _raw[5] = _rlps.receiptsRoot;
        _raw[6] = _rlps.logsBloom;
        _raw[7] = _rlps.difficulty;
        _raw[8] = RLPWriter.writeUint(_publicInput.number);
        _raw[9] = RLPWriter.writeUint(_publicInput.gasLimit);
        _raw[10] = _rlps.gasUsed;
        _raw[11] = RLPWriter.writeUint(_publicInput.timestamp);
        _raw[12] = _rlps.extraData;
        _raw[13] = _rlps.mixHash;
        _raw[14] = _rlps.nonce;
        _raw[15] = RLPWriter.writeUint(_publicInput.baseFee);
    }

    /**
     * @notice Hashes the various elements of a block header into a block hash(before shanghai).
     *
     * @param _publicInput Public input which should be hashed to a block hash.
     * @param _rlps        Pre-RLP encoded data which should be hashed to a block hash.
     *
     * @return Hashed block header.
     */
    function hashBlockHeader(
        Types.PublicInput memory _publicInput,
        Types.BlockHeaderRLP memory _rlps
    ) internal pure returns (bytes32) {
        bytes[] memory raw = new bytes[](16);
        _fillBlockHashFieldsToBytes(_publicInput, _rlps, raw);
        return keccak256(RLPWriter.writeList(raw));
    }

    /**
     * @notice Hashes the various elements of a block header into a block hash(after shanghai).
     *
     * @param _publicInput Public input which should be hashed to a block hash.
     * @param _rlps        Pre-RLP encoded data which should be hashed to a block hash.
     *
     * @return Hashed block header.
     */
    function hashBlockHeaderShanghai(
        Types.PublicInput memory _publicInput,
        Types.BlockHeaderRLP memory _rlps
    ) internal pure returns (bytes32) {
        bytes[] memory raw = new bytes[](17);
        _fillBlockHashFieldsToBytes(_publicInput, _rlps, raw);
        raw[16] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.withdrawalsRoot));
        return keccak256(RLPWriter.writeList(raw));
    }

    /**
     * @notice Hashes the various elements of a block header into a block hash(after Cancun).
     *
     * @param _publicInput Public input which should be hashed to a block hash.
     * @param _rlps        Pre-RLP encoded data which should be hashed to a block hash.
     *
     * @return Hashed block header.
     */
    function hashBlockHeaderCancun(
        Types.PublicInput memory _publicInput,
        Types.BlockHeaderRLP memory _rlps
    ) internal pure returns (bytes32) {
        bytes[] memory raw = new bytes[](20);
        _fillBlockHashFieldsToBytes(_publicInput, _rlps, raw);
        raw[16] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.withdrawalsRoot));
        raw[17] = RLPWriter.writeUint(_publicInput.blobGasUsed);
        raw[18] = RLPWriter.writeUint(_publicInput.excessBlobGas);
        raw[19] = RLPWriter.writeBytes(abi.encodePacked(_publicInput.parentBeaconRoot));
        return keccak256(RLPWriter.writeList(raw));
    }

    /**
     * @notice Hashes the various elements of a public input into a public input hash for zkEVM proof.
     *
     * @param _prevStateRoot Previous state root.
     * @param _publicInput   Public input which should be hashed to a public input hash.
     * @param _dummyHashes   Dummy hashes returned from generateDummyHashes().
     *
     * @return Hash of public input for zkEVM proof.
     */
    function hashZkEvmPublicInput(
        bytes32 _prevStateRoot,
        Types.PublicInput memory _publicInput,
        bytes32[] memory _dummyHashes
    ) internal pure returns (bytes32) {
        return
            keccak256(
                abi.encodePacked(
                    _prevStateRoot,
                    _publicInput.stateRoot,
                    // NOTE(0xHansLee): the withdrawalsRoot is not used in Scroll's zkEVM circuit, so it is filled by zero
                    bytes32(0),
                    _publicInput.blockHash,
                    _publicInput.parentHash,
                    _publicInput.number,
                    _publicInput.timestamp,
                    _publicInput.baseFee,
                    _publicInput.gasLimit,
                    uint16(_publicInput.txHashes.length),
                    _publicInput.txHashes,
                    _dummyHashes
                )
            );
    }

    /**
     * @notice Generates a bytes32 array filled with a dummy hash for the given length.
     *
     * @param _dummyHashes Dummy hash.
     * @param _length      A length of the array.
     *
     * @return Bytes32 array filled with dummy hash.
     */
    function generateDummyHashes(
        bytes32 _dummyHashes,
        uint256 _length
    ) internal pure returns (bytes32[] memory) {
        bytes32[] memory hashes = new bytes32[](_length);
        for (uint256 i = 0; i < _length; i++) {
            hashes[i] = _dummyHashes;
        }
        return hashes;
    }
}

File 4 of 10 : Predeploys.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title Predeploys
 * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.
 */
library Predeploys {
    /**
     * @notice Address of the ProxyAdmin predeploy.
     */
    address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000000;

    /**
     * @notice Address of the KromaL1Block predeploy used before Kroma MPT hardfork.
     */
    address internal constant KROMA_L1_BLOCK_ATTRIBUTES =
        0x4200000000000000000000000000000000000002;

    /**
     * @notice Address of the L2ToL1MessagePasser predeploy.
     */
    address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000003;

    /**
     * @notice Address of the L2CrossDomainMessenger predeploy.
     */
    address internal constant L2_CROSS_DOMAIN_MESSENGER =
        0x4200000000000000000000000000000000000004;

    /**
     * @notice Address of the GasPriceOracle predeploy. Includes fee information
     *         and helpers for computing the L1 portion of the transaction fee.
     */
    address internal constant GAS_PRICE_ORACLE = 0x4200000000000000000000000000000000000005;

    /**
     * @notice Address of the ProtocolVault predeploy used before Kroma MPT hardfork.
     */
    address internal constant PROTOCOL_VAULT = 0x4200000000000000000000000000000000000006;

    /**
     * @notice Address of the L1FeeVault predeploy used before Kroma MPT hardfork.
     */
    address internal constant KROMA_L1_FEE_VAULT = 0x4200000000000000000000000000000000000007;

    /**
     * @notice Address of the ValidatorRewardVault predeploy used before Kroma MPT hardfork.
     */
    address internal constant VALIDATOR_REWARD_VAULT = 0x4200000000000000000000000000000000000008;

    /**
     * @notice Address of the L2StandardBridge predeploy.
     */
    address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000009;

    /**
     * @notice Address of the L2ERC721Bridge predeploy.
     */
    address internal constant L2_ERC721_BRIDGE = 0x420000000000000000000000000000000000000A;

    /**
     * @notice Address of the KromaMintableERC20Factory predeploy.
     */
    address internal constant KROMA_MINTABLE_ERC20_FACTORY =
        0x420000000000000000000000000000000000000B;

    /**
     * @notice Address of the KromaMintableERC721Factory predeploy.
     */
    address internal constant KROMA_MINTABLE_ERC721_FACTORY =
        0x420000000000000000000000000000000000000c;

    /**
     * @notice Address of the SequencerFeeWallet predeploy used after Kroma MPT hardfork.
     */
    address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;

    /**
     * @notice Address of the L1Block predeploy used after Kroma MPT hardfork.
     */
    address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;

    /**
     * @notice Address of the BaseFeeVault predeploy used after Kroma MPT hardfork.
     */
    address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;

    /**
     * @notice Address of the L1FeeVault predeploy used after Kroma MPT hardfork.
     */
    address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;
}

File 5 of 10 : Types.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

/**
 * @title Types
 * @notice Contains various types used throughout the Kroma contract system.
 */
library Types {
    /**
     * @notice CheckpointOutput represents a commitment to the state of L2 checkpoint. The timestamp
     *         is the L1 timestamp that the output root is posted. This timestamp is used to verify
     *         that the finalization period has passed since the output root was submitted.
     *
     * @custom:field submitter     Address of the output submitter.
     * @custom:field outputRoot    Hash of the L2 output.
     * @custom:field timestamp     Timestamp of the L1 block that the output root was submitted in.
     * @custom:field l2BlockNumber L2 block number that the output corresponds to.
     */
    struct CheckpointOutput {
        address submitter;
        bytes32 outputRoot;
        uint128 timestamp;
        uint128 l2BlockNumber;
    }

    /**
     * @notice Struct representing the elements that are hashed together to generate an output root
     *         which itself represents a snapshot of the L2 state.
     *
     * @custom:field version                  Version of the output root.
     * @custom:field stateRoot                Root of the state trie at the block of this output.
     * @custom:field messagePasserStorageRoot Root of the message passer storage trie.
     * @custom:field latestBlockhash          Hash of the block this output was generated from.
     * @custom:field nextBlockHash            Hash of the next block. Note that it is only included in KromaOutputV0.
     */
    struct OutputRootProof {
        bytes32 version;
        bytes32 stateRoot;
        bytes32 messagePasserStorageRoot;
        bytes32 latestBlockhash;
        bytes32 nextBlockHash;
    }

    /**
     * @notice Struct representing the elements that are hashed together to generate a public input
     *         for zkEVM proof.
     *
     * @custom:field blockHash        The hash of the block.
     * @custom:field parentHash       The hash of the previous block.
     * @custom:field timestamp        The block time.
     * @custom:field number           The block number.
     * @custom:field gasLimit         Maximum gas allowed.
     * @custom:field baseFee          The base fee per gas.
     * @custom:field transactionsRoot Root hash of the transactions.
     * @custom:field stateRoot        Root hash of the state trie.
     * @custom:field withdrawalsRoot  Root hash of the withdrawals.
     * @custom:field txHashes         Array of hash of the transaction.
     * @custom:field blobGasUsed      The total amount of blob gas consumed by the transactions within the block.
     * @custom:field excessBlobGas    A total of blob gas consumed in excess of the target, prior to the block.
     * @custom:field parentBeaconRoot Root hash of the parent beacon block.
     */
    struct PublicInput {
        bytes32 blockHash;
        bytes32 parentHash;
        uint64 timestamp;
        uint64 number;
        uint64 gasLimit;
        uint256 baseFee;
        bytes32 transactionsRoot;
        bytes32 stateRoot;
        bytes32 withdrawalsRoot;
        bytes32[] txHashes;
        uint64 blobGasUsed;
        uint64 excessBlobGas;
        bytes32 parentBeaconRoot;
    }

    /**
     * @notice Struct representing the elements that are hashed together to generate a block hash.
     *         Some of fields that are contained in PublicInput are omitted.
     *
     * @custom:field uncleHash    RLP encoded uncle hash.
     * @custom:field coinbase     RLP encoded coinbase.
     * @custom:field receiptsRoot RLP encoded receipts root.
     * @custom:field logsBloom    RLP encoded logs bloom.
     * @custom:field difficulty   RLP encoded difficulty.
     * @custom:field gasUsed      RLP encoded gas used.
     * @custom:field extraData    RLP encoded extra data.
     * @custom:field mixHash      RLP encoded mix hash.
     * @custom:field nonce        RLP encoded nonce.
     */
    struct BlockHeaderRLP {
        bytes uncleHash;
        bytes coinbase;
        bytes receiptsRoot;
        bytes logsBloom;
        bytes difficulty;
        bytes gasUsed;
        bytes extraData;
        bytes mixHash;
        bytes nonce;
    }

    /**
     * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end
     *         user (as opposed to a system deposit transaction generated by the system).
     *
     * @custom:field from        Address of the sender of the transaction.
     * @custom:field to          Address of the recipient of the transaction.
     * @custom:field isCreation  True if the transaction is a contract creation.
     * @custom:field value       Value to send to the recipient.
     * @custom:field mint        Amount of ETH to mint.
     * @custom:field gasLimit    Gas limit of the transaction.
     * @custom:field data        Data of the transaction.
     * @custom:field l1BlockHash Hash of the block the transaction was submitted in.
     * @custom:field logIndex    Index of the log in the block the transaction was submitted in.
     */
    struct UserDepositTransaction {
        address from;
        address to;
        bool isCreation;
        uint256 value;
        uint256 mint;
        uint64 gasLimit;
        bytes data;
        bytes32 l1BlockHash;
        uint64 logIndex;
    }

    /**
     * @notice Struct representing a withdrawal transaction.
     *
     * @custom:field nonce    Nonce of the withdrawal transaction
     * @custom:field sender   Address of the sender of the transaction.
     * @custom:field target   Address of the recipient of the transaction.
     * @custom:field value    Value to send to the recipient.
     * @custom:field gasLimit Gas limit of the transaction.
     * @custom:field data     Data of the transaction.
     */
    struct WithdrawalTransaction {
        uint256 nonce;
        address sender;
        address target;
        uint256 value;
        uint256 gasLimit;
        bytes data;
    }

    /**
     * @notice Struct representing a challenge.
     *
     * @custom:field turn       The current turn.
     * @custom:field timeoutAt  Timeout timestamp of the next turn.
     * @custom:field asserter   Address of the asserter.
     * @custom:field challenger Address of the challenger.
     * @custom:field segments   Array of the segment.
     * @custom:field segStart   The L2 block number of the first segment.
     * @custom:field segSize    The number of L2 blocks.
     * @custom:field l1Head     Parent L1 block hash at the challenge creation time.
     */
    struct Challenge {
        uint8 turn;
        uint64 timeoutAt;
        address asserter;
        address challenger;
        bytes32[] segments;
        uint256 segSize;
        uint256 segStart;
        bytes32 l1Head;
    }

    /**
     * @notice Struct representing a validator's bond.
     *
     * @custom:field amount    Amount of the lock.
     * @custom:field expiresAt The expiration timestamp of bond.
     */
    struct Bond {
        uint128 amount;
        uint128 expiresAt;
    }

    /**
     * @notice Struct representing multisig transaction data.
     *
     * @custom:field target   The destination address to run the transaction.
     * @custom:field executed Record whether a transaction was executed or not.
     * @custom:field value    The value passed in while executing the transaction.
     * @custom:field data     Calldata for transaction.
     */
    struct MultiSigTransaction {
        address target;
        bool executed;
        uint256 value;
        bytes data;
    }

    /**
     * @notice Struct representing multisig confirmation data.
     *
     * @custom:field confirmationCount The sum of confirmations.
     * @custom:field confirmedBy       Map data that stores whether confirmation is performed by account.
     */
    struct MultiSigConfirmation {
        uint256 confirmationCount;
        mapping(address => bool) confirmedBy;
    }

    /**
     * @notice Struct representing the data for verifying the public input of zkEVM proof.
     *
     * @custom:field srcOutputRootProof          Proof of the source output root.
     * @custom:field dstOutputRootProof          Proof of the destination output root.
     * @custom:field publicInput                 Ingredients to compute the public input used by
     *                                           zkEVM proof verification.
     * @custom:field rlps                        Pre-encoded RLPs to compute the next block hash
     *                                           of the source output root proof.
     * @custom:field l2ToL1MessagePasserBalance  Balance of the L2ToL1MessagePasser account.
     * @custom:field l2ToL1MessagePasserCodeHash Codehash of the L2ToL1MessagePasser account.
     * @custom:field merkleProof                 Merkle proof of L2ToL1MessagePasser account against the state root.
     */
    struct PublicInputProof {
        OutputRootProof srcOutputRootProof;
        OutputRootProof dstOutputRootProof;
        PublicInput publicInput;
        BlockHeaderRLP rlps;
        bytes32 l2ToL1MessagePasserBalance;
        bytes32 l2ToL1MessagePasserCodeHash;
        bytes[] merkleProof;
    }

    /**
     * @notice Struct representing zkEVM public input and proof.
     *
     * @param publicInputProof Data for verifying the public input.
     * @param proof            Halo2 proofs composed of points and scalars.
     *                         See https://zcash.github.io/halo2/design/implementation/proofs.html.
     * @param pair             Aggregated multi-opening proofs and public inputs.
     *                         (Currently only 2 public inputs)
     */
    struct ZkEvmProof {
        PublicInputProof publicInputProof;
        uint256[] proof;
        uint256[] pair;
    }

    /**
     * @notice Struct representing zkVM public input and proof.
     *
     * @param zkVmProgramVKey The verification key for the zkVM program.
     * @param publicValues    The public values concatenated.
     *                        (Currently 3 public inputs: bytes32 srcOutputRoot, bytes32 dstOutputRoot, bytes32 l1Head)
     * @param proofBytes      The proof of the program execution the SP1 zkVM encoded as bytes.
     */
    struct ZkVmProof {
        bytes32 zkVmProgramVKey;
        bytes publicValues;
        bytes proofBytes;
    }
}

File 6 of 10 : ISemver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title ISemver
/// @notice ISemver is a simple contract for ensuring that contracts are
///         versioned using semantic versioning.
interface ISemver {
    /// @notice Getter for the semantic version of the contract. This is not
    ///         meant to be used onchain but instead meant to be used by offchain
    ///         tooling.
    /// @return Semver contract version as a string.
    function version() external view returns (string memory);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

/// @title SP1 Verifier Interface
/// @author Succinct Labs
/// @notice This contract is the interface for the SP1 Verifier.
///         See https://github.com/succinctlabs/sp1-contracts/blob/main-0.8.15/contracts/src/ISP1Verifier.sol
interface ISP1Verifier {
    /// @notice Verifies a proof with given public values and vkey.
    /// @dev It is expected that the first 4 bytes of proofBytes must match the first 4 bytes of
    /// target verifier's VERIFIER_HASH.
    /// @param programVKey The verification key for the RISC-V program.
    /// @param publicValues The public values encoded as bytes.
    /// @param proofBytes The proof of the program execution the SP1 zkVM encoded as bytes.
    function verifyProof(
        bytes32 programVKey,
        bytes calldata publicValues,
        bytes calldata proofBytes
    ) external view;
}

interface ISP1VerifierWithHash is ISP1Verifier {
    /// @notice Returns the hash of the verifier.
    function VERIFIER_HASH() external pure returns (bytes32);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

/**
 * @title IZKMerkleTrie
 */
interface IZKMerkleTrie {
    /**
     * @notice Verifies a proof that a given key/value pair is present in the trie.
     *
     * @param _key    Key of the node to search for, as a hex string.
     * @param _value  Value of the node to search for, as a hex string.
     * @param _proofs Merkle trie inclusion proof for the desired node.
     * @param _root   Known root of the Merkle trie. Used to verify that the included proof is
     *                correctly constructed.
     *
     * @return Whether or not the proof is valid.
     */
    function verifyInclusionProof(
        bytes32 _key,
        bytes memory _value,
        bytes[] memory _proofs,
        bytes32 _root
    ) external view returns (bool);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { Hashing } from "./Hashing.sol";
import { Types } from "./Types.sol";
import { RLPWriter } from "./rlp/RLPWriter.sol";

/// @title Encoding
/// @notice Encoding handles Kroma's various different encoding schemes.
library Encoding {
    /// @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent
    ///         to the L2 system. Useful for searching for a deposit in the L2 system. The
    ///         transaction is prefixed with 0x7e to identify its EIP-2718 type.
    /// @param _tx           User deposit transaction to encode.
    /// @param _isKromaDepTx Whether the given transaction is a KromaDepositTx.
    /// @return RLP encoded L2 deposit transaction.
    function encodeDepositTransaction(
        Types.UserDepositTransaction memory _tx,
        bool _isKromaDepTx
    ) internal pure returns (bytes memory) {
        bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);
        bytes[] memory raw;
        if (_isKromaDepTx) {
            raw = new bytes[](7);
            raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));
            raw[1] = RLPWriter.writeAddress(_tx.from);
            raw[2] = _tx.isCreation ? RLPWriter.writeBytes("") : RLPWriter.writeAddress(_tx.to);
            raw[3] = RLPWriter.writeUint(_tx.mint);
            raw[4] = RLPWriter.writeUint(_tx.value);
            raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));
            raw[6] = RLPWriter.writeBytes(_tx.data);
        } else {
            raw = new bytes[](8);
            raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));
            raw[1] = RLPWriter.writeAddress(_tx.from);
            raw[2] = _tx.isCreation ? RLPWriter.writeBytes("") : RLPWriter.writeAddress(_tx.to);
            raw[3] = RLPWriter.writeUint(_tx.mint);
            raw[4] = RLPWriter.writeUint(_tx.value);
            raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));
            raw[6] = RLPWriter.writeBool(false);
            raw[7] = RLPWriter.writeBytes(_tx.data);
        }
        return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));
    }

    /// @notice Encodes the cross domain message based on the version that is encoded into the
    ///         message nonce.
    /// @param _nonce    Message nonce with version encoded into the first two bytes.
    /// @param _sender   Address of the sender of the message.
    /// @param _target   Address of the target of the message.
    /// @param _value    ETH value to send to the target.
    /// @param _gasLimit Gas limit to use for the message.
    /// @param _data     Data to send with the message.
    /// @return Encoded cross domain message.
    function encodeCrossDomainMessage(
        uint256 _nonce,
        address _sender,
        address _target,
        uint256 _value,
        uint256 _gasLimit,
        bytes memory _data
    ) internal pure returns (bytes memory) {
        (, uint16 version) = decodeVersionedNonce(_nonce);
        if (version == 0) {
            return encodeCrossDomainMessageV0(_nonce, _sender, _target, _value, _gasLimit, _data);
        } else {
            revert("Encoding: unknown cross domain message version");
        }
    }

    /// @notice Encodes a cross domain message based on the V0 (current) encoding.
    /// @param _nonce    Message nonce.
    /// @param _sender   Address of the sender of the message.
    /// @param _target   Address of the target of the message.
    /// @param _value    ETH value to send to the target.
    /// @param _gasLimit Gas limit to use for the message.
    /// @param _data     Data to send with the message.
    /// @return Encoded cross domain message.
    function encodeCrossDomainMessageV0(
        uint256 _nonce,
        address _sender,
        address _target,
        uint256 _value,
        uint256 _gasLimit,
        bytes memory _data
    ) internal pure returns (bytes memory) {
        return
            abi.encodeWithSignature(
                "relayMessage(uint256,address,address,uint256,uint256,bytes)",
                _nonce,
                _sender,
                _target,
                _value,
                _gasLimit,
                _data
            );
    }

    /// @notice Adds a version number into the first two bytes of a message nonce.
    /// @param _nonce   Message nonce to encode into.
    /// @param _version Version number to encode into the message nonce.
    /// @return Message nonce with version encoded into the first two bytes.
    function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {
        uint256 nonce;
        assembly {
            nonce := or(shl(240, _version), _nonce)
        }
        return nonce;
    }

    /// @notice Pulls the version out of a version-encoded nonce.
    /// @param _nonce Message nonce with version encoded into the first two bytes.
    /// @return Nonce without encoded version.
    /// @return Version of the message.
    function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {
        uint240 nonce;
        uint16 version;
        assembly {
            nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            version := shr(240, _nonce)
        }
        return (nonce, version);
    }

    /// @notice Returns an appropriately encoded call to KromaL1Block.setL1BlockValuesEcotone
    /// @param baseFeeScalar         L1 base fee Scalar
    /// @param blobBaseFeeScalar     L1 blob base fee Scalar
    /// @param sequenceNumber        Number of L2 blocks since epoch start.
    /// @param timestamp             L1 timestamp.
    /// @param number                L1 blocknumber.
    /// @param baseFee               L1 base fee.
    /// @param blobBaseFee           L1 blob base fee.
    /// @param hash                  L1 blockhash.
    /// @param batcherHash           Versioned hash to authenticate batcher by.
    /// @param validatorRewardScalar Validator reward scalar.
    function encodeSetL1BlockValuesEcotone(
        uint32 baseFeeScalar,
        uint32 blobBaseFeeScalar,
        uint64 sequenceNumber,
        uint64 timestamp,
        uint64 number,
        uint256 baseFee,
        uint256 blobBaseFee,
        bytes32 hash,
        bytes32 batcherHash,
        uint256 validatorRewardScalar
    ) internal pure returns (bytes memory) {
        bytes4 functionSignature = bytes4(keccak256("setL1BlockValuesEcotone()"));
        return
            abi.encodePacked(
                functionSignature,
                baseFeeScalar,
                blobBaseFeeScalar,
                sequenceNumber,
                timestamp,
                number,
                baseFee,
                blobBaseFee,
                hash,
                batcherHash,
                validatorRewardScalar
            );
    }

    /// @notice Returns an appropriately encoded call to L1Block.setL1BlockValuesEcotone without validatorRewardScalar.
    /// @param baseFeeScalar     L1 base fee Scalar
    /// @param blobBaseFeeScalar L1 blob base fee Scalar
    /// @param sequenceNumber    Number of L2 blocks since epoch start.
    /// @param timestamp         L1 timestamp.
    /// @param number            L1 blocknumber.
    /// @param baseFee           L1 base fee.
    /// @param blobBaseFee       L1 blob base fee.
    /// @param hash              L1 blockhash.
    /// @param batcherHash       Versioned hash to authenticate batcher by.
    function encodeSetL1BlockValuesKromaMPT(
        uint32 baseFeeScalar,
        uint32 blobBaseFeeScalar,
        uint64 sequenceNumber,
        uint64 timestamp,
        uint64 number,
        uint256 baseFee,
        uint256 blobBaseFee,
        bytes32 hash,
        bytes32 batcherHash
    ) internal pure returns (bytes memory) {
        bytes4 functionSignature = bytes4(keccak256("setL1BlockValuesEcotone()"));
        return
            abi.encodePacked(
                functionSignature,
                baseFeeScalar,
                blobBaseFeeScalar,
                sequenceNumber,
                timestamp,
                number,
                baseFee,
                blobBaseFee,
                hash,
                batcherHash
            );
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @custom:attribution https://github.com/bakaoh/solidity-rlp-encode
/// @title RLPWriter
/// @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's
///         RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor
///         modifications to improve legibility.
library RLPWriter {
    /// @notice RLP encodes a byte string.
    /// @param _in The byte string to encode.
    /// @return out_ The RLP encoded string in bytes.
    function writeBytes(bytes memory _in) internal pure returns (bytes memory out_) {
        if (_in.length == 1 && uint8(_in[0]) < 128) {
            out_ = _in;
        } else {
            out_ = abi.encodePacked(_writeLength(_in.length, 128), _in);
        }
    }

    /// @notice RLP encodes a list of RLP encoded byte byte strings.
    /// @param _in The list of RLP encoded byte strings.
    /// @return list_ The RLP encoded list of items in bytes.
    function writeList(bytes[] memory _in) internal pure returns (bytes memory list_) {
        list_ = _flatten(_in);
        list_ = abi.encodePacked(_writeLength(list_.length, 192), list_);
    }

    /// @notice RLP encodes a string.
    /// @param _in The string to encode.
    /// @return out_ The RLP encoded string in bytes.
    function writeString(string memory _in) internal pure returns (bytes memory out_) {
        out_ = writeBytes(bytes(_in));
    }

    /// @notice RLP encodes an address.
    /// @param _in The address to encode.
    /// @return out_ The RLP encoded address in bytes.
    function writeAddress(address _in) internal pure returns (bytes memory out_) {
        out_ = writeBytes(abi.encodePacked(_in));
    }

    /// @notice RLP encodes a uint.
    /// @param _in The uint256 to encode.
    /// @return out_ The RLP encoded uint256 in bytes.
    function writeUint(uint256 _in) internal pure returns (bytes memory out_) {
        out_ = writeBytes(_toBinary(_in));
    }

    /// @notice RLP encodes a bool.
    /// @param _in The bool to encode.
    /// @return out_ The RLP encoded bool in bytes.
    function writeBool(bool _in) internal pure returns (bytes memory out_) {
        out_ = new bytes(1);
        out_[0] = (_in ? bytes1(0x01) : bytes1(0x80));
    }

    /// @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.
    /// @param _len    The length of the string or the payload.
    /// @param _offset 128 if item is string, 192 if item is list.
    /// @return out_ RLP encoded bytes.
    function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory out_) {
        if (_len < 56) {
            out_ = new bytes(1);
            out_[0] = bytes1(uint8(_len) + uint8(_offset));
        } else {
            uint256 lenLen;
            uint256 i = 1;
            while (_len / i != 0) {
                lenLen++;
                i *= 256;
            }

            out_ = new bytes(lenLen + 1);
            out_[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);
            for (i = 1; i <= lenLen; i++) {
                out_[i] = bytes1(uint8((_len / (256 ** (lenLen - i))) % 256));
            }
        }
    }

    /// @notice Encode integer in big endian binary form with no leading zeroes.
    /// @param _x The integer to encode.
    /// @return out_ RLP encoded bytes.
    function _toBinary(uint256 _x) private pure returns (bytes memory out_) {
        bytes memory b = abi.encodePacked(_x);

        uint256 i = 0;
        for (; i < 32; i++) {
            if (b[i] != 0) {
                break;
            }
        }

        out_ = new bytes(32 - i);
        for (uint256 j = 0; j < out_.length; j++) {
            out_[j] = b[i++];
        }
    }

    /// @custom:attribution https://github.com/Arachnid/solidity-stringutils
    /// @notice Copies a piece of memory to another location.
    /// @param _dest Destination location.
    /// @param _src  Source location.
    /// @param _len  Length of memory to copy.
    function _memcpy(uint256 _dest, uint256 _src, uint256 _len) private pure {
        uint256 dest = _dest;
        uint256 src = _src;
        uint256 len = _len;

        for (; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        uint256 mask;
        unchecked {
            mask = 256 ** (32 - len) - 1;
        }
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }
    }

    /// @custom:attribution https://github.com/sammayo/solidity-rlp-encoder
    /// @notice Flattens a list of byte strings into one byte string.
    /// @param _list List of byte strings to flatten.
    /// @return out_ The flattened byte string.
    function _flatten(bytes[] memory _list) private pure returns (bytes memory out_) {
        if (_list.length == 0) {
            return new bytes(0);
        }

        uint256 len;
        uint256 i = 0;
        for (; i < _list.length; i++) {
            len += _list[i].length;
        }

        out_ = new bytes(len);
        uint256 flattenedPtr;
        assembly {
            flattenedPtr := add(out_, 0x20)
        }

        for (i = 0; i < _list.length; i++) {
            bytes memory item = _list[i];

            uint256 listPtr;
            assembly {
                listPtr := add(item, 0x20)
            }

            _memcpy(flattenedPtr, listPtr, item.length);
            flattenedPtr += _list[i].length;
        }
    }
}

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": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract ZKVerifier","name":"_zkVerifier","type":"address"},{"internalType":"bytes32","name":"_dummyHash","type":"bytes32"},{"internalType":"uint256","name":"_maxTxs","type":"uint256"},{"internalType":"address","name":"_zkMerkleTrie","type":"address"},{"internalType":"contract ISP1Verifier","name":"_sp1Verifier","type":"address"},{"internalType":"bytes32","name":"_zkVmProgramVKey","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BlockHashMismatched","type":"error"},{"inputs":[],"name":"BlockHashMismatchedBtwSrcAndDst","type":"error"},{"inputs":[],"name":"DstOutputMatched","type":"error"},{"inputs":[],"name":"InvalidInclusionProof","type":"error"},{"inputs":[],"name":"InvalidPublicInput","type":"error"},{"inputs":[],"name":"InvalidZkProof","type":"error"},{"inputs":[],"name":"InvalidZkVmVKey","type":"error"},{"inputs":[],"name":"SrcOutputMismatched","type":"error"},{"inputs":[],"name":"StateRootMismatched","type":"error"},{"inputs":[],"name":"dummyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTxs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sp1Verifier","outputs":[{"internalType":"contract ISP1Verifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"components":[{"internalType":"bytes32","name":"version","type":"bytes32"},{"internalType":"bytes32","name":"stateRoot","type":"bytes32"},{"internalType":"bytes32","name":"messagePasserStorageRoot","type":"bytes32"},{"internalType":"bytes32","name":"latestBlockhash","type":"bytes32"},{"internalType":"bytes32","name":"nextBlockHash","type":"bytes32"}],"internalType":"struct Types.OutputRootProof","name":"srcOutputRootProof","type":"tuple"},{"components":[{"internalType":"bytes32","name":"version","type":"bytes32"},{"internalType":"bytes32","name":"stateRoot","type":"bytes32"},{"internalType":"bytes32","name":"messagePasserStorageRoot","type":"bytes32"},{"internalType":"bytes32","name":"latestBlockhash","type":"bytes32"},{"internalType":"bytes32","name":"nextBlockHash","type":"bytes32"}],"internalType":"struct Types.OutputRootProof","name":"dstOutputRootProof","type":"tuple"},{"components":[{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"parentHash","type":"bytes32"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"uint64","name":"number","type":"uint64"},{"internalType":"uint64","name":"gasLimit","type":"uint64"},{"internalType":"uint256","name":"baseFee","type":"uint256"},{"internalType":"bytes32","name":"transactionsRoot","type":"bytes32"},{"internalType":"bytes32","name":"stateRoot","type":"bytes32"},{"internalType":"bytes32","name":"withdrawalsRoot","type":"bytes32"},{"internalType":"bytes32[]","name":"txHashes","type":"bytes32[]"},{"internalType":"uint64","name":"blobGasUsed","type":"uint64"},{"internalType":"uint64","name":"excessBlobGas","type":"uint64"},{"internalType":"bytes32","name":"parentBeaconRoot","type":"bytes32"}],"internalType":"struct Types.PublicInput","name":"publicInput","type":"tuple"},{"components":[{"internalType":"bytes","name":"uncleHash","type":"bytes"},{"internalType":"bytes","name":"coinbase","type":"bytes"},{"internalType":"bytes","name":"receiptsRoot","type":"bytes"},{"internalType":"bytes","name":"logsBloom","type":"bytes"},{"internalType":"bytes","name":"difficulty","type":"bytes"},{"internalType":"bytes","name":"gasUsed","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"},{"internalType":"bytes","name":"mixHash","type":"bytes"},{"internalType":"bytes","name":"nonce","type":"bytes"}],"internalType":"struct Types.BlockHeaderRLP","name":"rlps","type":"tuple"},{"internalType":"bytes32","name":"l2ToL1MessagePasserBalance","type":"bytes32"},{"internalType":"bytes32","name":"l2ToL1MessagePasserCodeHash","type":"bytes32"},{"internalType":"bytes[]","name":"merkleProof","type":"bytes[]"}],"internalType":"struct Types.PublicInputProof","name":"publicInputProof","type":"tuple"},{"internalType":"uint256[]","name":"proof","type":"uint256[]"},{"internalType":"uint256[]","name":"pair","type":"uint256[]"}],"internalType":"struct Types.ZkEvmProof","name":"_zkEvmProof","type":"tuple"},{"internalType":"bytes32","name":"_storedSrcOutput","type":"bytes32"},{"internalType":"bytes32","name":"_storedDstOutput","type":"bytes32"}],"name":"verifyZkEvmProof","outputs":[{"internalType":"bytes32","name":"publicInputHash_","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"zkVmProgramVKey","type":"bytes32"},{"internalType":"bytes","name":"publicValues","type":"bytes"},{"internalType":"bytes","name":"proofBytes","type":"bytes"}],"internalType":"struct Types.ZkVmProof","name":"_zkVmProof","type":"tuple"},{"internalType":"bytes32","name":"_storedSrcOutput","type":"bytes32"},{"internalType":"bytes32","name":"_storedDstOutput","type":"bytes32"},{"internalType":"bytes32","name":"_storedL1Head","type":"bytes32"}],"name":"verifyZkVmProof","outputs":[{"internalType":"bytes32","name":"publicInputHash_","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zkMerkleTrie","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zkVerifier","outputs":[{"internalType":"contract ZKVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zkVmProgramVKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]

6101406040523480156200001257600080fd5b50604051620023bf380380620023bf83398101604081905262000035916200007e565b6001600160a01b0395861660805260a09490945260c092909252831660e0529091166101005261012052620000ef565b6001600160a01b03811681146200007b57600080fd5b50565b60008060008060008060c087890312156200009857600080fd5b8651620000a58162000065565b8096505060208701519450604087015193506060870151620000c78162000065565b6080880151909350620000da8162000065565b8092505060a087015190509295509295509295565b60805160a05160c05160e051610100516101205161224a620001756000396000818160aa0152818161041f015261055f01526000818160f2015261053801526000818161018201526108530152600081816101a80152818161094b01526109b90152600081816101e10152610985015260008181610207015261033a015261224a6000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80635747274b116100765780639a7ec1361161005b5780639a7ec136146101cc5780639aea2572146101df578063d6df096d1461020557600080fd5b80635747274b14610180578063816bf26d146101a657600080fd5b8063222ce122146100a85780633955d7a1146100dd57806352a07fa3146100f057806354fd4d5014610137575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b6100ca6100eb366004611504565b61022b565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100d4565b6101736040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d491906115c8565b7f0000000000000000000000000000000000000000000000000000000000000000610112565b7f00000000000000000000000000000000000000000000000000000000000000006100ca565b6100ca6101da3660046115e2565b610419565b7f00000000000000000000000000000000000000000000000000000000000000006100ca565b7f0000000000000000000000000000000000000000000000000000000000000000610112565b6000366102388580611636565b905060808101356101008201351461027c576040517f3f126fab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102b2848461029861029336869003860186611740565b610616565b6102ad61029336879003870160a08801611740565b6106b8565b6102da60a082016102c76101408401846117b0565b6102d56101608501856117e4565b610736565b6103066102eb6101c0830183611818565b6101808401356101a085013560e086013560c08701356107fb565b610321602082013561031c6101408401846117b0565b610945565b915073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016634292dc3e61036c6020880188611818565b61037960408a018a611818565b876040518663ffffffff1660e01b815260040161039a9594939291906118d6565b602060405180830381865afa1580156103b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103db9190611910565b610411576040517fe1ac453100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600084357f000000000000000000000000000000000000000000000000000000000000000014610475576040517f2166766900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104c484846104876020890189611932565b61049691602891600891611997565b61049f916119c1565b6104ac60208a018a611932565b6104bb91605091603091611997565b6102ad916119c1565b816104d26020870187611932565b6104e191607891605891611997565b6104ea916119c1565b14610521576040517f7458ca2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166341493c607f000000000000000000000000000000000000000000000000000000000000000061058b6020890189611932565b61059860408b018b611932565b6040518663ffffffff1660e01b81526004016105b8959493929190611a28565b60006040518083038186803b1580156105d057600080fd5b505afa1580156105e4573d6000803e3d6000fd5b506105f6925050506020860186611932565b604051610604929190611a61565b60405180910390209050949350505050565b60808101516000906106785781516020808401516040808601516060870151915161065b95949192910193845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b81516020808401516040808601516060808801516080808a01518551978801989098529386019490945284015282015260a081019190915260c00161065b565b8184146106f1576040517f8b10302800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b821561073057808303610730576040517f4e15341500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b82602001358260e0013514610777576040517f4d9e774000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006101808301356107a25761079d61078f84611b09565b61079884611c81565b610a02565b6107bc565b6107bc6107ae84611b09565b6107b784611c81565b610aa6565b905080846060013514610730576040517fb033950600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600060208201528082018690526060810185905260808082018590528251808303909101815260a08201928390527f12e64a72000000000000000000000000000000000000000000000000000000009092527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906312e64a72906108c5907f42000000000000000000000000000000000000030000000000000000000000009085908c908c90899060a401611df7565b602060405180830381865afa1580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190611910565b61093c576040517ff35959c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050565b600060607f0000000000000000000000000000000000000000000000000000000000000000610978610120850185611818565b905010156109e5576109e27f00000000000000000000000000000000000000000000000000000000000000006109b2610120860186611818565b6109dd91507f0000000000000000000000000000000000000000000000000000000000000000611f1f565b610bb7565b90505b6109f8846109f285611b09565b83610c3b565b9150505b92915050565b6040805160118082526102408201909252600091829190816020015b6060815260200190600190039081610a1e579050509050610a40848483610cad565b610a6f846101000151604051602001610a5b91815260200190565b604051602081830303815290604052610f60565b81601081518110610a8257610a82611f36565b6020026020010181905250610a9681610fcb565b8051906020012091505092915050565b6040805160148082526102a08201909252600091829190816020015b6060815260200190600190039081610ac2579050509050610ae4848483610cad565b610aff846101000151604051602001610a5b91815260200190565b81601081518110610b1257610b12611f36565b6020026020010181905250610b3584610140015167ffffffffffffffff16610ff6565b81601181518110610b4857610b48611f36565b6020026020010181905250610b6b84610160015167ffffffffffffffff16610ff6565b81601281518110610b7e57610b7e611f36565b6020026020010181905250610ba4846101800151604051602001610a5b91815260200190565b81601381518110610a8257610a82611f36565b606060008267ffffffffffffffff811115610bd457610bd4611674565b604051908082528060200260200182016040528015610bfd578160200160208202803683370190505b50905060005b838110156104115784828281518110610c1e57610c1e611f36565b602090810291909101015280610c3381611f65565b915050610c03565b6000838360e001516000801b85600001518660200151876060015188604001518960a001518a608001518b6101200151518c61012001518c604051602001610c8e9c9b9a99989796959493929190611fb2565b6040516020818303038152906040528051906020012090509392505050565b610cc78360200151604051602001610a5b91815260200190565b81600081518110610cda57610cda611f36565b6020026020010181905250816000015181600181518110610cfd57610cfd611f36565b6020026020010181905250816020015181600281518110610d2057610d20611f36565b6020026020010181905250610d458360e00151604051602001610a5b91815260200190565b81600381518110610d5857610d58611f36565b6020026020010181905250610d7d8360c00151604051602001610a5b91815260200190565b81600481518110610d9057610d90611f36565b6020026020010181905250816040015181600581518110610db357610db3611f36565b6020026020010181905250816060015181600681518110610dd657610dd6611f36565b6020026020010181905250816080015181600781518110610df957610df9611f36565b6020026020010181905250610e1b836060015167ffffffffffffffff16610ff6565b81600881518110610e2e57610e2e611f36565b6020026020010181905250610e50836080015167ffffffffffffffff16610ff6565b81600981518110610e6357610e63611f36565b60200260200101819052508160a0015181600a81518110610e8657610e86611f36565b6020026020010181905250610ea8836040015167ffffffffffffffff16610ff6565b81600b81518110610ebb57610ebb611f36565b60200260200101819052508160c0015181600c81518110610ede57610ede611f36565b60200260200101819052508160e0015181600d81518110610f0157610f01611f36565b602002602001018190525081610100015181600e81518110610f2557610f25611f36565b6020026020010181905250610f3d8360a00151610ff6565b81600f81518110610f5057610f50611f36565b6020026020010181905250505050565b606081516001148015610f8d5750608082600081518110610f8357610f83611f36565b016020015160f81c105b15610f96575090565b610fa282516080611009565b82604051602001610fb492919061206b565b60405160208183030381529060405290505b919050565b6060610fd6826111fd565b9050610fe4815160c0611009565b81604051602001610fb492919061206b565b60606109fc61100483611332565b610f60565b60606038831015611087576040805160018082528183019092529060208201818036833701905050905061103d828461209a565b60f81b8160008151811061105357611053611f36565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506109fc565b600060015b61109681866120ee565b156110bc57816110a581611f65565b92506110b5905061010082612102565b905061108c565b6110c7826001612121565b67ffffffffffffffff8111156110df576110df611674565b6040519080825280601f01601f191660200182016040528015611109576020820181803683370190505b509250611116848361209a565b61112190603761209a565b60f81b8360008151811061113757611137611f36565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600190505b8181116111f55761010061117f8284611f1f565b61118b9061010061221d565b61119590876120ee565b61119f9190612229565b60f81b8382815181106111b4576111b4611f36565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806111ed81611f65565b91505061116b565b505092915050565b6060815160000361121c57505060408051600081526020810190915290565b6000805b83518110156112635783818151811061123b5761123b611f36565b6020026020010151518261124f9190612121565b91508061125b81611f65565b915050611220565b8167ffffffffffffffff81111561127c5761127c611674565b6040519080825280601f01601f1916602001820160405280156112a6576020820181803683370190505b50925060009050602083015b845182101561132a5760008583815181106112cf576112cf611f36565b6020026020010151905060006020820190506112ed8382845161148f565b8684815181106112ff576112ff611f36565b602002602001015151836113139190612121565b92505050818061132290611f65565b9250506112b2565b505050919050565b606060008260405160200161134991815260200190565b604051602081830303815290604052905060005b60208110156113b85781818151811061137857611378611f36565b01602001517fff00000000000000000000000000000000000000000000000000000000000000166000036113b857806113b081611f65565b91505061135d565b6113c3816020611f1f565b67ffffffffffffffff8111156113db576113db611674565b6040519080825280601f01601f191660200182016040528015611405576020820181803683370190505b50925060005b835181101561132a57828261141f81611f65565b93508151811061143157611431611f36565b602001015160f81c60f81b84828151811061144e5761144e611f36565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061148781611f65565b91505061140b565b8282825b602081106114cb57815183526114aa602084612121565b92506114b7602083612121565b91506114c4602082611f1f565b9050611493565b905182516020929092036101000a6000190180199091169116179052505050565b6000606082840312156114fe57600080fd5b50919050565b60008060006060848603121561151957600080fd5b833567ffffffffffffffff81111561153057600080fd5b61153c868287016114ec565b9660208601359650604090950135949350505050565b60005b8381101561156d578181015183820152602001611555565b838111156107305750506000910152565b60008151808452611596816020860160208601611552565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006115db602083018461157e565b9392505050565b600080600080608085870312156115f857600080fd5b843567ffffffffffffffff81111561160f57600080fd5b61161b878288016114ec565b97602087013597506040870135966060013595509350505050565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2183360301811261166a57600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101a0810167ffffffffffffffff811182821017156116c7576116c7611674565b60405290565b604051610120810167ffffffffffffffff811182821017156116c7576116c7611674565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561173857611738611674565b604052919050565b600060a0828403121561175257600080fd5b60405160a0810181811067ffffffffffffffff8211171561177557611775611674565b806040525082358152602083013560208201526040830135604082015260608301356060820152608083013560808201528091505092915050565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6183360301811261166a57600080fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261166a57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261184d57600080fd5b83018035915067ffffffffffffffff82111561186857600080fd5b6020019150600581901b360382131561188057600080fd5b9250929050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156118b957600080fd5b8260051b8083602087013760009401602001938452509192915050565b6060815260006118ea606083018789611887565b82810360208401526118fd818688611887565b9150508260408301529695505050505050565b60006020828403121561192257600080fd5b815180151581146115db57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261196757600080fd5b83018035915067ffffffffffffffff82111561198257600080fd5b60200191503681900382131561188057600080fd5b600080858511156119a757600080fd5b838611156119b457600080fd5b5050820193919092039150565b803560208310156109fc57600019602084900360031b1b1692915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b858152606060208201526000611a426060830186886119df565b8281036040840152611a558185876119df565b98975050505050505050565b8183823760009101908152919050565b803567ffffffffffffffff81168114610fc657600080fd5b600082601f830112611a9a57600080fd5b8135602067ffffffffffffffff821115611ab657611ab6611674565b8160051b611ac58282016116f1565b9283528481018201928281019087851115611adf57600080fd5b83870192505b84831015611afe57823582529183019190830190611ae5565b979650505050505050565b60006101a08236031215611b1c57600080fd5b611b246116a3565b8235815260208301356020820152611b3e60408401611a71565b6040820152611b4f60608401611a71565b6060820152611b6060808401611a71565b608082015260a083013560a082015260c083013560c082015260e083013560e08201526101008084013581830152506101208084013567ffffffffffffffff811115611bab57600080fd5b611bb736828701611a89565b828401525050610140611bcb818501611a71565b90820152610160611bdd848201611a71565b9082015261018092830135928101929092525090565b600082601f830112611c0457600080fd5b813567ffffffffffffffff811115611c1e57611c1e611674565b611c4f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016116f1565b818152846020838601011115611c6457600080fd5b816020850160208301376000918101602001919091529392505050565b60006101208236031215611c9457600080fd5b611c9c6116cd565b823567ffffffffffffffff80821115611cb457600080fd5b611cc036838701611bf3565b83526020850135915080821115611cd657600080fd5b611ce236838701611bf3565b60208401526040850135915080821115611cfb57600080fd5b611d0736838701611bf3565b60408401526060850135915080821115611d2057600080fd5b611d2c36838701611bf3565b60608401526080850135915080821115611d4557600080fd5b611d5136838701611bf3565b608084015260a0850135915080821115611d6a57600080fd5b611d7636838701611bf3565b60a084015260c0850135915080821115611d8f57600080fd5b611d9b36838701611bf3565b60c084015260e0850135915080821115611db457600080fd5b611dc036838701611bf3565b60e084015261010091508185013581811115611ddb57600080fd5b611de736828801611bf3565b8385015250505080915050919050565b85815260006020608081840152611e11608084018861157e565b8381036040850152858152818101600587901b820183018860005b89811015611ed7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840301845281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18c3603018112611e8d57600080fd5b8b01868101903567ffffffffffffffff811115611ea957600080fd5b803603821315611eb857600080fd5b611ec38582846119df565b958801959450505090850190600101611e2c565b5050809450505050508260608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611f3157611f31611ef0565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006000198203611f7857611f78611ef0565b5060010190565b60008151602080840160005b83811015611fa757815187529582019590820190600101611f8b565b509495945050505050565b8c81528b60208201528a604082015289606082015288608082015260007fffffffffffffffff000000000000000000000000000000000000000000000000808a60c01b1660a0840152808960c01b1660a88401528760b0840152808760c01b1660d0840152507fffff0000000000000000000000000000000000000000000000000000000000008560f01b1660d883015261205961205360da840186611f7f565b84611f7f565b9e9d5050505050505050505050505050565b6000835161207d818460208801611552565b835190830190612091818360208801611552565b01949350505050565b600060ff821660ff84168060ff038211156120b7576120b7611ef0565b019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826120fd576120fd6120bf565b500490565b600081600019048311821515161561211c5761211c611ef0565b500290565b6000821982111561213457612134611ef0565b500190565b600181815b8085111561217457816000190482111561215a5761215a611ef0565b8085161561216757918102915b93841c939080029061213e565b509250929050565b60008261218b575060016109fc565b81612198575060006109fc565b81600181146121ae57600281146121b8576121d4565b60019150506109fc565b60ff8411156121c9576121c9611ef0565b50506001821b6109fc565b5060208310610133831016604e8410600b84101617156121f7575081810a6109fc565b6122018383612139565b806000190482111561221557612215611ef0565b029392505050565b60006115db838361217c565b600082612238576122386120bf565b50069056fea164736f6c634300080f000a0000000000000000000000006deb6a630d7b486c1c08d4016aee3835a2f52fa7edf1ae3da135c124658e215a9bf53477facb442a1dcd5a92388332cb6193237f0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000339208824010425cbe73201ced4372308acd610b000000000000000000000000d2832cf1fc8ba210ffabf62db9a8781153131d160082f10b794f55a90a98566913e7639ffeca0b7fcba30bdb1b3faed9c5534b75

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80635747274b116100765780639a7ec1361161005b5780639a7ec136146101cc5780639aea2572146101df578063d6df096d1461020557600080fd5b80635747274b14610180578063816bf26d146101a657600080fd5b8063222ce122146100a85780633955d7a1146100dd57806352a07fa3146100f057806354fd4d5014610137575b600080fd5b7f0082f10b794f55a90a98566913e7639ffeca0b7fcba30bdb1b3faed9c5534b755b6040519081526020015b60405180910390f35b6100ca6100eb366004611504565b61022b565b7f000000000000000000000000d2832cf1fc8ba210ffabf62db9a8781153131d165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100d4565b6101736040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d491906115c8565b7f000000000000000000000000339208824010425cbe73201ced4372308acd610b610112565b7f00000000000000000000000000000000000000000000000000000000000000646100ca565b6100ca6101da3660046115e2565b610419565b7fedf1ae3da135c124658e215a9bf53477facb442a1dcd5a92388332cb6193237f6100ca565b7f0000000000000000000000006deb6a630d7b486c1c08d4016aee3835a2f52fa7610112565b6000366102388580611636565b905060808101356101008201351461027c576040517f3f126fab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102b2848461029861029336869003860186611740565b610616565b6102ad61029336879003870160a08801611740565b6106b8565b6102da60a082016102c76101408401846117b0565b6102d56101608501856117e4565b610736565b6103066102eb6101c0830183611818565b6101808401356101a085013560e086013560c08701356107fb565b610321602082013561031c6101408401846117b0565b610945565b915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006deb6a630d7b486c1c08d4016aee3835a2f52fa716634292dc3e61036c6020880188611818565b61037960408a018a611818565b876040518663ffffffff1660e01b815260040161039a9594939291906118d6565b602060405180830381865afa1580156103b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103db9190611910565b610411576040517fe1ac453100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600084357f0082f10b794f55a90a98566913e7639ffeca0b7fcba30bdb1b3faed9c5534b7514610475576040517f2166766900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104c484846104876020890189611932565b61049691602891600891611997565b61049f916119c1565b6104ac60208a018a611932565b6104bb91605091603091611997565b6102ad916119c1565b816104d26020870187611932565b6104e191607891605891611997565b6104ea916119c1565b14610521576040517f7458ca2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d2832cf1fc8ba210ffabf62db9a8781153131d16166341493c607f0082f10b794f55a90a98566913e7639ffeca0b7fcba30bdb1b3faed9c5534b7561058b6020890189611932565b61059860408b018b611932565b6040518663ffffffff1660e01b81526004016105b8959493929190611a28565b60006040518083038186803b1580156105d057600080fd5b505afa1580156105e4573d6000803e3d6000fd5b506105f6925050506020860186611932565b604051610604929190611a61565b60405180910390209050949350505050565b60808101516000906106785781516020808401516040808601516060870151915161065b95949192910193845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b81516020808401516040808601516060808801516080808a01518551978801989098529386019490945284015282015260a081019190915260c00161065b565b8184146106f1576040517f8b10302800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b821561073057808303610730576040517f4e15341500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b82602001358260e0013514610777576040517f4d9e774000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006101808301356107a25761079d61078f84611b09565b61079884611c81565b610a02565b6107bc565b6107bc6107ae84611b09565b6107b784611c81565b610aa6565b905080846060013514610730576040517fb033950600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600060208201528082018690526060810185905260808082018590528251808303909101815260a08201928390527f12e64a72000000000000000000000000000000000000000000000000000000009092527f000000000000000000000000339208824010425cbe73201ced4372308acd610b73ffffffffffffffffffffffffffffffffffffffff16906312e64a72906108c5907f42000000000000000000000000000000000000030000000000000000000000009085908c908c90899060a401611df7565b602060405180830381865afa1580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190611910565b61093c576040517ff35959c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050565b600060607f0000000000000000000000000000000000000000000000000000000000000064610978610120850185611818565b905010156109e5576109e27fedf1ae3da135c124658e215a9bf53477facb442a1dcd5a92388332cb6193237f6109b2610120860186611818565b6109dd91507f0000000000000000000000000000000000000000000000000000000000000064611f1f565b610bb7565b90505b6109f8846109f285611b09565b83610c3b565b9150505b92915050565b6040805160118082526102408201909252600091829190816020015b6060815260200190600190039081610a1e579050509050610a40848483610cad565b610a6f846101000151604051602001610a5b91815260200190565b604051602081830303815290604052610f60565b81601081518110610a8257610a82611f36565b6020026020010181905250610a9681610fcb565b8051906020012091505092915050565b6040805160148082526102a08201909252600091829190816020015b6060815260200190600190039081610ac2579050509050610ae4848483610cad565b610aff846101000151604051602001610a5b91815260200190565b81601081518110610b1257610b12611f36565b6020026020010181905250610b3584610140015167ffffffffffffffff16610ff6565b81601181518110610b4857610b48611f36565b6020026020010181905250610b6b84610160015167ffffffffffffffff16610ff6565b81601281518110610b7e57610b7e611f36565b6020026020010181905250610ba4846101800151604051602001610a5b91815260200190565b81601381518110610a8257610a82611f36565b606060008267ffffffffffffffff811115610bd457610bd4611674565b604051908082528060200260200182016040528015610bfd578160200160208202803683370190505b50905060005b838110156104115784828281518110610c1e57610c1e611f36565b602090810291909101015280610c3381611f65565b915050610c03565b6000838360e001516000801b85600001518660200151876060015188604001518960a001518a608001518b6101200151518c61012001518c604051602001610c8e9c9b9a99989796959493929190611fb2565b6040516020818303038152906040528051906020012090509392505050565b610cc78360200151604051602001610a5b91815260200190565b81600081518110610cda57610cda611f36565b6020026020010181905250816000015181600181518110610cfd57610cfd611f36565b6020026020010181905250816020015181600281518110610d2057610d20611f36565b6020026020010181905250610d458360e00151604051602001610a5b91815260200190565b81600381518110610d5857610d58611f36565b6020026020010181905250610d7d8360c00151604051602001610a5b91815260200190565b81600481518110610d9057610d90611f36565b6020026020010181905250816040015181600581518110610db357610db3611f36565b6020026020010181905250816060015181600681518110610dd657610dd6611f36565b6020026020010181905250816080015181600781518110610df957610df9611f36565b6020026020010181905250610e1b836060015167ffffffffffffffff16610ff6565b81600881518110610e2e57610e2e611f36565b6020026020010181905250610e50836080015167ffffffffffffffff16610ff6565b81600981518110610e6357610e63611f36565b60200260200101819052508160a0015181600a81518110610e8657610e86611f36565b6020026020010181905250610ea8836040015167ffffffffffffffff16610ff6565b81600b81518110610ebb57610ebb611f36565b60200260200101819052508160c0015181600c81518110610ede57610ede611f36565b60200260200101819052508160e0015181600d81518110610f0157610f01611f36565b602002602001018190525081610100015181600e81518110610f2557610f25611f36565b6020026020010181905250610f3d8360a00151610ff6565b81600f81518110610f5057610f50611f36565b6020026020010181905250505050565b606081516001148015610f8d5750608082600081518110610f8357610f83611f36565b016020015160f81c105b15610f96575090565b610fa282516080611009565b82604051602001610fb492919061206b565b60405160208183030381529060405290505b919050565b6060610fd6826111fd565b9050610fe4815160c0611009565b81604051602001610fb492919061206b565b60606109fc61100483611332565b610f60565b60606038831015611087576040805160018082528183019092529060208201818036833701905050905061103d828461209a565b60f81b8160008151811061105357611053611f36565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506109fc565b600060015b61109681866120ee565b156110bc57816110a581611f65565b92506110b5905061010082612102565b905061108c565b6110c7826001612121565b67ffffffffffffffff8111156110df576110df611674565b6040519080825280601f01601f191660200182016040528015611109576020820181803683370190505b509250611116848361209a565b61112190603761209a565b60f81b8360008151811061113757611137611f36565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600190505b8181116111f55761010061117f8284611f1f565b61118b9061010061221d565b61119590876120ee565b61119f9190612229565b60f81b8382815181106111b4576111b4611f36565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806111ed81611f65565b91505061116b565b505092915050565b6060815160000361121c57505060408051600081526020810190915290565b6000805b83518110156112635783818151811061123b5761123b611f36565b6020026020010151518261124f9190612121565b91508061125b81611f65565b915050611220565b8167ffffffffffffffff81111561127c5761127c611674565b6040519080825280601f01601f1916602001820160405280156112a6576020820181803683370190505b50925060009050602083015b845182101561132a5760008583815181106112cf576112cf611f36565b6020026020010151905060006020820190506112ed8382845161148f565b8684815181106112ff576112ff611f36565b602002602001015151836113139190612121565b92505050818061132290611f65565b9250506112b2565b505050919050565b606060008260405160200161134991815260200190565b604051602081830303815290604052905060005b60208110156113b85781818151811061137857611378611f36565b01602001517fff00000000000000000000000000000000000000000000000000000000000000166000036113b857806113b081611f65565b91505061135d565b6113c3816020611f1f565b67ffffffffffffffff8111156113db576113db611674565b6040519080825280601f01601f191660200182016040528015611405576020820181803683370190505b50925060005b835181101561132a57828261141f81611f65565b93508151811061143157611431611f36565b602001015160f81c60f81b84828151811061144e5761144e611f36565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061148781611f65565b91505061140b565b8282825b602081106114cb57815183526114aa602084612121565b92506114b7602083612121565b91506114c4602082611f1f565b9050611493565b905182516020929092036101000a6000190180199091169116179052505050565b6000606082840312156114fe57600080fd5b50919050565b60008060006060848603121561151957600080fd5b833567ffffffffffffffff81111561153057600080fd5b61153c868287016114ec565b9660208601359650604090950135949350505050565b60005b8381101561156d578181015183820152602001611555565b838111156107305750506000910152565b60008151808452611596816020860160208601611552565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006115db602083018461157e565b9392505050565b600080600080608085870312156115f857600080fd5b843567ffffffffffffffff81111561160f57600080fd5b61161b878288016114ec565b97602087013597506040870135966060013595509350505050565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2183360301811261166a57600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101a0810167ffffffffffffffff811182821017156116c7576116c7611674565b60405290565b604051610120810167ffffffffffffffff811182821017156116c7576116c7611674565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561173857611738611674565b604052919050565b600060a0828403121561175257600080fd5b60405160a0810181811067ffffffffffffffff8211171561177557611775611674565b806040525082358152602083013560208201526040830135604082015260608301356060820152608083013560808201528091505092915050565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6183360301811261166a57600080fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261166a57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261184d57600080fd5b83018035915067ffffffffffffffff82111561186857600080fd5b6020019150600581901b360382131561188057600080fd5b9250929050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156118b957600080fd5b8260051b8083602087013760009401602001938452509192915050565b6060815260006118ea606083018789611887565b82810360208401526118fd818688611887565b9150508260408301529695505050505050565b60006020828403121561192257600080fd5b815180151581146115db57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261196757600080fd5b83018035915067ffffffffffffffff82111561198257600080fd5b60200191503681900382131561188057600080fd5b600080858511156119a757600080fd5b838611156119b457600080fd5b5050820193919092039150565b803560208310156109fc57600019602084900360031b1b1692915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b858152606060208201526000611a426060830186886119df565b8281036040840152611a558185876119df565b98975050505050505050565b8183823760009101908152919050565b803567ffffffffffffffff81168114610fc657600080fd5b600082601f830112611a9a57600080fd5b8135602067ffffffffffffffff821115611ab657611ab6611674565b8160051b611ac58282016116f1565b9283528481018201928281019087851115611adf57600080fd5b83870192505b84831015611afe57823582529183019190830190611ae5565b979650505050505050565b60006101a08236031215611b1c57600080fd5b611b246116a3565b8235815260208301356020820152611b3e60408401611a71565b6040820152611b4f60608401611a71565b6060820152611b6060808401611a71565b608082015260a083013560a082015260c083013560c082015260e083013560e08201526101008084013581830152506101208084013567ffffffffffffffff811115611bab57600080fd5b611bb736828701611a89565b828401525050610140611bcb818501611a71565b90820152610160611bdd848201611a71565b9082015261018092830135928101929092525090565b600082601f830112611c0457600080fd5b813567ffffffffffffffff811115611c1e57611c1e611674565b611c4f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016116f1565b818152846020838601011115611c6457600080fd5b816020850160208301376000918101602001919091529392505050565b60006101208236031215611c9457600080fd5b611c9c6116cd565b823567ffffffffffffffff80821115611cb457600080fd5b611cc036838701611bf3565b83526020850135915080821115611cd657600080fd5b611ce236838701611bf3565b60208401526040850135915080821115611cfb57600080fd5b611d0736838701611bf3565b60408401526060850135915080821115611d2057600080fd5b611d2c36838701611bf3565b60608401526080850135915080821115611d4557600080fd5b611d5136838701611bf3565b608084015260a0850135915080821115611d6a57600080fd5b611d7636838701611bf3565b60a084015260c0850135915080821115611d8f57600080fd5b611d9b36838701611bf3565b60c084015260e0850135915080821115611db457600080fd5b611dc036838701611bf3565b60e084015261010091508185013581811115611ddb57600080fd5b611de736828801611bf3565b8385015250505080915050919050565b85815260006020608081840152611e11608084018861157e565b8381036040850152858152818101600587901b820183018860005b89811015611ed7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085840301845281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18c3603018112611e8d57600080fd5b8b01868101903567ffffffffffffffff811115611ea957600080fd5b803603821315611eb857600080fd5b611ec38582846119df565b958801959450505090850190600101611e2c565b5050809450505050508260608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611f3157611f31611ef0565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006000198203611f7857611f78611ef0565b5060010190565b60008151602080840160005b83811015611fa757815187529582019590820190600101611f8b565b509495945050505050565b8c81528b60208201528a604082015289606082015288608082015260007fffffffffffffffff000000000000000000000000000000000000000000000000808a60c01b1660a0840152808960c01b1660a88401528760b0840152808760c01b1660d0840152507fffff0000000000000000000000000000000000000000000000000000000000008560f01b1660d883015261205961205360da840186611f7f565b84611f7f565b9e9d5050505050505050505050505050565b6000835161207d818460208801611552565b835190830190612091818360208801611552565b01949350505050565b600060ff821660ff84168060ff038211156120b7576120b7611ef0565b019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826120fd576120fd6120bf565b500490565b600081600019048311821515161561211c5761211c611ef0565b500290565b6000821982111561213457612134611ef0565b500190565b600181815b8085111561217457816000190482111561215a5761215a611ef0565b8085161561216757918102915b93841c939080029061213e565b509250929050565b60008261218b575060016109fc565b81612198575060006109fc565b81600181146121ae57600281146121b8576121d4565b60019150506109fc565b60ff8411156121c9576121c9611ef0565b50506001821b6109fc565b5060208310610133831016604e8410600b84101617156121f7575081810a6109fc565b6122018383612139565b806000190482111561221557612215611ef0565b029392505050565b60006115db838361217c565b600082612238576122386120bf565b50069056fea164736f6c634300080f000a

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

0000000000000000000000006deb6a630d7b486c1c08d4016aee3835a2f52fa7edf1ae3da135c124658e215a9bf53477facb442a1dcd5a92388332cb6193237f0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000339208824010425cbe73201ced4372308acd610b000000000000000000000000d2832cf1fc8ba210ffabf62db9a8781153131d160082f10b794f55a90a98566913e7639ffeca0b7fcba30bdb1b3faed9c5534b75

-----Decoded View---------------
Arg [0] : _zkVerifier (address): 0x6deb6a630D7b486c1C08d4016AEe3835a2F52Fa7
Arg [1] : _dummyHash (bytes32): 0xedf1ae3da135c124658e215a9bf53477facb442a1dcd5a92388332cb6193237f
Arg [2] : _maxTxs (uint256): 100
Arg [3] : _zkMerkleTrie (address): 0x339208824010425cBE73201ceD4372308ACD610B
Arg [4] : _sp1Verifier (address): 0xd2832Cf1fC8bA210FfABF62Db9A8781153131d16
Arg [5] : _zkVmProgramVKey (bytes32): 0x0082f10b794f55a90a98566913e7639ffeca0b7fcba30bdb1b3faed9c5534b75

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000006deb6a630d7b486c1c08d4016aee3835a2f52fa7
Arg [1] : edf1ae3da135c124658e215a9bf53477facb442a1dcd5a92388332cb6193237f
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [3] : 000000000000000000000000339208824010425cbe73201ced4372308acd610b
Arg [4] : 000000000000000000000000d2832cf1fc8ba210ffabf62db9a8781153131d16
Arg [5] : 0082f10b794f55a90a98566913e7639ffeca0b7fcba30bdb1b3faed9c5534b75


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

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