{"file_path":"src/ProtocolUpgradeHandler.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IZKsyncEra} from \"./interfaces/IZKsyncEra.sol\";\nimport {IChainTypeManager} from \"./interfaces/IChainTypeManager.sol\";\nimport {IBridgeHub} from \"./interfaces/IBridgeHub.sol\";\nimport {IPausable} from \"./interfaces/IPausable.sol\";\nimport {IChainAssetHandler} from \"./interfaces/IChainAssetHandler.sol\";\nimport {IProtocolUpgradeHandler} from \"./interfaces/IProtocolUpgradeHandler.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/// @title Protocol Upgrade Handler\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\n/// @dev The contract that holds ownership of all ZKsync contracts (L1 and L2). It is responsible\n/// for handling ZKsync protocol upgrades proposed by L2 Token Assembly and executing it.\n///\n/// The upgrade process follows these key stages:\n/// 1. Proposal: Token holders on L2 propose the protocol upgrades and send the L2 -> L1 message\n///    that this contract reads and starts the upgrade process.\n/// 2. Legal veto: During this period, the guardians can veto the upgrade **offchain**. The default legal period review\n///    takes 3 days but can be extended by guardians onchain for 7 days in total.\n/// 3. Approval: Requires approval from either the guardians or the Security Council. The Security Council can\n///    immediately move the proposal to the next stage, while guardians approval will move the proposal to the\n///    next stage only after 30 days delay after the legal veto passes. If no approval is received within the specified period, the proposal\n///    is expired.\n/// 4. Pending: A mandatory delay period before the actual execution of the upgrade, allowing for final\n///    preparations and reviews.\n/// 5. Execution: The proposed changes are executed by the authorized address in the proposal,\n///    completing the upgrade process.\n///\n/// The contract implements the state machine that represents the logic of moving upgrade from each\n/// stage by time changes and Guardians/Security Council actions.\ncontract ProtocolUpgradeHandler is IProtocolUpgradeHandler, Initializable {\n    /// @dev Duration of the standard legal veto period.\n    /// Note: this value should not exceed EXTENDED_LEGAL_VETO_PERIOD.\n    function STANDARD_LEGAL_VETO_PERIOD() internal pure virtual returns (uint256) {\n        return 3 days;\n    }\n\n    /// @dev Duration of the extended legal veto period.\n    uint256 internal constant EXTENDED_LEGAL_VETO_PERIOD = 7 days;\n\n    /// @dev The mandatory delay period before an upgrade can be executed.\n    /// This period is intended to provide a buffer after an upgrade's final approval and before its execution,\n    /// allowing for final reviews and preparations for devs and users.\n    function UPGRADE_DELAY_PERIOD() internal pure virtual returns (uint256) {\n        return 1 days;\n    }\n\n    /// @dev Time limit for an upgrade proposal to be approved by guardians or expire, and the waiting period for execution post-guardians approval.\n    /// If the Security Council approves, the upgrade can proceed immediately; otherwise,\n    /// the proposal will expire after this period if not approved, or wait this period after guardians approval.\n    uint256 internal constant UPGRADE_WAIT_OR_EXPIRE_PERIOD = 30 days;\n\n    /// @dev Duration of a soft freeze which temporarily pause protocol contract functionality.\n    /// This freeze window is needed for the Security Council to decide whether they want to\n    /// do hard freeze and protocol upgrade.\n    uint256 internal constant SOFT_FREEZE_PERIOD = 12 hours;\n\n    /// @dev Duration of a hard freeze which temporarily pause protocol contract functionality.\n    /// This freeze window is needed for the Security Council to perform emergency protocol upgrade.\n    uint256 internal constant HARD_FREEZE_PERIOD = 7 days;\n\n    /// @dev Address of the L2 Protocol Governor contract.\n    /// This address is used to interface with governance actions initiated on Layer 2,\n    /// specifically for proposing and approving protocol upgrades.\n    address public immutable L2_PROTOCOL_GOVERNOR;\n\n    /// @dev ZKsync smart contract that used to operate with L2 via asynchronous L2 <-> L1 communication.\n    IZKsyncEra public immutable ZKSYNC_ERA;\n\n    /// @dev ZKsync smart contract that is responsible for creating new ZK Chains and changing parameters in existent.\n    IChainTypeManager public immutable CHAIN_TYPE_MANAGER;\n\n    /// @dev Bridgehub smart contract that is used to operate with L2 via asynchronous L2 <-> L1 communication.\n    IBridgeHub public immutable BRIDGE_HUB;\n\n    /// @dev The nullifier contract that is used for bridging.\n    IPausable public immutable L1_NULLIFIER;\n\n    /// @dev The asset router contract that is used for bridging.\n    IPausable public immutable L1_ASSET_ROUTER;\n\n    /// @dev Vault holding L1 native ETH and ERC20 tokens bridged into the ZK chains.\n    IPausable public immutable L1_NATIVE_TOKEN_VAULT;\n\n    /// @dev Chain asset handler contract for migration pausing/unpausing.\n    IChainAssetHandler public immutable CHAIN_ASSET_HANDLER;\n\n    /// @notice The address of the Security Council.\n    address public securityCouncil;\n\n    /// @notice The address of the guardians.\n    address public guardians;\n\n    /// @notice The address of the smart contract that can execute protocol emergency upgrade.\n    address public emergencyUpgradeBoard;\n\n    /// @notice A mapping to store status of an upgrade process for each upgrade ID.\n    mapping(bytes32 upgradeId => UpgradeStatus) public upgradeStatus;\n\n    /// @notice Tracks the last freeze type within an upgrade cycle.\n    FreezeStatus public lastFreezeStatusInUpgradeCycle;\n\n    /// @notice Stores the timestamp until which the protocol remains frozen.\n    uint256 public protocolFrozenUntil;\n\n    /// @notice Initializes the contract with the Security Council address, guardians address and address of L2 voting governor.\n    /// @param _l2ProtocolGovernor The address of the L2 voting governor contract for protocol upgrades.\n    /// @param _ZKsyncEra The address of the zkSync Era chain, on top of which the `_l2ProtocolGovernor` is deployed.\n    /// @param _chainTypeManager The address of the state transition manager.\n    /// @param _bridgeHub The address of the bridgehub.\n    /// @param _l1Nullifier The address of the nullifier\n    /// @param _l1AssetRouter The address of the L1 asset router.\n    /// @param _l1NativeTokenVault The address of the L1 native token vault.\n    /// @param _chainAssetHandler The address of the L1 chain asset handler.\n    constructor(\n        address _l2ProtocolGovernor,\n        IZKsyncEra _ZKsyncEra,\n        IChainTypeManager _chainTypeManager,\n        IBridgeHub _bridgeHub,\n        IPausable _l1Nullifier,\n        IPausable _l1AssetRouter,\n        IPausable _l1NativeTokenVault,\n        IChainAssetHandler _chainAssetHandler\n    ) {\n        _disableInitializers();\n\n        // Soft configuration check for contracts that inherit this contract.\n        assert(STANDARD_LEGAL_VETO_PERIOD() <= EXTENDED_LEGAL_VETO_PERIOD);\n\n        L2_PROTOCOL_GOVERNOR = _l2ProtocolGovernor;\n        ZKSYNC_ERA = _ZKsyncEra;\n        CHAIN_TYPE_MANAGER = _chainTypeManager;\n        BRIDGE_HUB = _bridgeHub;\n        L1_NULLIFIER = _l1Nullifier;\n        L1_ASSET_ROUTER = _l1AssetRouter;\n        L1_NATIVE_TOKEN_VAULT = _l1NativeTokenVault;\n        CHAIN_ASSET_HANDLER = _chainAssetHandler;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            MODIFIERS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Checks that the message sender is contract itself.\n    modifier onlySelf() {\n        require(msg.sender == address(this), \"Only upgrade handler contract itself is allowed to call this function\");\n        _;\n    }\n\n    /// @notice Checks that the message sender is an active Security Council.\n    modifier onlySecurityCouncil() {\n        require(msg.sender == securityCouncil, \"Only Security Council is allowed to call this function\");\n        _;\n    }\n\n    /// @notice Checks that the message sender is an active guardians.\n    modifier onlyGuardians() {\n        require(msg.sender == guardians, \"Only guardians is allowed to call this function\");\n        _;\n    }\n\n    /// @notice Checks that the message sender is an active Security Council or the protocol is frozen but freeze period expired.\n    modifier onlySecurityCouncilOrProtocolFreezeExpired() {\n        require(\n            msg.sender == securityCouncil || (protocolFrozenUntil != 0 && block.timestamp > protocolFrozenUntil),\n            \"Only Security Council is allowed to call this function or the protocol should be frozen\"\n        );\n        _;\n    }\n\n    /// @notice Checks that the message sender is an Emergency Upgrade Board.\n    modifier onlyEmergencyUpgradeBoard() {\n        require(msg.sender == emergencyUpgradeBoard, \"Only Emergency Upgrade Board is allowed to call this function\");\n        _;\n    }\n\n    /// @notice Calculates the current upgrade state for the specified upgrade ID.\n    /// @param _id The unique identifier of the upgrade proposal to be approved.\n    function upgradeState(bytes32 _id) public view returns (UpgradeState) {\n        UpgradeStatus memory upg = upgradeStatus[_id];\n        // Upgrade already executed\n        if (upg.executed) {\n            return UpgradeState.Done;\n        }\n\n        // Upgrade doesn't exist\n        if (upg.creationTimestamp == 0) {\n            return UpgradeState.None;\n        }\n\n        // Legal veto period\n        uint256 legalVetoTime =\n            upg.guardiansExtendedLegalVeto ? EXTENDED_LEGAL_VETO_PERIOD : STANDARD_LEGAL_VETO_PERIOD();\n        if (block.timestamp < upg.creationTimestamp + legalVetoTime) {\n            return UpgradeState.LegalVetoPeriod;\n        }\n\n        // Security council approval case\n        if (upg.securityCouncilApprovalTimestamp != 0) {\n            uint256 readyWithSecurityCouncilTimestamp = upg.securityCouncilApprovalTimestamp + UPGRADE_DELAY_PERIOD();\n            return block.timestamp >= readyWithSecurityCouncilTimestamp\n                ? UpgradeState.Ready\n                : UpgradeState.ExecutionPending;\n        }\n\n        uint256 waitOrExpiryTimestamp = upg.creationTimestamp + legalVetoTime + UPGRADE_WAIT_OR_EXPIRE_PERIOD;\n        if (block.timestamp >= waitOrExpiryTimestamp) {\n            if (!upg.guardiansApproval) {\n                return UpgradeState.Expired;\n            }\n\n            uint256 readyWithGuardiansTimestamp = waitOrExpiryTimestamp + UPGRADE_DELAY_PERIOD();\n            return block.timestamp >= readyWithGuardiansTimestamp ? UpgradeState.Ready : UpgradeState.ExecutionPending;\n        }\n\n        return UpgradeState.Waiting;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            UPGRADE PROCESS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Initiates the upgrade process by verifying an L2 voting decision.\n    /// @dev This function decodes and validates an upgrade proposal message from L2, setting the initial state for the upgrade process.\n    /// @param _l2BatchNumber The batch number of the L2 transaction containing the upgrade proposal.\n    /// @param _l2MessageIndex The index of the message within the L2 batch.\n    /// @param _l2TxNumberInBatch The transaction number of the upgrade proposal in the L2 batch.\n    /// @param _proof Merkle proof verifying the inclusion of the upgrade message in the L2 batch.\n    /// @param _proposal The upgrade proposal details including proposed actions and the executor address.\n    function startUpgrade(\n        uint256 _l2BatchNumber,\n        uint256 _l2MessageIndex,\n        uint16 _l2TxNumberInBatch,\n        bytes32[] calldata _proof,\n        UpgradeProposal calldata _proposal\n    ) external {\n        bytes memory upgradeMessage = abi.encode(_proposal);\n        IZKsyncEra.L2Message memory l2ToL1Message = IZKsyncEra.L2Message({\n            txNumberInBatch: _l2TxNumberInBatch,\n            sender: L2_PROTOCOL_GOVERNOR,\n            data: upgradeMessage\n        });\n        bool success = ZKSYNC_ERA.proveL2MessageInclusion(_l2BatchNumber, _l2MessageIndex, l2ToL1Message, _proof);\n        require(success, \"Failed to check upgrade proposal initiation\");\n        require(_proposal.executor != emergencyUpgradeBoard, \"Emergency Upgrade Board can't execute usual upgrade\");\n\n        bytes32 id = keccak256(upgradeMessage);\n        UpgradeState upgState = upgradeState(id);\n        require(upgState == UpgradeState.None, \"Upgrade with this id already exists\");\n\n        upgradeStatus[id].creationTimestamp = uint48(block.timestamp);\n        emit UpgradeStarted(id, _proposal);\n    }\n\n    /// @notice Extends the legal veto period by the guardians.\n    /// @param _id The unique identifier of the upgrade proposal to be approved.\n    function extendLegalVeto(bytes32 _id) external onlyGuardians {\n        require(!upgradeStatus[_id].guardiansExtendedLegalVeto, \"Legal veto period is already extended\");\n        UpgradeState upgState = upgradeState(_id);\n        require(upgState == UpgradeState.LegalVetoPeriod, \"Upgrade with this id is not in the legal veto period\");\n        upgradeStatus[_id].guardiansExtendedLegalVeto = true;\n\n        emit UpgradeLegalVetoExtended(_id);\n    }\n\n    /// @notice Approves an upgrade proposal by the Security Council.\n    /// @dev Transitions the state of an upgrade proposal to 'VetoPeriod' after approval by the Security Council.\n    /// @param _id The unique identifier of the upgrade proposal to be approved.\n    function approveUpgradeSecurityCouncil(bytes32 _id) external onlySecurityCouncil {\n        UpgradeState upgState = upgradeState(_id);\n        require(\n            upgState == UpgradeState.Waiting,\n            \"Upgrade with this id is not waiting for the approval from Security Council\"\n        );\n        upgradeStatus[_id].securityCouncilApprovalTimestamp = uint48(block.timestamp);\n\n        emit UpgradeApprovedBySecurityCouncil(_id);\n    }\n\n    /// @notice Approves an upgrade proposal by the guardians.\n    /// @dev Marks the upgrade proposal identified by `_id` as approved by guardians.\n    /// @param _id The unique identifier of the upgrade proposal to approve.\n    function approveUpgradeGuardians(bytes32 _id) external onlyGuardians {\n        require(!upgradeStatus[_id].guardiansApproval, \"Upgrade is already approved by guardians\");\n\n        UpgradeState upgState = upgradeState(_id);\n        require(upgState == UpgradeState.Waiting, \"Upgrade with this id is not waiting for the approval from Guardians\");\n        upgradeStatus[_id].guardiansApproval = true;\n\n        emit UpgradeApprovedByGuardians(_id);\n    }\n\n    /// @notice Executes an upgrade proposal that has reached the 'Ready' state.\n    /// @param _proposal The upgrade proposal to be executed, containing the target calls and optionally an executor.\n    function execute(UpgradeProposal calldata _proposal) external payable {\n        bytes32 id = keccak256(abi.encode(_proposal));\n        UpgradeState upgState = upgradeState(id);\n        // 1. Checks\n        require(upgState == UpgradeState.Ready, \"Upgrade is not yet ready\");\n        require(\n            _proposal.executor == address(0) || _proposal.executor == msg.sender,\n            \"msg.sender is not authorized to perform the upgrade\"\n        );\n        // 2. Effects\n        upgradeStatus[id].executed = true;\n        // 3. Interactions\n        _execute(_proposal.calls);\n        emit UpgradeExecuted(id);\n    }\n\n    /// @notice Executes an emergency upgrade proposal initiated by the emergency upgrade board.\n    /// @param _proposal The upgrade proposal details including proposed actions and the executor address.\n    function executeEmergencyUpgrade(UpgradeProposal calldata _proposal) external payable onlyEmergencyUpgradeBoard {\n        bytes32 id = keccak256(abi.encode(_proposal));\n        UpgradeState upgState = upgradeState(id);\n        // 1. Checks\n        require(upgState == UpgradeState.None, \"Upgrade already exists\");\n        require(_proposal.executor == msg.sender, \"msg.sender is not authorized to perform the upgrade\");\n        // 2. Effects\n        upgradeStatus[id].executed = true;\n        // Clear the freeze\n        lastFreezeStatusInUpgradeCycle = FreezeStatus.None;\n        protocolFrozenUntil = 0;\n        _unfreeze();\n        // 3. Interactions\n        _execute(_proposal.calls);\n        emit Unfreeze();\n        emit EmergencyUpgradeExecuted(id);\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            HELPERS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Execute an upgrade's calls.\n    /// @param _calls The array of calls to be executed.\n    function _execute(Call[] calldata _calls) internal {\n        for (uint256 i = 0; i < _calls.length; ++i) {\n            if (_calls[i].data.length > 0) {\n                require(\n                    _calls[i].target.code.length > 0, \"Target must be a smart contract if the calldata is not empty\"\n                );\n            }\n            (bool success, bytes memory returnData) = _calls[i].target.call{value: _calls[i].value}(_calls[i].data);\n            if (!success) {\n                // Propagate an error if the call fails.\n                assembly {\n                    revert(add(returnData, 0x20), mload(returnData))\n                }\n            }\n        }\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            FREEZABILITY\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Initiates a soft protocol freeze.\n    function softFreeze() external onlySecurityCouncil {\n        require(lastFreezeStatusInUpgradeCycle == FreezeStatus.None, \"Protocol already frozen\");\n        lastFreezeStatusInUpgradeCycle = FreezeStatus.Soft;\n        protocolFrozenUntil = block.timestamp + SOFT_FREEZE_PERIOD;\n        _freeze();\n        emit SoftFreeze(protocolFrozenUntil);\n    }\n\n    /// @notice Initiates a hard protocol freeze.\n    function hardFreeze() external onlySecurityCouncil {\n        FreezeStatus freezeStatus = lastFreezeStatusInUpgradeCycle;\n        require(\n            freezeStatus == FreezeStatus.None || freezeStatus == FreezeStatus.Soft\n                || freezeStatus == FreezeStatus.AfterSoftFreeze,\n            \"Protocol can't be hard frozen\"\n        );\n        lastFreezeStatusInUpgradeCycle = FreezeStatus.Hard;\n        protocolFrozenUntil = block.timestamp + HARD_FREEZE_PERIOD;\n        _freeze();\n        emit HardFreeze(protocolFrozenUntil);\n    }\n\n    /// @dev Reinforces the freezing state of the protocol if it is already within the frozen period. This function\n    /// can be called by anyone to ensure the protocol remains in a frozen state, particularly useful if there is a need\n    /// to confirm or re-apply the freeze due to partial or incomplete application during the initial freeze.\n    function reinforceFreeze() external {\n        require(block.timestamp <= protocolFrozenUntil, \"Protocol should be already frozen\");\n        _freeze();\n        emit ReinforceFreeze();\n    }\n\n    /// @dev Reinforces the freezing state of the specific chain if the protocol is already within the frozen period.\n    /// The function is an analog of `reinforceFreeze` but only for one specific chain, needed in the\n    /// rare case where the execution could get stuck at a particular ID for some unforeseen reason.\n    function reinforceFreezeOneChain(uint256 _chainId) external {\n        require(block.timestamp <= protocolFrozenUntil, \"Protocol should be already frozen\");\n        CHAIN_TYPE_MANAGER.freezeChain(_chainId);\n        emit ReinforceFreezeOneChain(_chainId);\n    }\n\n    /// @dev Freeze all ZKsync contracts, including bridges, state transition managers and all ZK Chains.\n    function _freeze() internal {\n        uint256[] memory zkChainIds = BRIDGE_HUB.getAllZKChainChainIDs();\n        uint256 len = zkChainIds.length;\n        for (uint256 i = 0; i < len; ++i) {\n            try CHAIN_TYPE_MANAGER.freezeChain(zkChainIds[i]) {} catch {}\n        }\n\n        try BRIDGE_HUB.pause() {} catch {}\n        try L1_NULLIFIER.pause() {} catch {}\n        try L1_ASSET_ROUTER.pause() {} catch {}\n        try L1_NATIVE_TOKEN_VAULT.pause() {} catch {}\n        try CHAIN_ASSET_HANDLER.pauseMigration() {} catch {}\n    }\n\n    /// @dev Unfreezes the protocol and resumes normal operations.\n    function unfreeze() external onlySecurityCouncilOrProtocolFreezeExpired {\n        if (lastFreezeStatusInUpgradeCycle == FreezeStatus.Soft) {\n            lastFreezeStatusInUpgradeCycle = FreezeStatus.AfterSoftFreeze;\n        } else if (lastFreezeStatusInUpgradeCycle == FreezeStatus.Hard) {\n            lastFreezeStatusInUpgradeCycle = FreezeStatus.AfterHardFreeze;\n        } else {\n            revert(\"Unexpected last freeze status\");\n        }\n        protocolFrozenUntil = 0;\n        _unfreeze();\n        emit Unfreeze();\n    }\n\n    /// @dev Reinforces the unfreeze for protocol if it is not in the freeze mode. This function can be called\n    /// by anyone to ensure the protocol remains in an unfrozen state, particularly useful if there is a need\n    /// to confirm or re-apply the unfreeze due to partial or incomplete application during the initial unfreeze.\n    function reinforceUnfreeze() external {\n        require(protocolFrozenUntil == 0, \"Protocol should be already unfrozen\");\n        _unfreeze();\n        emit ReinforceUnfreeze();\n    }\n\n    /// @dev Reinforces the unfreeze for one specific chain if the protocol is not in the freeze mode.\n    /// The function is an analog of `reinforceUnfreeze` but only for one specific chain, needed in the\n    /// rare case where the execution could get stuck at a particular ID for some unforeseen reason.\n    function reinforceUnfreezeOneChain(uint256 _chainId) external {\n        require(protocolFrozenUntil == 0, \"Protocol should be already unfrozen\");\n        CHAIN_TYPE_MANAGER.unfreezeChain(_chainId);\n        emit ReinforceUnfreezeOneChain(_chainId);\n    }\n\n    /// @dev Unfreeze all ZKsync contracts, including bridges, state transition managers and all ZK Chains.\n    function _unfreeze() internal {\n        uint256[] memory zkChainIds = BRIDGE_HUB.getAllZKChainChainIDs();\n        uint256 len = zkChainIds.length;\n        for (uint256 i = 0; i < len; ++i) {\n            try CHAIN_TYPE_MANAGER.unfreezeChain(zkChainIds[i]) {} catch {}\n        }\n\n        try BRIDGE_HUB.unpause() {} catch {}\n        try L1_NULLIFIER.unpause() {} catch {}\n        try L1_ASSET_ROUTER.unpause() {} catch {}\n        try L1_NATIVE_TOKEN_VAULT.unpause() {} catch {}\n        try CHAIN_ASSET_HANDLER.unpauseMigration() {} catch {}\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            SELF UPGRADES\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Updates the address of the Security Council.\n    /// @param _newSecurityCouncil The address of the new Security Council.\n    function updateSecurityCouncil(address _newSecurityCouncil) external onlySelf {\n        emit ChangeSecurityCouncil(securityCouncil, _newSecurityCouncil);\n        securityCouncil = _newSecurityCouncil;\n    }\n\n    /// @dev Updates the address of the guardians.\n    /// @param _newGuardians The address of the guardians.\n    function updateGuardians(address _newGuardians) external onlySelf {\n        emit ChangeGuardians(guardians, _newGuardians);\n        guardians = _newGuardians;\n    }\n\n    /// @dev Updates the address of the emergency upgrade board.\n    /// @param _newEmergencyUpgradeBoard The address of the guardians.\n    function updateEmergencyUpgradeBoard(address _newEmergencyUpgradeBoard) external onlySelf {\n        emit ChangeEmergencyUpgradeBoard(emergencyUpgradeBoard, _newEmergencyUpgradeBoard);\n        emergencyUpgradeBoard = _newEmergencyUpgradeBoard;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            FALLBACK\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Contract might receive/hold ETH as part of the maintenance process.\n    receive() external payable {}\n\n    /*//////////////////////////////////////////////////////////////\n                        PROXY INITIALIZER\n    //////////////////////////////////////////////////////////////*/\n    function initialize(\n        address _securityCouncil,\n        address _guardians,\n        address _emergencyUpgradeBoard\n    ) external initializer() {\n        securityCouncil = _securityCouncil;\n        emit ChangeSecurityCouncil(address(0), _securityCouncil);\n\n        guardians = _guardians;\n        emit ChangeGuardians(address(0), _guardians);\n\n        emergencyUpgradeBoard = _emergencyUpgradeBoard;\n        emit ChangeEmergencyUpgradeBoard(address(0), _emergencyUpgradeBoard);\n    }\n}\n","deployed_bytecode":"0x6080604052600436106101de575f3560e01c806384a20db8116100fd578063d370613211610092578063e60ccaba11610062578063e60ccaba1461061a578063ea3e739b1461064d578063ec1507cb1461066c578063f12913d814610698575f80fd5b8063d37061321461058e578063d43806f9146105b4578063d6f7e8da146105e7578063dbfe3e96146105fb575f80fd5b8063b9d1f21a116100cd578063b9d1f21a1461048e578063c0c53b8b14610528578063c54dd62814610547578063cdf254301461055b575f80fd5b806384a20db8146104295780639c5392da1461043d578063a1dcb9b81461045c578063b429f41c1461046f575f80fd5b80634717bd36116101735780636a28f000116101435780636a28f000146103a45780636e4c3365146103b857806374f5d9d2146103eb5780637aedf3371461040a575f80fd5b80634717bd36146103005780635a81d4ba146103335780635d4edca714610352578063691616c514610385575f80fd5b8063293e8520116101ae578063293e852014610287578063314e6ebe146102ba578063407626b5146102ce5780634523da36146102ed575f80fd5b80630855b2e1146101e957806308ee01eb1461020a5780630ed505a21461024657806327eb6c0f14610269575f80fd5b366101e557005b5f80fd5b3480156101f4575f80fd5b5061020861020336600461241e565b6106cb565b005b348015610215575f80fd5b50600254610229906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610251575f80fd5b5061025b60055481565b60405190815260200161023d565b348015610274575f80fd5b505f54610229906001600160a01b031681565b348015610292575f80fd5b506102297f000000000000000000000000bed1eb542f9a5aa6419ff3deb921a372681111f681565b3480156102c5575f80fd5b506102086107a7565b3480156102d9575f80fd5b506102086102e836600461241e565b610896565b6102086102fb36600461244b565b61095c565b34801561030b575f80fd5b506102297f000000000000000000000000085b8b6407f150d62adb1ef926f7f304600ec71481565b34801561033e575f80fd5b50600154610229906001600160a01b031681565b34801561035d575f80fd5b506102297f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb521381565b348015610390575f80fd5b5061020861039f3660046124a0565b610b3e565b3480156103af575f80fd5b50610208610bb8565b3480156103c3575f80fd5b506102297f000000000000000000000000dd5cb8b9037357b4cd37391a073798f8aab6107681565b3480156103f6575f80fd5b5061020861040536600461241e565b610d5b565b348015610415575f80fd5b506102086104243660046124a0565b610ee3565b348015610434575f80fd5b50610208610f5d565b348015610448575f80fd5b506102086104573660046124c0565b61107c565b61020861046a36600461244b565b611348565b34801561047a575f80fd5b5061020861048936600461241e565b611492565b348015610499575f80fd5b506104ee6104a836600461241e565b60036020525f908152604090205465ffffffffffff80821691600160301b81049091169060ff600160601b8204811691600160681b8104821691600160701b9091041685565b6040805165ffffffffffff96871681529590941660208601529115159284019290925290151560608301521515608082015260a00161023d565b348015610533575f80fd5b5061020861054236600461257c565b611602565b348015610552575f80fd5b506102086117e0565b348015610566575f80fd5b506102297f0000000000000000000000008829ad80e425c646dab305381ff105169feece5681565b348015610599575f80fd5b506004546105a79060ff1681565b60405161023d91906125d0565b3480156105bf575f80fd5b506102297f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c81565b3480156105f2575f80fd5b50610208611832565b348015610606575f80fd5b506102086106153660046124a0565b611886565b348015610625575f80fd5b506102297f000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb81565b348015610658575f80fd5b5061020861066736600461241e565b6118fe565b348015610677575f80fd5b5061068b61068636600461241e565b611a28565b60405161023d91906125ea565b3480156106a3575f80fd5b506102297f00000000000000000000000032400084c286cf3e17e7b677ea9583e60a00032481565b6005544211156106f65760405162461bcd60e51b81526004016106ed906125fe565b60405180910390fd5b604051632b33745b60e21b8152600481018290527f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b03169063accdd16c906024015f604051808303815f87803b158015610755575f80fd5b505af1158015610767573d5f803e3d5ffd5b505050507fe2b6c70f0bb14be8c1be3a3875d171dd198b1f9f2d35972501b91c0fc6c1b0ce8160405161079c91815260200190565b60405180910390a150565b5f546001600160a01b031633146107d05760405162461bcd60e51b81526004016106ed9061263f565b5f6004805460ff16908111156107e8576107e86125bc565b146108355760405162461bcd60e51b815260206004820152601760248201527f50726f746f636f6c20616c72656164792066726f7a656e00000000000000000060448201526064016106ed565b6004805460ff1916600117905561084e61a8c042612695565b600555610859611bbd565b7f24f7761883b592e1cb80bcb0b5ad54822c7ed844019f3459111f131715d1ecc960055460405161088c91815260200190565b60405180910390a1565b600554156108b65760405162461bcd60e51b81526004016106ed906126ba565b6040516351d218f760e01b8152600481018290527f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b0316906351d218f7906024015f604051808303815f87803b158015610915575f80fd5b505af1158015610927573d5f803e3d5ffd5b505050507fa938747b1cf8e014275de2758fc8d441002154a94bca459b291cbbbeb0c7c89d8160405161079c91815260200190565b6002546001600160a01b031633146109dc5760405162461bcd60e51b815260206004820152603d60248201527f4f6e6c7920456d657267656e6379205570677261646520426f6172642069732060448201527f616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e00000060648201526084016106ed565b5f816040516020016109ee91906126fd565b6040516020818303038152906040528051906020012090505f610a1082611a28565b90505f816006811115610a2557610a256125bc565b14610a6b5760405162461bcd60e51b81526020600482015260166024820152755570677261646520616c72656164792065786973747360501b60448201526064016106ed565b33610a7c60408501602086016124a0565b6001600160a01b031614610aa25760405162461bcd60e51b81526004016106ed90612858565b5f828152600360205260408120805460ff60701b1916600160701b1790556004805460ff19169055600555610ad5611efe565b610ae7610ae284806128ab565b612229565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded905f90a160405182907f39f6aeadc0239b46b37917ee1c12e98f9cd3a5dea6c038efa22af67471128e51905f90a2505050565b333014610b5d5760405162461bcd60e51b81526004016106ed906128f8565b6001546040516001600160a01b038084169216907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d88905f90a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b0316331480610bdd575060055415801590610bdd575060055442115b610c755760405162461bcd60e51b815260206004820152605760248201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f77656460448201527f20746f2063616c6c20746869732066756e6374696f6e206f722074686520707260648201527f6f746f636f6c2073686f756c642062652066726f7a656e000000000000000000608482015260a4016106ed565b60016004805460ff1690811115610c8e57610c8e6125bc565b03610cad57600480546003919060ff19166001835b0217905550610d25565b60026004805460ff1690811115610cc657610cc66125bc565b03610cdd5760048054819060ff1916600182610ca3565b60405162461bcd60e51b815260206004820152601d60248201527f556e6578706563746564206c61737420667265657a652073746174757300000060448201526064016106ed565b5f600555610d31611efe565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded905f90a1565b6001546001600160a01b03163314610d855760405162461bcd60e51b81526004016106ed90612963565b5f81815260036020526040902054600160601b900460ff1615610dfb5760405162461bcd60e51b815260206004820152602860248201527f5570677261646520697320616c726561647920617070726f76656420627920676044820152677561726469616e7360c01b60648201526084016106ed565b5f610e0582611a28565b90506002816006811115610e1b57610e1b6125bc565b14610e9a5760405162461bcd60e51b815260206004820152604360248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d20477561726469606482015262616e7360e81b608482015260a4016106ed565b5f82815260036020526040808220805460ff60601b1916600160601b1790555183917f4bdba07411d36daebbfc1a5062f25d0d02c753374c8498aec76d5954c707682a91a25050565b333014610f025760405162461bcd60e51b81526004016106ed906128f8565b6002546040516001600160a01b038084169216907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d76670905f90a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b03163314610f865760405162461bcd60e51b81526004016106ed9061263f565b60045460ff165f816004811115610f9f57610f9f6125bc565b1480610fbc57506001816004811115610fba57610fba6125bc565b145b80610fd857506003816004811115610fd657610fd66125bc565b145b6110245760405162461bcd60e51b815260206004820152601d60248201527f50726f746f636f6c2063616e277420626520686172642066726f7a656e00000060448201526064016106ed565b6004805460ff1916600217905561103e62093a8042612695565b600555611049611bbd565b7f8cfb4dcbe7dce698c042e43e42e1e496194abadb41ac3756f5793a9c5a8bb3e860055460405161079c91815260200190565b5f8160405160200161108e91906126fd565b60408051601f1981840301815260608301825261ffff881683526001600160a01b037f000000000000000000000000085b8b6407f150d62adb1ef926f7f304600ec71481166020850152838301829052915163e4948f4360e01b81529093505f917f00000000000000000000000032400084c286cf3e17e7b677ea9583e60a000324169063e4948f439061112e908c908c9087908c908c906004016129e2565b602060405180830381865afa158015611149573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061116d9190612a83565b9050806111d05760405162461bcd60e51b815260206004820152602b60248201527f4661696c656420746f20636865636b20757067726164652070726f706f73616c60448201526a1034b734ba34b0ba34b7b760a91b60648201526084016106ed565b6002546001600160a01b03166111ec60408601602087016124a0565b6001600160a01b03160361125e5760405162461bcd60e51b815260206004820152603360248201527f456d657267656e6379205570677261646520426f6172642063616e2774206578604482015272656375746520757375616c207570677261646560681b60648201526084016106ed565b825160208401205f61126f82611a28565b90505f816006811115611284576112846125bc565b146112dd5760405162461bcd60e51b815260206004820152602360248201527f557067726164652077697468207468697320696420616c72656164792065786960448201526273747360e81b60648201526084016106ed565b5f8281526003602052604090819020805465ffffffffffff19164265ffffffffffff161790555182907f71a79729ed8b7db17b27c5dfe0ae24cf41d52b08c8dfc82592fc7db23010c879906113339089906126fd565b60405180910390a25050505050505050505050565b5f8160405160200161135a91906126fd565b6040516020818303038152906040528051906020012090505f61137c82611a28565b90506004816006811115611392576113926125bc565b146113df5760405162461bcd60e51b815260206004820152601860248201527f55706772616465206973206e6f7420796574207265616479000000000000000060448201526064016106ed565b5f6113f060408501602086016124a0565b6001600160a01b0316148061141c57503361141160408501602086016124a0565b6001600160a01b0316145b6114385760405162461bcd60e51b81526004016106ed90612858565b5f828152600360205260409020805460ff60701b1916600160701b179055611463610ae284806128ab565b60405182907ff6224a998aea3de231cf75375faf8c3711379d54bb84c92ef9d9779dabd383a9905f90a2505050565b6001546001600160a01b031633146114bc5760405162461bcd60e51b81526004016106ed90612963565b5f81815260036020526040902054600160681b900460ff161561152f5760405162461bcd60e51b815260206004820152602560248201527f4c6567616c207665746f20706572696f6420697320616c726561647920657874604482015264195b99195960da1b60648201526084016106ed565b5f61153982611a28565b9050600181600681111561154f5761154f6125bc565b146115b95760405162461bcd60e51b815260206004820152603460248201527f5570677261646520776974682074686973206964206973206e6f7420696e20746044820152731a19481b1959d85b081d995d1bc81c195c9a5bd960621b60648201526084016106ed565b5f82815260036020526040808220805460ff60681b1916600160681b1790555183917f6679375a2761fa72f4163ccf9a92a514bfd3adff8eb1f2f17256f25834dc46ca91a25050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f811580156116475750825b90505f8267ffffffffffffffff1660011480156116635750303b155b905081158015611671575080155b1561168f5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156116b957845460ff60401b1916600160401b1785555b5f80546001600160a01b0319166001600160a01b038a1690811782556040519091907fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f5951908290a3600180546001600160a01b0319166001600160a01b0389169081179091556040515f907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d88908290a3600280546001600160a01b0319166001600160a01b0388169081179091556040515f907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d76670908290a383156117d657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b600554156118005760405162461bcd60e51b81526004016106ed906126ba565b611808611efe565b6040517fea592eda90ea1daf1d7577bddc51f4f8425ec0332f0dd8b58aa08f8a2d1da621905f90a1565b6005544211156118545760405162461bcd60e51b81526004016106ed906125fe565b61185c611bbd565b6040517fbe5088092f32032505342f55f3393029ab55bd4dfcc2edad138d715f485ace6e905f90a1565b3330146118a55760405162461bcd60e51b81526004016106ed906128f8565b5f80546040516001600160a01b03808516939216917fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f595191a35f80546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b031633146119275760405162461bcd60e51b81526004016106ed9061263f565b5f61193182611a28565b90506002816006811115611947576119476125bc565b146119cd5760405162461bcd60e51b815260206004820152604a60248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d205365637572696064820152691d1e4810dbdd5b98da5b60b21b608482015260a4016106ed565b5f8281526003602052604080822080546bffffffffffff0000000000001916600160301b4265ffffffffffff16021790555183917f4ea0d7cd48461eaf68f428942cdfb19039bd43dc723fa8875c65bec57d911ac491a25050565b5f818152600360209081526040808320815160a081018352905465ffffffffffff8082168352600160301b8204169382019390935260ff600160601b84048116151592820192909252600160681b8304821615156060820152600160701b909204161580156080830152611a9f5750600692915050565b805165ffffffffffff165f03611ab757505f92915050565b5f8160600151611aca576203f480611acf565b62093a805b8251909150611ae790829065ffffffffffff16612695565b421015611af8575060019392505050565b602082015165ffffffffffff1615611b43575f62015180836020015165ffffffffffff16611b269190612695565b905080421015611b37576003611b3a565b60045b95945050505050565b5f62278d0082845f015165ffffffffffff16611b5f9190612695565b611b699190612695565b9050804210611bb2578260400151611b8657506005949350505050565b5f611b946201518083612695565b905080421015611ba5576003611ba8565b60045b9695505050505050565b506002949350505050565b5f7f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b03166368b8d3316040518163ffffffff1660e01b81526004015f60405180830381865afa158015611c19573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611c409190810190612ab6565b80519091505f5b81811015611ce7577f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b031663accdd16c848381518110611c9057611c90612b6f565b60200260200101516040518263ffffffff1660e01b8152600401611cb691815260200190565b5f604051808303815f87803b158015611ccd575f80fd5b505af1925050508015611cde575060015b50600101611c47565b507f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b0316638456cb596040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611d40575f80fd5b505af1925050508015611d51575060015b507f000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb6001600160a01b0316638456cb596040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611daa575f80fd5b505af1925050508015611dbb575060015b507f0000000000000000000000008829ad80e425c646dab305381ff105169feece566001600160a01b0316638456cb596040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611e14575f80fd5b505af1925050508015611e25575060015b507f000000000000000000000000bed1eb542f9a5aa6419ff3deb921a372681111f66001600160a01b0316638456cb596040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611e7e575f80fd5b505af1925050508015611e8f575060015b507f000000000000000000000000dd5cb8b9037357b4cd37391a073798f8aab610766001600160a01b031663ac700e636040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611ee8575f80fd5b505af1925050508015611ef9575060015b505050565b5f7f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b03166368b8d3316040518163ffffffff1660e01b81526004015f60405180830381865afa158015611f5a573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611f819190810190612ab6565b80519091505f5b81811015612028577f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b03166351d218f7848381518110611fd157611fd1612b6f565b60200260200101516040518263ffffffff1660e01b8152600401611ff791815260200190565b5f604051808303815f87803b15801561200e575f80fd5b505af192505050801561201f575060015b50600101611f88565b507f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b0316633f4ba83a6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015612081575f80fd5b505af1925050508015612092575060015b507f000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb6001600160a01b0316633f4ba83a6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156120eb575f80fd5b505af19250505080156120fc575060015b507f0000000000000000000000008829ad80e425c646dab305381ff105169feece566001600160a01b0316633f4ba83a6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015612155575f80fd5b505af1925050508015612166575060015b507f000000000000000000000000bed1eb542f9a5aa6419ff3deb921a372681111f66001600160a01b0316633f4ba83a6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156121bf575f80fd5b505af19250505080156121d0575060015b507f000000000000000000000000dd5cb8b9037357b4cd37391a073798f8aab610766001600160a01b031663f7c7eb926040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611ee8575f80fd5b5f5b81811015611ef9575f83838381811061224657612246612b6f565b90506020028101906122589190612b83565b612266906040810190612ba1565b9050111561231e575f83838381811061228157612281612b6f565b90506020028101906122939190612b83565b6122a19060208101906124a0565b6001600160a01b03163b1161231e5760405162461bcd60e51b815260206004820152603c60248201527f546172676574206d757374206265206120736d61727420636f6e74726163742060448201527f6966207468652063616c6c64617461206973206e6f7420656d7074790000000060648201526084016106ed565b5f8084848481811061233257612332612b6f565b90506020028101906123449190612b83565b6123529060208101906124a0565b6001600160a01b031685858581811061236d5761236d612b6f565b905060200281019061237f9190612b83565b6020013586868681811061239557612395612b6f565b90506020028101906123a79190612b83565b6123b5906040810190612ba1565b6040516123c3929190612be4565b5f6040518083038185875af1925050503d805f81146123fd576040519150601f19603f3d011682016040523d82523d5f602084013e612402565b606091505b50915091508161241457805160208201fd5b505060010161222b565b5f6020828403121561242e575f80fd5b5035919050565b5f60608284031215612445575f80fd5b50919050565b5f6020828403121561245b575f80fd5b813567ffffffffffffffff811115612471575f80fd5b61247d84828501612435565b949350505050565b80356001600160a01b038116811461249b575f80fd5b919050565b5f602082840312156124b0575f80fd5b6124b982612485565b9392505050565b5f805f805f8060a087890312156124d5575f80fd5b8635955060208701359450604087013561ffff811681146124f4575f80fd5b9350606087013567ffffffffffffffff80821115612510575f80fd5b818901915089601f830112612523575f80fd5b813581811115612531575f80fd5b8a60208260051b8501011115612545575f80fd5b602083019550809450506080890135915080821115612562575f80fd5b5061256f89828a01612435565b9150509295509295509295565b5f805f6060848603121561258e575f80fd5b61259784612485565b92506125a560208501612485565b91506125b360408501612485565b90509250925092565b634e487b7160e01b5f52602160045260245ffd5b60208101600583106125e4576125e46125bc565b91905290565b60208101600783106125e4576125e46125bc565b60208082526021908201527f50726f746f636f6c2073686f756c6420626520616c72656164792066726f7a656040820152603760f91b606082015260800190565b60208082526036908201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f776564604082015275103a379031b0b636103a3434b990333ab731ba34b7b760511b606082015260800190565b808201808211156126b457634e487b7160e01b5f52601160045260245ffd5b92915050565b60208082526023908201527f50726f746f636f6c2073686f756c6420626520616c726561647920756e66726f6040820152623d32b760e91b606082015260800190565b5f602080835260808084018535601e1987360301811261271b575f80fd5b8601803584820167ffffffffffffffff80831115612737575f80fd5b8260051b803603831315612749575f80fd5b60608a890181905295849052890160a0908101955f918b0136879003607e19015b8684101561281e578c8903609f190182528535818112612788575f80fd5b88016001600160a01b0361279d8d8301612485565b168a526040808201358d8c015284820135603e198336030181126127bf575f80fd5b90910181810191908d0135878111156127d6575f80fd5b8036038313156127e4575f80fd5b85828d015280868d015280838e8e01375f8c82018e0152601f01601f1916909a018b01995050948a019460019390930192908a019061276a565b5050505050505050612831838701612485565b6001600160a01b038116604087015292506040860135606086015280935050505092915050565b60208082526033908201527f6d73672e73656e646572206973206e6f7420617574686f72697a656420746f20604082015272706572666f726d20746865207570677261646560681b606082015260800190565b5f808335601e198436030181126128c0575f80fd5b83018035915067ffffffffffffffff8211156128da575f80fd5b6020019150600581901b36038213156128f1575f80fd5b9250929050565b60208082526045908201527f4f6e6c7920757067726164652068616e646c657220636f6e747261637420697460408201527f73656c6620697320616c6c6f77656420746f2063616c6c20746869732066756e60608201526431ba34b7b760d91b608082015260a00190565b6020808252602f908201527f4f6e6c7920677561726469616e7320697320616c6c6f77656420746f2063616c60408201526e36103a3434b990333ab731ba34b7b760891b606082015260800190565b8183525f6001600160fb1b038311156129c9575f80fd5b8260051b80836020870137939093016020019392505050565b8581525f60208660208401526080604084015261ffff865116608084015260018060a01b0360208701511660a08401526040860151606060c085015280518060e08601525f5b81811015612a455782810184015186820161010001528301612a28565b5061010092505f838287010152601f19601f820116850191505081848203016060850152612a7682820186886129b2565b9998505050505050505050565b5f60208284031215612a93575f80fd5b815180151581146124b9575f80fd5b634e487b7160e01b5f52604160045260245ffd5b5f6020808385031215612ac7575f80fd5b825167ffffffffffffffff80821115612ade575f80fd5b818501915085601f830112612af1575f80fd5b815181811115612b0357612b03612aa2565b8060051b604051601f19603f83011681018181108582111715612b2857612b28612aa2565b604052918252848201925083810185019188831115612b45575f80fd5b938501935b82851015612b6357845184529385019392850192612b4a565b98975050505050505050565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112612b97575f80fd5b9190910192915050565b5f808335601e19843603018112612bb6575f80fd5b83018035915067ffffffffffffffff821115612bd0575f80fd5b6020019150368190038213156128f1575f80fd5b818382375f910190815291905056fea2646970667358221220aadc6bea6f812101237dfeae34d5ba93c3bd57e843564d12d38526b32c92244d64736f6c63430008180033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":200},"remappings":[":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",":ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",":forge-std/=lib/forge-std/src/",":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",":openzeppelin-contracts/=lib/openzeppelin-contracts/"]},"optimization_runs":200,"sourcify_repo_url":"https://repo.sourcify.dev/contracts/full_match/1/0x36625Bd3dDB469377C6e9893712158cA3c0cC14B/","decoded_constructor_args":[["0x085b8B6407f150D62adB1EF926F7f304600ec714",{"internalType":"address","name":"_l2ProtocolGovernor","type":"address"}],["0x32400084C286CF3E17e7B677ea9583e60a000324",{"internalType":"contract IZKsyncEra","name":"_ZKsyncEra","type":"address"}],["0xc2eE6b6af7d616f6e27ce7F4A451Aedc2b0F5f5C",{"internalType":"contract IChainTypeManager","name":"_chainTypeManager","type":"address"}],["0x303a465B659cBB0ab36eE643eA362c509EEb5213",{"internalType":"contract IBridgeHub","name":"_bridgeHub","type":"address"}],["0xD7f9f54194C633F36CCD5F3da84ad4a1c38cB2cB",{"internalType":"contract IPausable","name":"_l1Nullifier","type":"address"}],["0x8829AD80E425C646DAB305381ff105169FeEcE56",{"internalType":"contract IPausable","name":"_l1AssetRouter","type":"address"}],["0xbeD1EB542f9a5aA6419Ff3deb921A372681111f6",{"internalType":"contract IPausable","name":"_l1NativeTokenVault","type":"address"}],["0xDd5CB8B9037357B4cD37391A073798f8aaB61076",{"internalType":"contract IChainAssetHandler","name":"_chainAssetHandler","type":"address"}]],"compiler_version":"0.8.24+commit.e11b9ed9","is_verified_via_verifier_alliance":false,"verified_at":"2026-02-13T09:33:39.949894Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x61018060405234801562000011575f80fd5b5060405162002f0338038062002f03833981016040819052620000349162000144565b6200003e6200007b565b6001600160a01b0397881660805295871660a05293861660c05291851660e052841661010052831661012052821661014052166101605262000200565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000cc5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146200012c5780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6001600160a01b03811681146200012c575f80fd5b5f805f805f805f80610100898b0312156200015d575f80fd5b88516200016a816200012f565b60208a01519098506200017d816200012f565b60408a015190975062000190816200012f565b60608a0151909650620001a3816200012f565b60808a0151909550620001b6816200012f565b60a08a0151909450620001c9816200012f565b60c08a0151909350620001dc816200012f565b60e08a0151909250620001ef816200012f565b809150509295985092959890939650565b60805160a05160c05160e05161010051610120516101405161016051612c29620002da5f395f81816103c901528181611e9201526121d301525f818161029801528181611e28015261216901525f818161056c01528181611dbe01526120ff01525f818161062b01528181611d54015261209501525f818161036301528181611bc001528181611cea01528181611f01015261202b01525f81816105c50152818161070c015281816108cc01528181611c510152611f9201525f81816106a901526110f101525f818161031101526110b20152612c295ff3fe6080604052600436106101de575f3560e01c806384a20db8116100fd578063d370613211610092578063e60ccaba11610062578063e60ccaba1461061a578063ea3e739b1461064d578063ec1507cb1461066c578063f12913d814610698575f80fd5b8063d37061321461058e578063d43806f9146105b4578063d6f7e8da146105e7578063dbfe3e96146105fb575f80fd5b8063b9d1f21a116100cd578063b9d1f21a1461048e578063c0c53b8b14610528578063c54dd62814610547578063cdf254301461055b575f80fd5b806384a20db8146104295780639c5392da1461043d578063a1dcb9b81461045c578063b429f41c1461046f575f80fd5b80634717bd36116101735780636a28f000116101435780636a28f000146103a45780636e4c3365146103b857806374f5d9d2146103eb5780637aedf3371461040a575f80fd5b80634717bd36146103005780635a81d4ba146103335780635d4edca714610352578063691616c514610385575f80fd5b8063293e8520116101ae578063293e852014610287578063314e6ebe146102ba578063407626b5146102ce5780634523da36146102ed575f80fd5b80630855b2e1146101e957806308ee01eb1461020a5780630ed505a21461024657806327eb6c0f14610269575f80fd5b366101e557005b5f80fd5b3480156101f4575f80fd5b5061020861020336600461241e565b6106cb565b005b348015610215575f80fd5b50600254610229906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610251575f80fd5b5061025b60055481565b60405190815260200161023d565b348015610274575f80fd5b505f54610229906001600160a01b031681565b348015610292575f80fd5b506102297f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c5575f80fd5b506102086107a7565b3480156102d9575f80fd5b506102086102e836600461241e565b610896565b6102086102fb36600461244b565b61095c565b34801561030b575f80fd5b506102297f000000000000000000000000000000000000000000000000000000000000000081565b34801561033e575f80fd5b50600154610229906001600160a01b031681565b34801561035d575f80fd5b506102297f000000000000000000000000000000000000000000000000000000000000000081565b348015610390575f80fd5b5061020861039f3660046124a0565b610b3e565b3480156103af575f80fd5b50610208610bb8565b3480156103c3575f80fd5b506102297f000000000000000000000000000000000000000000000000000000000000000081565b3480156103f6575f80fd5b5061020861040536600461241e565b610d5b565b348015610415575f80fd5b506102086104243660046124a0565b610ee3565b348015610434575f80fd5b50610208610f5d565b348015610448575f80fd5b506102086104573660046124c0565b61107c565b61020861046a36600461244b565b611348565b34801561047a575f80fd5b5061020861048936600461241e565b611492565b348015610499575f80fd5b506104ee6104a836600461241e565b60036020525f908152604090205465ffffffffffff80821691600160301b81049091169060ff600160601b8204811691600160681b8104821691600160701b9091041685565b6040805165ffffffffffff96871681529590941660208601529115159284019290925290151560608301521515608082015260a00161023d565b348015610533575f80fd5b5061020861054236600461257c565b611602565b348015610552575f80fd5b506102086117e0565b348015610566575f80fd5b506102297f000000000000000000000000000000000000000000000000000000000000000081565b348015610599575f80fd5b506004546105a79060ff1681565b60405161023d91906125d0565b3480156105bf575f80fd5b506102297f000000000000000000000000000000000000000000000000000000000000000081565b3480156105f2575f80fd5b50610208611832565b348015610606575f80fd5b506102086106153660046124a0565b611886565b348015610625575f80fd5b506102297f000000000000000000000000000000000000000000000000000000000000000081565b348015610658575f80fd5b5061020861066736600461241e565b6118fe565b348015610677575f80fd5b5061068b61068636600461241e565b611a28565b60405161023d91906125ea565b3480156106a3575f80fd5b506102297f000000000000000000000000000000000000000000000000000000000000000081565b6005544211156106f65760405162461bcd60e51b81526004016106ed906125fe565b60405180910390fd5b604051632b33745b60e21b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063accdd16c906024015f604051808303815f87803b158015610755575f80fd5b505af1158015610767573d5f803e3d5ffd5b505050507fe2b6c70f0bb14be8c1be3a3875d171dd198b1f9f2d35972501b91c0fc6c1b0ce8160405161079c91815260200190565b60405180910390a150565b5f546001600160a01b031633146107d05760405162461bcd60e51b81526004016106ed9061263f565b5f6004805460ff16908111156107e8576107e86125bc565b146108355760405162461bcd60e51b815260206004820152601760248201527f50726f746f636f6c20616c72656164792066726f7a656e00000000000000000060448201526064016106ed565b6004805460ff1916600117905561084e61a8c042612695565b600555610859611bbd565b7f24f7761883b592e1cb80bcb0b5ad54822c7ed844019f3459111f131715d1ecc960055460405161088c91815260200190565b60405180910390a1565b600554156108b65760405162461bcd60e51b81526004016106ed906126ba565b6040516351d218f760e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906351d218f7906024015f604051808303815f87803b158015610915575f80fd5b505af1158015610927573d5f803e3d5ffd5b505050507fa938747b1cf8e014275de2758fc8d441002154a94bca459b291cbbbeb0c7c89d8160405161079c91815260200190565b6002546001600160a01b031633146109dc5760405162461bcd60e51b815260206004820152603d60248201527f4f6e6c7920456d657267656e6379205570677261646520426f6172642069732060448201527f616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e00000060648201526084016106ed565b5f816040516020016109ee91906126fd565b6040516020818303038152906040528051906020012090505f610a1082611a28565b90505f816006811115610a2557610a256125bc565b14610a6b5760405162461bcd60e51b81526020600482015260166024820152755570677261646520616c72656164792065786973747360501b60448201526064016106ed565b33610a7c60408501602086016124a0565b6001600160a01b031614610aa25760405162461bcd60e51b81526004016106ed90612858565b5f828152600360205260408120805460ff60701b1916600160701b1790556004805460ff19169055600555610ad5611efe565b610ae7610ae284806128ab565b612229565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded905f90a160405182907f39f6aeadc0239b46b37917ee1c12e98f9cd3a5dea6c038efa22af67471128e51905f90a2505050565b333014610b5d5760405162461bcd60e51b81526004016106ed906128f8565b6001546040516001600160a01b038084169216907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d88905f90a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b0316331480610bdd575060055415801590610bdd575060055442115b610c755760405162461bcd60e51b815260206004820152605760248201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f77656460448201527f20746f2063616c6c20746869732066756e6374696f6e206f722074686520707260648201527f6f746f636f6c2073686f756c642062652066726f7a656e000000000000000000608482015260a4016106ed565b60016004805460ff1690811115610c8e57610c8e6125bc565b03610cad57600480546003919060ff19166001835b0217905550610d25565b60026004805460ff1690811115610cc657610cc66125bc565b03610cdd5760048054819060ff1916600182610ca3565b60405162461bcd60e51b815260206004820152601d60248201527f556e6578706563746564206c61737420667265657a652073746174757300000060448201526064016106ed565b5f600555610d31611efe565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded905f90a1565b6001546001600160a01b03163314610d855760405162461bcd60e51b81526004016106ed90612963565b5f81815260036020526040902054600160601b900460ff1615610dfb5760405162461bcd60e51b815260206004820152602860248201527f5570677261646520697320616c726561647920617070726f76656420627920676044820152677561726469616e7360c01b60648201526084016106ed565b5f610e0582611a28565b90506002816006811115610e1b57610e1b6125bc565b14610e9a5760405162461bcd60e51b815260206004820152604360248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d20477561726469606482015262616e7360e81b608482015260a4016106ed565b5f82815260036020526040808220805460ff60601b1916600160601b1790555183917f4bdba07411d36daebbfc1a5062f25d0d02c753374c8498aec76d5954c707682a91a25050565b333014610f025760405162461bcd60e51b81526004016106ed906128f8565b6002546040516001600160a01b038084169216907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d76670905f90a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b03163314610f865760405162461bcd60e51b81526004016106ed9061263f565b60045460ff165f816004811115610f9f57610f9f6125bc565b1480610fbc57506001816004811115610fba57610fba6125bc565b145b80610fd857506003816004811115610fd657610fd66125bc565b145b6110245760405162461bcd60e51b815260206004820152601d60248201527f50726f746f636f6c2063616e277420626520686172642066726f7a656e00000060448201526064016106ed565b6004805460ff1916600217905561103e62093a8042612695565b600555611049611bbd565b7f8cfb4dcbe7dce698c042e43e42e1e496194abadb41ac3756f5793a9c5a8bb3e860055460405161079c91815260200190565b5f8160405160200161108e91906126fd565b60408051601f1981840301815260608301825261ffff881683526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166020850152838301829052915163e4948f4360e01b81529093505f917f0000000000000000000000000000000000000000000000000000000000000000169063e4948f439061112e908c908c9087908c908c906004016129e2565b602060405180830381865afa158015611149573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061116d9190612a83565b9050806111d05760405162461bcd60e51b815260206004820152602b60248201527f4661696c656420746f20636865636b20757067726164652070726f706f73616c60448201526a1034b734ba34b0ba34b7b760a91b60648201526084016106ed565b6002546001600160a01b03166111ec60408601602087016124a0565b6001600160a01b03160361125e5760405162461bcd60e51b815260206004820152603360248201527f456d657267656e6379205570677261646520426f6172642063616e2774206578604482015272656375746520757375616c207570677261646560681b60648201526084016106ed565b825160208401205f61126f82611a28565b90505f816006811115611284576112846125bc565b146112dd5760405162461bcd60e51b815260206004820152602360248201527f557067726164652077697468207468697320696420616c72656164792065786960448201526273747360e81b60648201526084016106ed565b5f8281526003602052604090819020805465ffffffffffff19164265ffffffffffff161790555182907f71a79729ed8b7db17b27c5dfe0ae24cf41d52b08c8dfc82592fc7db23010c879906113339089906126fd565b60405180910390a25050505050505050505050565b5f8160405160200161135a91906126fd565b6040516020818303038152906040528051906020012090505f61137c82611a28565b90506004816006811115611392576113926125bc565b146113df5760405162461bcd60e51b815260206004820152601860248201527f55706772616465206973206e6f7420796574207265616479000000000000000060448201526064016106ed565b5f6113f060408501602086016124a0565b6001600160a01b0316148061141c57503361141160408501602086016124a0565b6001600160a01b0316145b6114385760405162461bcd60e51b81526004016106ed90612858565b5f828152600360205260409020805460ff60701b1916600160701b179055611463610ae284806128ab565b60405182907ff6224a998aea3de231cf75375faf8c3711379d54bb84c92ef9d9779dabd383a9905f90a2505050565b6001546001600160a01b031633146114bc5760405162461bcd60e51b81526004016106ed90612963565b5f81815260036020526040902054600160681b900460ff161561152f5760405162461bcd60e51b815260206004820152602560248201527f4c6567616c207665746f20706572696f6420697320616c726561647920657874604482015264195b99195960da1b60648201526084016106ed565b5f61153982611a28565b9050600181600681111561154f5761154f6125bc565b146115b95760405162461bcd60e51b815260206004820152603460248201527f5570677261646520776974682074686973206964206973206e6f7420696e20746044820152731a19481b1959d85b081d995d1bc81c195c9a5bd960621b60648201526084016106ed565b5f82815260036020526040808220805460ff60681b1916600160681b1790555183917f6679375a2761fa72f4163ccf9a92a514bfd3adff8eb1f2f17256f25834dc46ca91a25050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f811580156116475750825b90505f8267ffffffffffffffff1660011480156116635750303b155b905081158015611671575080155b1561168f5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156116b957845460ff60401b1916600160401b1785555b5f80546001600160a01b0319166001600160a01b038a1690811782556040519091907fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f5951908290a3600180546001600160a01b0319166001600160a01b0389169081179091556040515f907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d88908290a3600280546001600160a01b0319166001600160a01b0388169081179091556040515f907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d76670908290a383156117d657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b600554156118005760405162461bcd60e51b81526004016106ed906126ba565b611808611efe565b6040517fea592eda90ea1daf1d7577bddc51f4f8425ec0332f0dd8b58aa08f8a2d1da621905f90a1565b6005544211156118545760405162461bcd60e51b81526004016106ed906125fe565b61185c611bbd565b6040517fbe5088092f32032505342f55f3393029ab55bd4dfcc2edad138d715f485ace6e905f90a1565b3330146118a55760405162461bcd60e51b81526004016106ed906128f8565b5f80546040516001600160a01b03808516939216917fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f595191a35f80546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b031633146119275760405162461bcd60e51b81526004016106ed9061263f565b5f61193182611a28565b90506002816006811115611947576119476125bc565b146119cd5760405162461bcd60e51b815260206004820152604a60248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d205365637572696064820152691d1e4810dbdd5b98da5b60b21b608482015260a4016106ed565b5f8281526003602052604080822080546bffffffffffff0000000000001916600160301b4265ffffffffffff16021790555183917f4ea0d7cd48461eaf68f428942cdfb19039bd43dc723fa8875c65bec57d911ac491a25050565b5f818152600360209081526040808320815160a081018352905465ffffffffffff8082168352600160301b8204169382019390935260ff600160601b84048116151592820192909252600160681b8304821615156060820152600160701b909204161580156080830152611a9f5750600692915050565b805165ffffffffffff165f03611ab757505f92915050565b5f8160600151611aca576203f480611acf565b62093a805b8251909150611ae790829065ffffffffffff16612695565b421015611af8575060019392505050565b602082015165ffffffffffff1615611b43575f62015180836020015165ffffffffffff16611b269190612695565b905080421015611b37576003611b3a565b60045b95945050505050565b5f62278d0082845f015165ffffffffffff16611b5f9190612695565b611b699190612695565b9050804210611bb2578260400151611b8657506005949350505050565b5f611b946201518083612695565b905080421015611ba5576003611ba8565b60045b9695505050505050565b506002949350505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166368b8d3316040518163ffffffff1660e01b81526004015f60405180830381865afa158015611c19573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611c409190810190612ab6565b80519091505f5b81811015611ce7577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663accdd16c848381518110611c9057611c90612b6f565b60200260200101516040518263ffffffff1660e01b8152600401611cb691815260200190565b5f604051808303815f87803b158015611ccd575f80fd5b505af1925050508015611cde575060015b50600101611c47565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638456cb596040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611d40575f80fd5b505af1925050508015611d51575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638456cb596040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611daa575f80fd5b505af1925050508015611dbb575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638456cb596040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611e14575f80fd5b505af1925050508015611e25575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638456cb596040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611e7e575f80fd5b505af1925050508015611e8f575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ac700e636040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611ee8575f80fd5b505af1925050508015611ef9575060015b505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166368b8d3316040518163ffffffff1660e01b81526004015f60405180830381865afa158015611f5a573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611f819190810190612ab6565b80519091505f5b81811015612028577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166351d218f7848381518110611fd157611fd1612b6f565b60200260200101516040518263ffffffff1660e01b8152600401611ff791815260200190565b5f604051808303815f87803b15801561200e575f80fd5b505af192505050801561201f575060015b50600101611f88565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633f4ba83a6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015612081575f80fd5b505af1925050508015612092575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633f4ba83a6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156120eb575f80fd5b505af19250505080156120fc575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633f4ba83a6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015612155575f80fd5b505af1925050508015612166575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633f4ba83a6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156121bf575f80fd5b505af19250505080156121d0575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f7c7eb926040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611ee8575f80fd5b5f5b81811015611ef9575f83838381811061224657612246612b6f565b90506020028101906122589190612b83565b612266906040810190612ba1565b9050111561231e575f83838381811061228157612281612b6f565b90506020028101906122939190612b83565b6122a19060208101906124a0565b6001600160a01b03163b1161231e5760405162461bcd60e51b815260206004820152603c60248201527f546172676574206d757374206265206120736d61727420636f6e74726163742060448201527f6966207468652063616c6c64617461206973206e6f7420656d7074790000000060648201526084016106ed565b5f8084848481811061233257612332612b6f565b90506020028101906123449190612b83565b6123529060208101906124a0565b6001600160a01b031685858581811061236d5761236d612b6f565b905060200281019061237f9190612b83565b6020013586868681811061239557612395612b6f565b90506020028101906123a79190612b83565b6123b5906040810190612ba1565b6040516123c3929190612be4565b5f6040518083038185875af1925050503d805f81146123fd576040519150601f19603f3d011682016040523d82523d5f602084013e612402565b606091505b50915091508161241457805160208201fd5b505060010161222b565b5f6020828403121561242e575f80fd5b5035919050565b5f60608284031215612445575f80fd5b50919050565b5f6020828403121561245b575f80fd5b813567ffffffffffffffff811115612471575f80fd5b61247d84828501612435565b949350505050565b80356001600160a01b038116811461249b575f80fd5b919050565b5f602082840312156124b0575f80fd5b6124b982612485565b9392505050565b5f805f805f8060a087890312156124d5575f80fd5b8635955060208701359450604087013561ffff811681146124f4575f80fd5b9350606087013567ffffffffffffffff80821115612510575f80fd5b818901915089601f830112612523575f80fd5b813581811115612531575f80fd5b8a60208260051b8501011115612545575f80fd5b602083019550809450506080890135915080821115612562575f80fd5b5061256f89828a01612435565b9150509295509295509295565b5f805f6060848603121561258e575f80fd5b61259784612485565b92506125a560208501612485565b91506125b360408501612485565b90509250925092565b634e487b7160e01b5f52602160045260245ffd5b60208101600583106125e4576125e46125bc565b91905290565b60208101600783106125e4576125e46125bc565b60208082526021908201527f50726f746f636f6c2073686f756c6420626520616c72656164792066726f7a656040820152603760f91b606082015260800190565b60208082526036908201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f776564604082015275103a379031b0b636103a3434b990333ab731ba34b7b760511b606082015260800190565b808201808211156126b457634e487b7160e01b5f52601160045260245ffd5b92915050565b60208082526023908201527f50726f746f636f6c2073686f756c6420626520616c726561647920756e66726f6040820152623d32b760e91b606082015260800190565b5f602080835260808084018535601e1987360301811261271b575f80fd5b8601803584820167ffffffffffffffff80831115612737575f80fd5b8260051b803603831315612749575f80fd5b60608a890181905295849052890160a0908101955f918b0136879003607e19015b8684101561281e578c8903609f190182528535818112612788575f80fd5b88016001600160a01b0361279d8d8301612485565b168a526040808201358d8c015284820135603e198336030181126127bf575f80fd5b90910181810191908d0135878111156127d6575f80fd5b8036038313156127e4575f80fd5b85828d015280868d015280838e8e01375f8c82018e0152601f01601f1916909a018b01995050948a019460019390930192908a019061276a565b5050505050505050612831838701612485565b6001600160a01b038116604087015292506040860135606086015280935050505092915050565b60208082526033908201527f6d73672e73656e646572206973206e6f7420617574686f72697a656420746f20604082015272706572666f726d20746865207570677261646560681b606082015260800190565b5f808335601e198436030181126128c0575f80fd5b83018035915067ffffffffffffffff8211156128da575f80fd5b6020019150600581901b36038213156128f1575f80fd5b9250929050565b60208082526045908201527f4f6e6c7920757067726164652068616e646c657220636f6e747261637420697460408201527f73656c6620697320616c6c6f77656420746f2063616c6c20746869732066756e60608201526431ba34b7b760d91b608082015260a00190565b6020808252602f908201527f4f6e6c7920677561726469616e7320697320616c6c6f77656420746f2063616c60408201526e36103a3434b990333ab731ba34b7b760891b606082015260800190565b8183525f6001600160fb1b038311156129c9575f80fd5b8260051b80836020870137939093016020019392505050565b8581525f60208660208401526080604084015261ffff865116608084015260018060a01b0360208701511660a08401526040860151606060c085015280518060e08601525f5b81811015612a455782810184015186820161010001528301612a28565b5061010092505f838287010152601f19601f820116850191505081848203016060850152612a7682820186886129b2565b9998505050505050505050565b5f60208284031215612a93575f80fd5b815180151581146124b9575f80fd5b634e487b7160e01b5f52604160045260245ffd5b5f6020808385031215612ac7575f80fd5b825167ffffffffffffffff80821115612ade575f80fd5b818501915085601f830112612af1575f80fd5b815181811115612b0357612b03612aa2565b8060051b604051601f19603f83011681018181108582111715612b2857612b28612aa2565b604052918252848201925083810185019188831115612b45575f80fd5b938501935b82851015612b6357845184529385019392850192612b4a565b98975050505050505050565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112612b97575f80fd5b9190910192915050565b5f808335601e19843603018112612bb6575f80fd5b83018035915067ffffffffffffffff821115612bd0575f80fd5b6020019150368190038213156128f1575f80fd5b818382375f910190815291905056fea2646970667358221220aadc6bea6f812101237dfeae34d5ba93c3bd57e843564d12d38526b32c92244d64736f6c63430008180033000000000000000000000000085b8b6407f150d62adb1ef926f7f304600ec71400000000000000000000000032400084c286cf3e17e7b677ea9583e60a000324000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb5213000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb0000000000000000000000008829ad80e425c646dab305381ff105169feece56000000000000000000000000bed1eb542f9a5aa6419ff3deb921a372681111f6000000000000000000000000dd5cb8b9037357b4cd37391a073798f8aab61076","name":"ProtocolUpgradeHandler","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":true,"additional_sources":[{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"},{"file_path":"src/interfaces/IBridgeHub.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IPausable} from \"./IPausable.sol\";\n\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\ninterface IBridgeHub is IPausable {\n    function getAllZKChainChainIDs() external view returns (uint256[] memory);\n}\n"},{"file_path":"src/interfaces/IChainAssetHandler.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\ninterface IChainAssetHandler {\n    /// @notice Pauses migration functions.\n    function pauseMigration() external;\n\n    /// @notice Unpauses migration functions.\n    function unpauseMigration() external;\n}\n"},{"file_path":"src/interfaces/IChainTypeManager.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\ninterface IChainTypeManager {\n    function freezeChain(uint256 _chainId) external;\n\n    function unfreezeChain(uint256 _chainId) external;\n\n    function validatorTimelock() external view returns (address);\n}\n"},{"file_path":"src/interfaces/IPausable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\ninterface IPausable {\n    function pause() external;\n\n    function unpause() external;\n}\n"},{"file_path":"src/interfaces/IProtocolUpgradeHandler.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\ninterface IProtocolUpgradeHandler {\n    /// @dev This enumeration includes the following states:\n    /// @param None Default state, indicating the upgrade has not been set.\n    /// @param LegalVetoPeriod The upgrade passed L2 voting process but it is waiting for the legal veto period.\n    /// @param Waiting The upgrade passed Legal Veto period but it is waiting for the approval from guardians or Security Council.\n    /// @param ExecutionPending The upgrade proposal is waiting for the delay period before being ready for execution.\n    /// @param Ready The upgrade proposal is ready to be executed.\n    /// @param Expired The upgrade proposal was expired.\n    /// @param Done The upgrade has been successfully executed.\n    enum UpgradeState {\n        None,\n        LegalVetoPeriod,\n        Waiting,\n        ExecutionPending,\n        Ready,\n        Expired,\n        Done\n    }\n\n    /// @dev Represents the status of an upgrade process, including the creation timestamp and actions made by guardians and Security Council.\n    /// @param creationTimestamp The timestamp (in seconds) when the upgrade state was created.\n    /// @param securityCouncilApprovalTimestamp The timestamp (in seconds) when Security Council approved the upgrade.\n    /// @param guardiansApproval Indicates whether the upgrade has been approved by the guardians.\n    /// @param guardiansExtendedLegalVeto Indicates whether guardians extended the legal veto period.\n    /// @param executed Indicates whether the proposal is executed or not.\n    struct UpgradeStatus {\n        uint48 creationTimestamp;\n        uint48 securityCouncilApprovalTimestamp;\n        bool guardiansApproval;\n        bool guardiansExtendedLegalVeto;\n        bool executed;\n    }\n\n    /// @dev Represents a call to be made during an upgrade.\n    /// @param target The address to which the call will be made.\n    /// @param value The amount of Ether (in wei) to be sent along with the call.\n    /// @param data The calldata to be executed on the `target` address.\n    struct Call {\n        address target;\n        uint256 value;\n        bytes data;\n    }\n\n    /// @dev Defines the structure of an upgrade that is executed by Protocol Upgrade Handler.\n    /// @param executor The L1 address that is authorized to perform the upgrade execution (if address(0) then anyone).\n    /// @param calls An array of `Call` structs, each representing a call to be made during the upgrade execution.\n    /// @param salt A bytes32 value used for creating unique upgrade proposal hashes.\n    struct UpgradeProposal {\n        Call[] calls;\n        address executor;\n        bytes32 salt;\n    }\n\n    /// @dev This enumeration includes the following states:\n    /// @param None Default state, indicating the freeze has not been happening in this upgrade cycle.\n    /// @param Soft The protocol is/was frozen for the short time.\n    /// @param Hard The protocol is/was frozen for the long time.\n    /// @param AfterSoftFreeze The protocol was soft frozen, it can be hard frozen in this upgrade cycle.\n    /// @param AfterHardFreeze The protocol was hard frozen, but now it can't be frozen until the upgrade.\n    enum FreezeStatus {\n        None,\n        Soft,\n        Hard,\n        AfterSoftFreeze,\n        AfterHardFreeze\n    }\n\n    function startUpgrade(\n        uint256 _l2BatchNumber,\n        uint256 _l2MessageIndex,\n        uint16 _l2TxNumberInBatch,\n        bytes32[] calldata _proof,\n        UpgradeProposal calldata _proposal\n    ) external;\n\n    function extendLegalVeto(bytes32 _id) external;\n\n    function approveUpgradeSecurityCouncil(bytes32 _id) external;\n\n    function approveUpgradeGuardians(bytes32 _id) external;\n\n    function execute(UpgradeProposal calldata _proposal) external payable;\n\n    function executeEmergencyUpgrade(UpgradeProposal calldata _proposal) external payable;\n\n    function softFreeze() external;\n\n    function hardFreeze() external;\n\n    function reinforceFreeze() external;\n\n    function unfreeze() external;\n\n    function reinforceFreezeOneChain(uint256 _chainId) external;\n\n    function reinforceUnfreeze() external;\n\n    function reinforceUnfreezeOneChain(uint256 _chainId) external;\n\n    function upgradeState(bytes32 _id) external view returns (UpgradeState);\n\n    function updateSecurityCouncil(address _newSecurityCouncil) external;\n\n    function updateGuardians(address _newGuardians) external;\n\n    function updateEmergencyUpgradeBoard(address _newEmergencyUpgradeBoard) external;\n\n    /// @notice Emitted when the security council address is changed.\n    event ChangeSecurityCouncil(address indexed _securityCouncilBefore, address indexed _securityCouncilAfter);\n\n    /// @notice Emitted when the guardians address is changed.\n    event ChangeGuardians(address indexed _guardiansBefore, address indexed _guardiansAfter);\n\n    /// @notice Emitted when the emergency upgrade board address is changed.\n    event ChangeEmergencyUpgradeBoard(\n        address indexed _emergencyUpgradeBoardBefore, address indexed _emergencyUpgradeBoardAfter\n    );\n\n    /// @notice Emitted when upgrade process on L1 is started.\n    event UpgradeStarted(bytes32 indexed _id, UpgradeProposal _proposal);\n\n    /// @notice Emitted when the legal veto period is extended.\n    event UpgradeLegalVetoExtended(bytes32 indexed _id);\n\n    /// @notice Emitted when Security Council approved the upgrade.\n    event UpgradeApprovedBySecurityCouncil(bytes32 indexed _id);\n\n    /// @notice Emitted when Guardians approved the upgrade.\n    event UpgradeApprovedByGuardians(bytes32 indexed _id);\n\n    /// @notice Emitted when the upgrade is executed.\n    event UpgradeExecuted(bytes32 indexed _id);\n\n    /// @notice Emitted when the emergency upgrade is executed.\n    event EmergencyUpgradeExecuted(bytes32 indexed _id);\n\n    /// @notice Emitted when the protocol became soft frozen.\n    event SoftFreeze(uint256 _protocolFrozenUntil);\n\n    /// @notice Emitted when the protocol became hard frozen.\n    event HardFreeze(uint256 _protocolFrozenUntil);\n\n    /// @notice Emitted when someone makes an attempt to freeze the protocol when it is frozen already.\n    event ReinforceFreeze();\n\n    /// @notice Emitted when the protocol became active after the soft/hard freeze.\n    event Unfreeze();\n\n    /// @notice Emitted when someone makes an attempt to freeze the specific chain when the protocol is frozen already.\n    event ReinforceFreezeOneChain(uint256 _chainId);\n\n    /// @notice Emitted when someone makes an attempt to unfreeze the protocol when it is unfrozen already.\n    event ReinforceUnfreeze();\n\n    /// @notice Emitted when someone makes an attempt to unfreeze the specific chain when the protocol is unfrozen already.\n    event ReinforceUnfreezeOneChain(uint256 _chainId);\n}\n"},{"file_path":"src/interfaces/IZKsyncEra.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/// @author Matter Labs\n/// @custom:security-contact security@matterlabs.dev\ninterface IZKsyncEra {\n    /// @dev An arbitrary length message passed from L2\n    /// @notice Under the hood it is `L2Log` sent from the special system L2 contract\n    /// @param txNumberInBatch The L2 transaction number in the batch, in which the message was sent\n    /// @param sender The address of the L2 account from which the message was passed\n    /// @param data An arbitrary length message\n    struct L2Message {\n        uint16 txNumberInBatch;\n        address sender;\n        bytes data;\n    }\n\n    /// @notice Prove that a specific arbitrary-length message was sent in a specific L2 batch number\n    /// @param _batchNumber The executed L2 batch number in which the message appeared\n    /// @param _index The position in the L2 logs Merkle tree of the l2Log that was sent with the message\n    /// @param _message Information about the sent message: sender address, the message itself, tx index in the L2 batch where the message was sent\n    /// @param _proof Merkle proof for inclusion of L2 log that was sent with the message\n    /// @return Whether the proof is valid\n    function proveL2MessageInclusion(\n        uint256 _batchNumber,\n        uint256 _index,\n        L2Message memory _message,\n        bytes32[] calldata _proof\n    ) external view returns (bool);\n\n    /// @notice Request execution of L2 transaction from L1.\n    /// @param _contractL2 The L2 receiver address\n    /// @param _l2Value `msg.value` of L2 transaction\n    /// @param _calldata The input of the L2 transaction\n    /// @param _l2GasLimit Maximum amount of L2 gas that transaction can consume during execution on L2\n    /// @param _l2GasPerPubdataByteLimit The maximum amount L2 gas that the operator may charge the user for single byte of pubdata.\n    /// @param _factoryDeps An array of L2 bytecodes that will be marked as known on L2\n    /// @param _refundRecipient The address on L2 that will receive the refund for the transaction.\n    /// @dev If the L2 deposit finalization transaction fails, the `_refundRecipient` will receive the `_l2Value`.\n    /// Please note, the contract may change the refund recipient's address to eliminate sending funds to addresses out of control.\n    /// - If `_refundRecipient` is a contract on L1, the refund will be sent to the aliased `_refundRecipient`.\n    /// - If `_refundRecipient` is set to `address(0)` and the sender has NO deployed bytecode on L1, the refund will be sent to the `msg.sender` address.\n    /// - If `_refundRecipient` is set to `address(0)` and the sender has deployed bytecode on L1, the refund will be sent to the aliased `msg.sender` address.\n    /// @dev The address aliasing of L1 contracts as refund recipient on L2 is necessary to guarantee that the funds are controllable,\n    /// since address aliasing to the from address for the L2 tx will be applied if the L1 `msg.sender` is a contract.\n    /// Without address aliasing for L1 contracts as refund recipients they would not be able to make proper L2 tx requests\n    /// through the Mailbox to use or withdraw the funds from L2, and the funds would be lost.\n    function requestL2Transaction(\n        address _contractL2,\n        uint256 _l2Value,\n        bytes calldata _calldata,\n        uint256 _l2GasLimit,\n        uint256 _l2GasPerPubdataByteLimit,\n        bytes[] calldata _factoryDeps,\n        address _refundRecipient\n    ) external payable;\n\n    /// @notice Estimates the cost in Ether of requesting execution of an L2 transaction from L1\n    /// @param _gasPrice expected L1 gas price at which the user requests the transaction execution\n    /// @param _l2GasLimit Maximum amount of L2 gas that transaction can consume during execution on L2\n    /// @param _l2GasPerPubdataByteLimit The maximum amount of L2 gas that the operator may charge the user for a single byte of pubdata.\n    /// @return The estimated ETH spent on L2 gas for the transaction\n    function l2TransactionBaseCost(\n        uint256 _gasPrice,\n        uint256 _l2GasLimit,\n        uint256 _l2GasPerPubdataByteLimit\n    ) external view returns (uint256);\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"_l2ProtocolGovernor","type":"address"},{"internalType":"contract IZKsyncEra","name":"_ZKsyncEra","type":"address"},{"internalType":"contract IChainTypeManager","name":"_chainTypeManager","type":"address"},{"internalType":"contract IBridgeHub","name":"_bridgeHub","type":"address"},{"internalType":"contract IPausable","name":"_l1Nullifier","type":"address"},{"internalType":"contract IPausable","name":"_l1AssetRouter","type":"address"},{"internalType":"contract IPausable","name":"_l1NativeTokenVault","type":"address"},{"internalType":"contract IChainAssetHandler","name":"_chainAssetHandler","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_emergencyUpgradeBoardBefore","type":"address"},{"indexed":true,"internalType":"address","name":"_emergencyUpgradeBoardAfter","type":"address"}],"name":"ChangeEmergencyUpgradeBoard","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_guardiansBefore","type":"address"},{"indexed":true,"internalType":"address","name":"_guardiansAfter","type":"address"}],"name":"ChangeGuardians","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_securityCouncilBefore","type":"address"},{"indexed":true,"internalType":"address","name":"_securityCouncilAfter","type":"address"}],"name":"ChangeSecurityCouncil","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"EmergencyUpgradeExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_protocolFrozenUntil","type":"uint256"}],"name":"HardFreeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[],"name":"ReinforceFreeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"ReinforceFreezeOneChain","type":"event"},{"anonymous":false,"inputs":[],"name":"ReinforceUnfreeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"ReinforceUnfreezeOneChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_protocolFrozenUntil","type":"uint256"}],"name":"SoftFreeze","type":"event"},{"anonymous":false,"inputs":[],"name":"Unfreeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"UpgradeApprovedByGuardians","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"UpgradeApprovedBySecurityCouncil","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"UpgradeExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"UpgradeLegalVetoExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_id","type":"bytes32"},{"components":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IProtocolUpgradeHandler.Call[]","name":"calls","type":"tuple[]"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"indexed":false,"internalType":"struct IProtocolUpgradeHandler.UpgradeProposal","name":"_proposal","type":"tuple"}],"name":"UpgradeStarted","type":"event"},{"inputs":[],"name":"BRIDGE_HUB","outputs":[{"internalType":"contract IBridgeHub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHAIN_ASSET_HANDLER","outputs":[{"internalType":"contract IChainAssetHandler","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHAIN_TYPE_MANAGER","outputs":[{"internalType":"contract IChainTypeManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L1_ASSET_ROUTER","outputs":[{"internalType":"contract IPausable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L1_NATIVE_TOKEN_VAULT","outputs":[{"internalType":"contract IPausable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L1_NULLIFIER","outputs":[{"internalType":"contract IPausable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L2_PROTOCOL_GOVERNOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZKSYNC_ERA","outputs":[{"internalType":"contract IZKsyncEra","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"approveUpgradeGuardians","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"approveUpgradeSecurityCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyUpgradeBoard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IProtocolUpgradeHandler.Call[]","name":"calls","type":"tuple[]"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"internalType":"struct IProtocolUpgradeHandler.UpgradeProposal","name":"_proposal","type":"tuple"}],"name":"execute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IProtocolUpgradeHandler.Call[]","name":"calls","type":"tuple[]"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"internalType":"struct IProtocolUpgradeHandler.UpgradeProposal","name":"_proposal","type":"tuple"}],"name":"executeEmergencyUpgrade","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"extendLegalVeto","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"guardians","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hardFreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_securityCouncil","type":"address"},{"internalType":"address","name":"_guardians","type":"address"},{"internalType":"address","name":"_emergencyUpgradeBoard","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastFreezeStatusInUpgradeCycle","outputs":[{"internalType":"enum IProtocolUpgradeHandler.FreezeStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFrozenUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reinforceFreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"reinforceFreezeOneChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reinforceUnfreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"reinforceUnfreezeOneChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"securityCouncil","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"softFreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_l2BatchNumber","type":"uint256"},{"internalType":"uint256","name":"_l2MessageIndex","type":"uint256"},{"internalType":"uint16","name":"_l2TxNumberInBatch","type":"uint16"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"components":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IProtocolUpgradeHandler.Call[]","name":"calls","type":"tuple[]"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"internalType":"struct IProtocolUpgradeHandler.UpgradeProposal","name":"_proposal","type":"tuple"}],"name":"startUpgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unfreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newEmergencyUpgradeBoard","type":"address"}],"name":"updateEmergencyUpgradeBoard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGuardians","type":"address"}],"name":"updateGuardians","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newSecurityCouncil","type":"address"}],"name":"updateSecurityCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"upgradeState","outputs":[{"internalType":"enum IProtocolUpgradeHandler.UpgradeState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"upgradeId","type":"bytes32"}],"name":"upgradeStatus","outputs":[{"internalType":"uint48","name":"creationTimestamp","type":"uint48"},{"internalType":"uint48","name":"securityCouncilApprovalTimestamp","type":"uint48"},{"internalType":"bool","name":"guardiansApproval","type":"bool"},{"internalType":"bool","name":"guardiansExtendedLegalVeto","type":"bool"},{"internalType":"bool","name":"executed","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":"0x000000000000000000000000085b8b6407f150d62adb1ef926f7f304600ec71400000000000000000000000032400084c286cf3e17e7b677ea9583e60a000324000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb5213000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb0000000000000000000000008829ad80e425c646dab305381ff105169feece56000000000000000000000000bed1eb542f9a5aa6419ff3deb921a372681111f6000000000000000000000000dd5cb8b9037357b4cd37391a073798f8aab61076"}