{"file_path":"contracts/state-transition/verifiers/DualVerifier.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.28;\n\nimport {IVerifierV2} from \"../chain-interfaces/IVerifierV2.sol\";\nimport {IVerifier} from \"../chain-interfaces/IVerifier.sol\";\nimport {UnknownVerifierType, EmptyProofLength} from \"../../common/L1ContractErrors.sol\";\n\n/// @title Dual Verifier\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\n/// @notice This contract wraps two different verifiers (FFLONK and PLONK) and routes zk-SNARK proof verification\n/// to the correct verifier based on the provided proof type. It reuses the same interface as on the original `Verifier`\n/// contract, while abusing on of the fields (`_recursiveAggregationInput`) for proof verification type. The contract is\n/// needed for the smooth transition from PLONK based verifier to the FFLONK verifier.\ncontract DualVerifier is IVerifier {\n    /// @notice The latest FFLONK verifier contract.\n    IVerifierV2 public immutable FFLONK_VERIFIER;\n\n    /// @notice PLONK verifier contract.\n    IVerifier public immutable PLONK_VERIFIER;\n\n    /// @notice Type of verification for FFLONK verifier.\n    uint256 internal constant FFLONK_VERIFICATION_TYPE = 0;\n\n    /// @notice Type of verification for PLONK verifier.\n    uint256 internal constant PLONK_VERIFICATION_TYPE = 1;\n\n    /// @param _fflonkVerifier The address of the FFLONK verifier contract.\n    /// @param _plonkVerifier The address of the PLONK verifier contract.\n    constructor(IVerifierV2 _fflonkVerifier, IVerifier _plonkVerifier) {\n        FFLONK_VERIFIER = _fflonkVerifier;\n        PLONK_VERIFIER = _plonkVerifier;\n    }\n\n    /// @notice Routes zk-SNARK proof verification to the appropriate verifier (FFLONK or PLONK) based on the proof type.\n    /// @param _publicInputs The public inputs to the proof.\n    /// @param _proof The zk-SNARK proof itself.\n    /// @dev  The first element of the `_proof` determines the verifier type.\n    ///     - 0 indicates the FFLONK verifier should be used.\n    ///     - 1 indicates the PLONK verifier should be used.\n    /// @return Returns `true` if the proof verification succeeds, otherwise throws an error.\n    function verify(uint256[] calldata _publicInputs, uint256[] calldata _proof) public view virtual returns (bool) {\n        // Ensure the proof has a valid length (at least one element\n        // for the proof system differentiator).\n        if (_proof.length == 0) {\n            revert EmptyProofLength();\n        }\n\n        // The first element of `_proof` determines the verifier type (either FFLONK or PLONK).\n        uint256 verifierType = _proof[0];\n        if (verifierType == FFLONK_VERIFICATION_TYPE) {\n            return FFLONK_VERIFIER.verify(_publicInputs, _extractProof(_proof));\n        } else if (verifierType == PLONK_VERIFICATION_TYPE) {\n            return PLONK_VERIFIER.verify(_publicInputs, _extractProof(_proof));\n        }\n        // If the verifier type is unknown, revert with an error.\n        else {\n            revert UnknownVerifierType();\n        }\n    }\n\n    /// @inheritdoc IVerifier\n    /// @dev Used for backward compatibility with older Verifier implementation. Returns PLONK verification key hash.\n    function verificationKeyHash() external view returns (bytes32) {\n        return PLONK_VERIFIER.verificationKeyHash();\n    }\n\n    /// @notice Calculates a keccak256 hash of the runtime loaded verification keys from the selected verifier.\n    /// @return The keccak256 hash of the loaded verification keys based on the verifier.\n    function verificationKeyHash(uint256 _verifierType) external view returns (bytes32) {\n        if (_verifierType == FFLONK_VERIFICATION_TYPE) {\n            return FFLONK_VERIFIER.verificationKeyHash();\n        } else if (_verifierType == PLONK_VERIFICATION_TYPE) {\n            return PLONK_VERIFIER.verificationKeyHash();\n        }\n        // If the verifier type is unknown, revert with an error.\n        else {\n            revert UnknownVerifierType();\n        }\n    }\n\n    /// @notice Extract the proof by removing the first element (proof type differentiator).\n    /// @param _proof The proof array array.\n    /// @return result A new array with the first element removed. The first element was used as a hack for\n    /// differentiator between FFLONK and PLONK proofs.\n    function _extractProof(uint256[] calldata _proof) internal pure returns (uint256[] memory result) {\n        uint256 resultLength = _proof.length - 1;\n\n        // Allocate memory for the new array (_proof.length - 1) since the first element is omitted.\n        result = new uint256[](resultLength);\n\n        // Copy elements starting from index 1 (the second element) of the original array.\n        assembly {\n            calldatacopy(add(result, 0x20), add(_proof.offset, 0x20), mul(resultLength, 0x20))\n        }\n    }\n}\n","deployed_bytecode":"0x608060405234801561000f575f5ffd5b5060043610610064575f3560e01c80639e8945d21161004d5780639e8945d2146100e0578063b864f5a9146100f6578063ff47aa9114610119575f5ffd5b806304a28b0e1461006857806352544622146100b9575b5f5ffd5b61008f7f0000000000000000000000000daab2b7b38ab48712996e760152c569fa356dbf81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61008f7f0000000000000000000000008470d6b3fd71b5fe3906b4ea04498d18f721ede981565b6100e861012c565b6040519081526020016100b0565b61010961010436600461050e565b6101bf565b60405190151581526020016100b0565b6100e861012736600461057a565b610353565b5f7f0000000000000000000000000daab2b7b38ab48712996e760152c569fa356dbf73ffffffffffffffffffffffffffffffffffffffff16639e8945d26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610196573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101ba9190610591565b905090565b5f8181036101f9576040517f456f8f7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f83835f81811061020c5761020c6105a8565b9050602002013590505f81036102c9577f0000000000000000000000008470d6b3fd71b5fe3906b4ea04498d18f721ede973ffffffffffffffffffffffffffffffffffffffff1663b864f5a98787610264888861045d565b6040518463ffffffff1660e01b8152600401610282939291906105d5565b602060405180830381865afa15801561029d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102c1919061066b565b91505061034b565b60018103610319577f0000000000000000000000000daab2b7b38ab48712996e760152c569fa356dbf73ffffffffffffffffffffffffffffffffffffffff1663b864f5a98787610264888861045d565b6040517fc352bb7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b949350505050565b5f816103ec577f0000000000000000000000008470d6b3fd71b5fe3906b4ea04498d18f721ede973ffffffffffffffffffffffffffffffffffffffff16639e8945d26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103e69190610591565b92915050565b60018203610319577f0000000000000000000000000daab2b7b38ab48712996e760152c569fa356dbf73ffffffffffffffffffffffffffffffffffffffff16639e8945d26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c2573d5f5f3e3d5ffd5b60605f61046b600184610691565b90508067ffffffffffffffff811115610486576104866106c9565b6040519080825280602002602001820160405280156104af578160200160208202803683370190505b509150602081026020850160208401375092915050565b5f5f83601f8401126104d6575f5ffd5b50813567ffffffffffffffff8111156104ed575f5ffd5b6020830191508360208260051b8501011115610507575f5ffd5b9250929050565b5f5f5f5f60408587031215610521575f5ffd5b843567ffffffffffffffff811115610537575f5ffd5b610543878288016104c6565b909550935050602085013567ffffffffffffffff811115610562575f5ffd5b61056e878288016104c6565b95989497509550505050565b5f6020828403121561058a575f5ffd5b5035919050565b5f602082840312156105a1575f5ffd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b604081528260408201525f7f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84111561060c575f5ffd5b8360051b808660608501376060908301838103820160208086019190915285519282018390528501915f91608001905b8083101561065f578351825260208201915060208401935060018301925061063c565b50979650505050505050565b5f6020828403121561067b575f5ffd5b8151801515811461068a575f5ffd5b9392505050565b818103818111156103e6577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffdfea2646970667358221220c9c3fbf40a58745dcc87a6d164938511e8ba38af0983e355e4736752d12b825864736f6c634300081c0033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{},"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"optimizer":{"enabled":true,"runs":9999999},"outputSelection":{"*":{"":["*"],"*":["*"]}},"remappings":["@ensdomains/=node_modules/@ensdomains/","ds-test/=lib/forge-std/lib/ds-test/src/","eth-gas-reporter/=node_modules/eth-gas-reporter/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","murky/=lib/murky/src/","foundry-test/=test/foundry/","l2-contracts/=../l2-contracts/contracts/","@openzeppelin/contracts-v4/=lib/openzeppelin-contracts-v4/contracts/","@openzeppelin/contracts-upgradeable-v4/=lib/openzeppelin-contracts-upgradeable-v4/contracts/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable-v4/lib/erc4626-tests/","openzeppelin-contracts-upgradeable-v4/=lib/openzeppelin-contracts-upgradeable-v4/","openzeppelin-contracts-v4/=lib/openzeppelin-contracts-v4/","openzeppelin-contracts/=lib/murky/lib/openzeppelin-contracts/"],"viaIR":false},"optimization_runs":9999999,"sourcify_repo_url":null,"decoded_constructor_args":[["0x8470d6B3fd71B5fE3906B4ea04498d18F721eDe9",{"internalType":"contract IVerifierV2","name":"_fflonkVerifier","type":"address"}],["0x0DAAB2B7b38ab48712996E760152c569FA356DbF",{"internalType":"contract IVerifier","name":"_plonkVerifier","type":"address"}]],"compiler_version":"v0.8.28+commit.7893614a","is_verified_via_verifier_alliance":false,"verified_at":"2026-08-14T13:20:39.950701Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60c060405234801561000f575f5ffd5b5060405161080238038061080283398101604081905261002e9161005c565b6001600160a01b039182166080521660a052610094565b6001600160a01b0381168114610059575f5ffd5b50565b5f5f6040838503121561006d575f5ffd5b825161007881610045565b602084015190925061008981610045565b809150509250929050565b60805160a05161072c6100d65f395f8181606d0152818161012f015281816102d301526103f601525f818160be0152818161021e015261035b015261072c5ff3fe608060405234801561000f575f5ffd5b5060043610610064575f3560e01c80639e8945d21161004d5780639e8945d2146100e0578063b864f5a9146100f6578063ff47aa9114610119575f5ffd5b806304a28b0e1461006857806352544622146100b9575b5f5ffd5b61008f7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61008f7f000000000000000000000000000000000000000000000000000000000000000081565b6100e861012c565b6040519081526020016100b0565b61010961010436600461050e565b6101bf565b60405190151581526020016100b0565b6100e861012736600461057a565b610353565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639e8945d26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610196573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101ba9190610591565b905090565b5f8181036101f9576040517f456f8f7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f83835f81811061020c5761020c6105a8565b9050602002013590505f81036102c9577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b864f5a98787610264888861045d565b6040518463ffffffff1660e01b8152600401610282939291906105d5565b602060405180830381865afa15801561029d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102c1919061066b565b91505061034b565b60018103610319577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b864f5a98787610264888861045d565b6040517fc352bb7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b949350505050565b5f816103ec577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639e8945d26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103e69190610591565b92915050565b60018203610319577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639e8945d26040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c2573d5f5f3e3d5ffd5b60605f61046b600184610691565b90508067ffffffffffffffff811115610486576104866106c9565b6040519080825280602002602001820160405280156104af578160200160208202803683370190505b509150602081026020850160208401375092915050565b5f5f83601f8401126104d6575f5ffd5b50813567ffffffffffffffff8111156104ed575f5ffd5b6020830191508360208260051b8501011115610507575f5ffd5b9250929050565b5f5f5f5f60408587031215610521575f5ffd5b843567ffffffffffffffff811115610537575f5ffd5b610543878288016104c6565b909550935050602085013567ffffffffffffffff811115610562575f5ffd5b61056e878288016104c6565b95989497509550505050565b5f6020828403121561058a575f5ffd5b5035919050565b5f602082840312156105a1575f5ffd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b604081528260408201525f7f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84111561060c575f5ffd5b8360051b808660608501376060908301838103820160208086019190915285519282018390528501915f91608001905b8083101561065f578351825260208201915060208401935060018301925061063c565b50979650505050505050565b5f6020828403121561067b575f5ffd5b8151801515811461068a575f5ffd5b9392505050565b818103818111156103e6577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffdfea2646970667358221220c9c3fbf40a58745dcc87a6d164938511e8ba38af0983e355e4736752d12b825864736f6c634300081c00330000000000000000000000008470d6b3fd71b5fe3906b4ea04498d18f721ede90000000000000000000000000daab2b7b38ab48712996e760152c569fa356dbf","name":"DualVerifier","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":false,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"contracts/common/L1ContractErrors.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.21;\n\n// 0x5ecf2d7a\nerror AccessToFallbackDenied(address target, address invoker);\n// 0x3995f750\nerror AccessToFunctionDenied(address target, bytes4 selector, address invoker);\n// 0x6c167909\nerror OnlySelfAllowed();\n// 0x52e22c98\nerror RestrictionWasNotPresent(address restriction);\n// 0xf126e113\nerror RestrictionWasAlreadyPresent(address restriction);\n// 0x3331e9c0\nerror CallNotAllowed(bytes call);\n// 0xf6fd7071\nerror RemovingPermanentRestriction();\n// 0xfcb9b2e1\nerror UnallowedImplementation(bytes32 implementationHash);\n// 0x0dfb42bf\nerror AddressAlreadySet(address addr);\n// 0x86bb51b8\nerror AddressHasNoCode(address);\n// 0x1f73225f\nerror AddressMismatch(address expected, address supplied);\n// 0x5e85ae73\nerror AmountMustBeGreaterThanZero();\n// 0xfde974f4\nerror AssetHandlerDoesNotExist(bytes32 assetId);\n// 0x1294e9e1\nerror AssetIdMismatch(bytes32 expected, bytes32 supplied);\n// 0xfe919e28\nerror AssetIdAlreadyRegistered();\n// 0x0bfcef28\nerror AlreadyWhitelisted(address);\n// 0x04a0b7e9\nerror AssetIdNotSupported(bytes32 assetId);\n// 0x6ef9a972\nerror BaseTokenGasPriceDenominatorNotSet();\n// 0x55ad3fd3\nerror BatchHashMismatch(bytes32 expected, bytes32 actual);\n// 0x2078a6a0\nerror BatchNotExecuted(uint256 batchNumber);\n// 0xbd4455ff\nerror BatchNumberMismatch(uint256 expectedBatchNumber, uint256 providedBatchNumber);\n// 0x6cf12312\nerror BridgeHubAlreadyRegistered();\n// 0xdb538614\nerror BridgeMintNotImplemented();\n// 0xe85392f9\nerror CanOnlyProcessOneBatch();\n// 0x00c6ead2\nerror CantExecuteUnprovenBatches();\n// 0xe18cb383\nerror CantRevertExecutedBatch();\n// 0x24591d89\nerror ChainIdAlreadyExists();\n// 0x717a1656\nerror ChainIdCantBeCurrentChain();\n// 0xa179f8c9\nerror ChainIdMismatch();\n// 0x23f3c357\nerror ChainIdNotRegistered(uint256 chainId);\n// 0x8f620a06\nerror ChainIdTooBig();\n// 0xf7a01e4d\nerror DelegateCallFailed(bytes returnData);\n// 0x0a8ed92c\nerror DenominatorIsZero();\n// 0xb4f54111\nerror DeployFailed();\n// 0x138ee1a3\nerror DeployingBridgedTokenForNativeToken();\n// 0xc7c9660f\nerror DepositDoesNotExist();\n// 0xad2fa98e\nerror DepositExists();\n// 0x0e7ee319\nerror DiamondAlreadyFrozen();\n// 0xa7151b9a\nerror DiamondNotFrozen();\n// 0x7138356f\nerror EmptyAddress();\n// 0x2d4d012f\nerror EmptyAssetId();\n// 0x1c25715b\nerror EmptyBytes32();\n// 0x95b66fe9\nerror EmptyDeposit();\n// 0x627e0872\nerror ETHDepositNotSupported();\n// 0xac4a3f98\nerror FacetExists(bytes4 selector, address);\n// 0xc91cf3b1\nerror GasPerPubdataMismatch();\n// 0x6d4a7df8\nerror GenesisBatchCommitmentZero();\n// 0x7940c83f\nerror GenesisBatchHashZero();\n// 0xb4fc6835\nerror GenesisIndexStorageZero();\n// 0x3a1a8589\nerror GenesisUpgradeZero();\n// 0xd356e6ba\nerror HashedLogIsDefault();\n// 0x0b08d5be\nerror HashMismatch(bytes32 expected, bytes32 actual);\n// 0x601b6882\nerror ZKChainLimitReached();\n// 0xdd381a4c\nerror IncorrectBridgeHubAddress(address bridgehub);\n// 0x826fb11e\nerror InsufficientChainBalance();\n// 0xcbd9d2e0\nerror InvalidCaller(address);\n// 0x4fbe5dba\nerror InvalidDelay();\n// 0xc1780bd6\nerror InvalidLogSender(address sender, uint256 logKey);\n// 0xd8e9405c\nerror InvalidNumberOfBlobs(uint256 expected, uint256 numCommitments, uint256 numHashes);\n// 0x09bde339\nerror InvalidProof();\n// 0x5428eae7\nerror InvalidProtocolVersion();\n// 0x6f1cf752\nerror InvalidPubdataPricingMode();\n// 0x12ba286f\nerror InvalidSelector(bytes4 func);\n// 0x0214acb6\nerror InvalidUpgradeTxn(UpgradeTxVerifyParam);\n// 0xfb5c22e6\nerror L2TimestampTooBig();\n// 0x97e1359e\nerror L2WithdrawalMessageWrongLength(uint256 messageLen);\n// 0xe37d2c02\nerror LengthIsNotDivisibleBy32(uint256 length);\n// 0x1b6825bb\nerror LogAlreadyProcessed(uint8);\n// 0xcea34703\nerror MalformedBytecode(BytecodeError);\n// 0x9bb54c35\nerror MerkleIndexOutOfBounds();\n// 0x8e23ac1a\nerror MerklePathEmpty();\n// 0x1c500385\nerror MerklePathOutOfBounds();\n// 0x3312a450\nerror MigrationPaused();\n// 0xfa44b527\nerror MissingSystemLogs(uint256 expected, uint256 actual);\n// 0x4a094431\nerror MsgValueMismatch(uint256 expectedMsgValue, uint256 providedMsgValue);\n// 0xb385a3da\nerror MsgValueTooLow(uint256 required, uint256 provided);\n// 0x79cc2d22\nerror NoCallsProvided();\n// 0xa6fef710\nerror NoFunctionsForDiamondCut();\n// 0xcab098d8\nerror NoFundsTransferred();\n// 0xc21b1ab7\nerror NonEmptyCalldata();\n// 0x536ec84b\nerror NonEmptyMsgValue();\n// 0xd018e08e\nerror NonIncreasingTimestamp();\n// 0x0105f9c0\nerror NonSequentialBatch();\n// 0x0ac76f01\nerror NonSequentialVersion();\n// 0xdd7e3621\nerror NotInitializedReentrancyGuard();\n// 0xdf17e316\nerror NotWhitelisted(address);\n// 0xf3ed9dfa\nerror OnlyEraSupported();\n// 0x1a21feed\nerror OperationExists();\n// 0xeda2fbb1\nerror OperationMustBePending();\n// 0xe1c1ff37\nerror OperationMustBeReady();\n// 0xb926450e\nerror OriginChainIdNotFound();\n// 0x9b48e060\nerror PreviousOperationNotExecuted();\n// 0xd5a99014\nerror PriorityOperationsRollingHashMismatch();\n// 0x1a4d284a\nerror PriorityTxPubdataExceedsMaxPubDataPerBatch();\n// 0xa461f651\nerror ProtocolIdMismatch(uint256 expectedProtocolVersion, uint256 providedProtocolId);\n// 0x64f94ec2\nerror ProtocolIdNotGreater();\n// 0x959f26fb\nerror PubdataGreaterThanLimit(uint256 limit, uint256 length);\n// 0x63c36549\nerror QueueIsEmpty();\n// 0xab143c06\nerror Reentrancy();\n// 0x667d17de\nerror RemoveFunctionFacetAddressNotZero(address facet);\n// 0xa2d4b16c\nerror RemoveFunctionFacetAddressZero();\n// 0x3580370c\nerror ReplaceFunctionFacetAddressZero();\n// 0x9a67c1cb\nerror RevertedBatchNotAfterNewLastBatch();\n// 0xd3b6535b\nerror SelectorsMustAllHaveSameFreezability();\n// 0xd7a6b5e6\nerror SharedBridgeValueNotSet(SharedBridgeKey);\n// 0x856d5b77\nerror SharedBridgeNotSet();\n// 0xdf3a8fdd\nerror SlotOccupied();\n// 0xec273439\nerror CTMAlreadyRegistered();\n// 0xc630ef3c\nerror CTMNotRegistered();\n// 0xae43b424\nerror SystemLogsSizeTooBig();\n// 0x08753982\nerror TimeNotReached(uint256 expectedTimestamp, uint256 actualTimestamp);\n// 0x2d50c33b\nerror TimestampError();\n// 0x06439c6b\nerror TokenNotSupported(address token);\n// 0x23830e28\nerror TokensWithFeesNotSupported();\n// 0x76da24b9\nerror TooManyFactoryDeps();\n// 0xf0b4e88f\nerror TooMuchGas();\n// 0x00c5a6a9\nerror TransactionNotAllowed();\n// 0x4c991078\nerror TxHashMismatch();\n// 0x2e311df8\nerror TxnBodyGasLimitNotEnoughGas();\n// 0x8e4a23d6\nerror Unauthorized(address caller);\n// 0xe52478c7\nerror UndefinedDiamondCutAction();\n// 0x6aa39880\nerror UnexpectedSystemLog(uint256 logKey);\n// 0xf093c2e5\nerror UpgradeBatchNumberIsNotZero();\n// 0x084a1449\nerror UnsupportedEncodingVersion();\n// 0x47b3b145\nerror ValidateTxnNotEnoughGas();\n// 0x626ade30\nerror ValueMismatch(uint256 expected, uint256 actual);\n// 0xe1022469\nerror VerifiedBatchesExceedsCommittedBatches();\n// 0xae899454\nerror WithdrawalAlreadyFinalized();\n// 0x750b219c\nerror WithdrawFailed();\n// 0x15e8e429\nerror WrongMagicValue(uint256 expectedMagicValue, uint256 providedMagicValue);\n// 0xd92e233d\nerror ZeroAddress();\n// 0xc84885d4\nerror ZeroChainId();\n// 0x99d8fec9\nerror EmptyData();\n// 0xf3dd1b9c\nerror UnsupportedCommitBatchEncoding(uint8 version);\n// 0xf338f830\nerror UnsupportedProofBatchEncoding(uint8 version);\n// 0x14d2ed8a\nerror UnsupportedExecuteBatchEncoding(uint8 version);\n// 0xd7d93e1f\nerror IncorrectBatchBounds(\n    uint256 processFromExpected,\n    uint256 processToExpected,\n    uint256 processFromProvided,\n    uint256 processToProvided\n);\n// 0x64107968\nerror AssetHandlerNotRegistered(bytes32 assetId);\n// 0x64846fe4\nerror NotARestriction(address addr);\n// 0xfa5cd00f\nerror NotAllowed(address addr);\n// 0xccdd18d2\nerror BytecodeAlreadyPublished(bytes32 bytecodeHash);\n// 0x25d8333c\nerror CallerNotTimerAdmin();\n// 0x907f8e51\nerror DeadlineNotYetPassed();\n// 0x6eef58d1\nerror NewDeadlineNotGreaterThanCurrent();\n// 0x8b7e144a\nerror NewDeadlineExceedsMaxDeadline();\n// 0x2a5989a0\nerror AlreadyPermanentRollup();\n// 0x92daded2\nerror InvalidDAForPermanentRollup();\n// 0x7a4902ad\nerror TimerAlreadyStarted();\n\n// 0x09aa9830\nerror MerklePathLengthMismatch(uint256 pathLength, uint256 expectedLength);\n\n// 0xc33e6128\nerror MerkleNothingToProve();\n\n// 0xafbb7a4e\nerror MerkleIndexOrHeightMismatch();\n\n// 0x1b582fcf\nerror MerkleWrongIndex(uint256 index, uint256 maxNodeNumber);\n\n// 0x485cfcaa\nerror MerkleWrongLength(uint256 newLeavesLength, uint256 leafNumber);\n\n// 0xce63ce17\nerror NoCTMForAssetId(bytes32 assetId);\n// 0x02181a13\nerror SettlementLayersMustSettleOnL1();\n// 0x1850b46b\nerror TokenNotLegacy();\n// 0x1929b7de\nerror IncorrectTokenAddressFromNTV(bytes32 assetId, address tokenAddress);\n// 0x48c5fa28\nerror InvalidProofLengthForFinalNode();\n// 0xfade089a\nerror LegacyEncodingUsedForNonL1Token();\n// 0xa51fa558\nerror TokenIsLegacy();\n// 0x29963361\nerror LegacyBridgeUsesNonNativeToken();\n// 0x11832de8\nerror AssetRouterAllowanceNotZero();\n// 0xaa5f6180\nerror BurningNativeWETHNotSupported();\n// 0xb20b58ce\nerror NoLegacySharedBridge();\n// 0x8e3ce3cb\nerror TooHighDeploymentNonce();\n// 0x78d2ed02\nerror ChainAlreadyLive();\n// 0x4e98b356\nerror MigrationsNotPaused();\n// 0xf20c5c2a\nerror WrappedBaseTokenAlreadyRegistered();\n\n// 0xde4c0b96\nerror InvalidNTVBurnData();\n// 0xbe7193d4\nerror InvalidSystemLogsLength();\n// 0x8efef97a\nerror LegacyBridgeNotSet();\n// 0x767eed08\nerror LegacyMethodForNonL1Token();\n// 0xc352bb73\nerror UnknownVerifierType();\n// 0x456f8f7a\nerror EmptyProofLength();\n\nenum SharedBridgeKey {\n    PostUpgradeFirstBatch,\n    LegacyBridgeFirstBatch,\n    LegacyBridgeLastDepositBatch,\n    LegacyBridgeLastDepositTxn\n}\n\nenum BytecodeError {\n    Version,\n    NumberOfWords,\n    Length,\n    WordsMustBeOdd\n}\n\nenum UpgradeTxVerifyParam {\n    From,\n    To,\n    Paymaster,\n    Value,\n    MaxFeePerGas,\n    MaxPriorityFeePerGas,\n    Reserved0,\n    Reserved1,\n    Reserved2,\n    Reserved3,\n    Signature,\n    PaymasterInput,\n    ReservedDynamic\n}\n"},{"file_path":"contracts/state-transition/chain-interfaces/IVerifier.sol","source_code":"// SPDX-License-Identifier: MIT\n// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.\npragma solidity ^0.8.21;\n\n/// @notice Part of the configuration parameters of ZKP circuits\nstruct VerifierParams {\n    bytes32 recursionNodeLevelVkHash;\n    bytes32 recursionLeafLevelVkHash;\n    bytes32 recursionCircuitsSetVksHash;\n}\n\n/// @title The interface of the Verifier contract, responsible for the zero knowledge proof verification.\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\ninterface IVerifier {\n    /// @dev Verifies a zk-SNARK proof.\n    /// @return A boolean value indicating whether the zk-SNARK proof is valid.\n    /// Note: The function may revert execution instead of returning false in some cases.\n    function verify(uint256[] calldata _publicInputs, uint256[] calldata _proof) external view returns (bool);\n\n    /// @notice Calculates a keccak256 hash of the runtime loaded verification keys.\n    /// @return vkHash The keccak256 hash of the loaded verification keys.\n    function verificationKeyHash() external view returns (bytes32);\n}\n"},{"file_path":"contracts/state-transition/chain-interfaces/IVerifierV2.sol","source_code":"// SPDX-License-Identifier: MIT\n// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.\npragma solidity ^0.8.21;\n\n/// @title The interface of the Verifier contract, responsible for the zero knowledge proof verification.\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\ninterface IVerifierV2 {\n    /// @dev Verifies a zk-SNARK proof.\n    /// @return A boolean value indicating whether the zk-SNARK proof is valid.\n    /// Note: The function may revert execution instead of returning false in some cases.\n    function verify(uint256[] calldata _publicInputs, uint256[] calldata _proof) external view returns (bool);\n\n    /// @notice Calculates a keccak256 hash of the runtime loaded verification keys.\n    /// @return vkHash The keccak256 hash of the loaded verification keys.\n    function verificationKeyHash() external view returns (bytes32);\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"contract IVerifierV2","name":"_fflonkVerifier","type":"address"},{"internalType":"contract IVerifier","name":"_plonkVerifier","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EmptyProofLength","type":"error"},{"inputs":[],"name":"UnknownVerifierType","type":"error"},{"inputs":[],"name":"FFLONK_VERIFIER","outputs":[{"internalType":"contract IVerifierV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PLONK_VERIFIER","outputs":[{"internalType":"contract IVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"verificationKeyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_verifierType","type":"uint256"}],"name":"verificationKeyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_publicInputs","type":"uint256[]"},{"internalType":"uint256[]","name":"_proof","type":"uint256[]"}],"name":"verify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0x0000000000000000000000008470d6b3fd71b5fe3906b4ea04498d18f721ede90000000000000000000000000daab2b7b38ab48712996e760152c569fa356dbf"}