Sepolia Testnet

Contract

0x9B956d242e6806044877C7C1B530D475E371d544

Overview

ETH Balance

8.943372035894775808 ETH

More Info

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Amount
Execute76186232025-02-01 17:08:48281 days ago1738429728IN
0x9B956d24...5E371d544
0 ETH0.001775929.02342063
Start Upgrade76039082025-01-30 15:14:48283 days ago1738250088IN
0x9B956d24...5E371d544
0 ETH0.000853757.976655
Transfer69844482024-10-31 16:18:12374 days ago1730391492IN
0x9B956d24...5E371d544
10 ETH0.000092854.41001258
Start Upgrade66435642024-09-06 14:04:24429 days ago1725631464IN
0x9B956d24...5E371d544
0 ETH0.0014213516.24345926
Execute66333712024-09-04 20:51:24430 days ago1725483084IN
0x9B956d24...5E371d544
0 ETH0.000381839.44183208
Execute65293852024-08-19 8:31:12447 days ago1724056272IN
0x9B956d24...5E371d544
0 ETH0.0008500619.15683764
Execute64943482024-08-13 20:38:00452 days ago1723581480IN
0x9B956d24...5E371d544
0 ETH0.000159024.29775398

Latest 5 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Amount
Request L2Transa...69844752024-10-31 16:24:00374 days ago1730391840
0x9B956d24...5E371d544
0.52831398 ETH
Request L2Transa...69844552024-10-31 16:19:48374 days ago1730391588
0x9B956d24...5E371d544
0.52831398 ETH
Transfer65293852024-08-19 8:31:12447 days ago1724056272
0x9B956d24...5E371d544
1 ETH
Transfer65293802024-08-19 8:30:00447 days ago1724056200
0x9B956d24...5E371d544
1 ETH
0x6101206064614752024-08-08 15:48:36458 days ago1723132116  Contract Creation0 ETH
Loading...
Loading

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code Verified (Exact Match)

Contract Name:
TestnetProtocolUpgradeHandler

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {ProtocolUpgradeHandler} from "./ProtocolUpgradeHandler.sol";
import {IZKsyncEra} from "./interfaces/IZKsyncEra.sol";
import {IStateTransitionManager} from "./interfaces/IStateTransitionManager.sol";
import {IPausable} from "./interfaces/IPausable.sol";

/// @title Testnet Protocol Upgrade Handler
/// @author Matter Labs
/// @custom:security-contact [email protected]
contract TestnetProtocolUpgradeHandler is ProtocolUpgradeHandler {
    /// @dev Duration of the standard legal veto period.
    function STANDARD_LEGAL_VETO_PERIOD() internal pure override returns (uint256) {
        return 0 days;
    }

    /// @notice Initializes the contract with the Security Council address, guardians address and address of L2 voting governor.
    /// @param _securityCouncil The address to be assigned as the Security Council of the contract.
    /// @param _guardians The address to be assigned as the guardians of the contract.
    /// @param _l2ProtocolGovernor The address of the L2 voting governor contract for protocol upgrades.
    constructor(
        address _securityCouncil,
        address _guardians,
        address _emergencyUpgradeBoard,
        address _l2ProtocolGovernor,
        IZKsyncEra _ZKsyncEra,
        IStateTransitionManager _stateTransitionManager,
        IPausable _bridgeHub,
        IPausable _sharedBridge
    )
        ProtocolUpgradeHandler(
            _securityCouncil,
            _guardians,
            _emergencyUpgradeBoard,
            _l2ProtocolGovernor,
            _ZKsyncEra,
            _stateTransitionManager,
            _bridgeHub,
            _sharedBridge
        )
    {}
}

// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {IZKsyncEra} from "./interfaces/IZKsyncEra.sol";
import {IStateTransitionManager} from "./interfaces/IStateTransitionManager.sol";
import {IPausable} from "./interfaces/IPausable.sol";
import {IProtocolUpgradeHandler} from "./interfaces/IProtocolUpgradeHandler.sol";

/// @title Protocol Upgrade Handler
/// @author Matter Labs
/// @custom:security-contact [email protected]
/// @dev The contract that holds ownership of all ZKsync contracts (L1 and L2). It is responsible
/// for handling ZKsync protocol upgrades proposed by L2 Token Assembly and executing it.
///
/// The upgrade process follows these key stages:
/// 1. Proposal: Token holders on L2 propose the protocol upgrades and send the L2 -> L1 message
///    that this contract reads and starts the upgrade process.
/// 2. Legal veto: During this period, the guardians can veto the upgrade **offchain**. The default legal period review
///    takes 3 days but can be extended by guardians onchain for 7 days in total.
/// 3. Approval: Requires approval from either the guardians or the Security Council. The Security Council can
///    immediately move the proposal to the next stage, while guardians approval will move the proposal to the
///    next stage only after 30 days delay after the legal veto passes. If no approval is received within the specified period, the proposal
///    is expired.
/// 4. Pending: A mandatory delay period before the actual execution of the upgrade, allowing for final
///    preparations and reviews.
/// 5. Execution: The proposed changes are executed by the authorized address in the proposal,
///    completing the upgrade process.
///
/// The contract implements the state machine that represents the logic of moving upgrade from each
/// stage by time changes and Guardians/Security Council actions.
contract ProtocolUpgradeHandler is IProtocolUpgradeHandler {
    /// @dev Duration of the standard legal veto period.
    /// Note: this value should not exceed EXTENDED_LEGAL_VETO_PERIOD.
    function STANDARD_LEGAL_VETO_PERIOD() internal pure virtual returns (uint256) {
        return 3 days;
    }

    /// @dev Duration of the extended legal veto period.
    uint256 internal constant EXTENDED_LEGAL_VETO_PERIOD = 7 days;

    /// @dev The mandatory delay period before an upgrade can be executed.
    /// This period is intended to provide a buffer after an upgrade's final approval and before its execution,
    /// allowing for final reviews and preparations for devs and users.
    uint256 internal constant UPGRADE_DELAY_PERIOD = 1 days;

    /// @dev Time limit for an upgrade proposal to be approved by guardians or expire, and the waiting period for execution post-guardians approval.
    /// If the Security Council approves, the upgrade can proceed immediately; otherwise,
    /// the proposal will expire after this period if not approved, or wait this period after guardians approval.
    uint256 internal constant UPGRADE_WAIT_OR_EXPIRE_PERIOD = 30 days;

    /// @dev Duration of a soft freeze which temporarily pause protocol contract functionality.
    /// This freeze window is needed for the Security Council to decide whether they want to
    /// do hard freeze and protocol upgrade.
    uint256 internal constant SOFT_FREEZE_PERIOD = 12 hours;

    /// @dev Duration of a hard freeze which temporarily pause protocol contract functionality.
    /// This freeze window is needed for the Security Council to perform emergency protocol upgrade.
    uint256 internal constant HARD_FREEZE_PERIOD = 7 days;

    /// @dev Address of the L2 Protocol Governor contract.
    /// This address is used to interface with governance actions initiated on Layer 2,
    /// specifically for proposing and approving protocol upgrades.
    address public immutable L2_PROTOCOL_GOVERNOR;

    /// @dev ZKsync smart contract that used to operate with L2 via asynchronous L2 <-> L1 communication.
    IZKsyncEra public immutable ZKSYNC_ERA;

    /// @dev ZKsync smart contract that is responsible for creating new hyperchains and changing parameters in existent.
    IStateTransitionManager public immutable STATE_TRANSITION_MANAGER;

    /// @dev Bridgehub smart contract that is used to operate with L2 via asynchronous L2 <-> L1 communication.
    IPausable public immutable BRIDGE_HUB;

    /// @dev The shared bridge that is used for all bridging.
    IPausable public immutable SHARED_BRIDGE;

    /// @notice The address of the Security Council.
    address public securityCouncil;

    /// @notice The address of the guardians.
    address public guardians;

    /// @notice The address of the smart contract that can execute protocol emergency upgrade.
    address public emergencyUpgradeBoard;

    /// @notice A mapping to store status of an upgrade process for each upgrade ID.
    mapping(bytes32 upgradeId => UpgradeStatus) public upgradeStatus;

    /// @notice Tracks the last freeze type within an upgrade cycle.
    FreezeStatus public lastFreezeStatusInUpgradeCycle;

    /// @notice Stores the timestamp until which the protocol remains frozen.
    uint256 public protocolFrozenUntil;

    /// @notice Initializes the contract with the Security Council address, guardians address and address of L2 voting governor.
    /// @param _securityCouncil The address to be assigned as the Security Council of the contract.
    /// @param _guardians The address to be assigned as the guardians of the contract.
    /// @param _l2ProtocolGovernor The address of the L2 voting governor contract for protocol upgrades.
    constructor(
        address _securityCouncil,
        address _guardians,
        address _emergencyUpgradeBoard,
        address _l2ProtocolGovernor,
        IZKsyncEra _ZKsyncEra,
        IStateTransitionManager _stateTransitionManager,
        IPausable _bridgeHub,
        IPausable _sharedBridge
    ) {
        // Soft configuration check for contracts that inherit this contract.
        assert(STANDARD_LEGAL_VETO_PERIOD() <= EXTENDED_LEGAL_VETO_PERIOD);

        securityCouncil = _securityCouncil;
        emit ChangeSecurityCouncil(address(0), _securityCouncil);

        guardians = _guardians;
        emit ChangeGuardians(address(0), _guardians);

        emergencyUpgradeBoard = _emergencyUpgradeBoard;
        emit ChangeEmergencyUpgradeBoard(address(0), _emergencyUpgradeBoard);

        L2_PROTOCOL_GOVERNOR = _l2ProtocolGovernor;
        ZKSYNC_ERA = _ZKsyncEra;
        STATE_TRANSITION_MANAGER = _stateTransitionManager;
        BRIDGE_HUB = _bridgeHub;
        SHARED_BRIDGE = _sharedBridge;
    }

    /*//////////////////////////////////////////////////////////////
                            MODIFIERS
    //////////////////////////////////////////////////////////////*/

    /// @notice Checks that the message sender is contract itself.
    modifier onlySelf() {
        require(msg.sender == address(this), "Only upgrade handler contract itself is allowed to call this function");
        _;
    }

    /// @notice Checks that the message sender is an active Security Council.
    modifier onlySecurityCouncil() {
        require(msg.sender == securityCouncil, "Only Security Council is allowed to call this function");
        _;
    }

    /// @notice Checks that the message sender is an active guardians.
    modifier onlyGuardians() {
        require(msg.sender == guardians, "Only guardians is allowed to call this function");
        _;
    }

    /// @notice Checks that the message sender is an active Security Council or the protocol is frozen but freeze period expired.
    modifier onlySecurityCouncilOrProtocolFreezeExpired() {
        require(
            msg.sender == securityCouncil || (protocolFrozenUntil != 0 && block.timestamp > protocolFrozenUntil),
            "Only Security Council is allowed to call this function or the protocol should be frozen"
        );
        _;
    }

    /// @notice Checks that the message sender is an Emergency Upgrade Board.
    modifier onlyEmergencyUpgradeBoard() {
        require(msg.sender == emergencyUpgradeBoard, "Only Emergency Upgrade Board is allowed to call this function");
        _;
    }

    /// @notice Calculates the current upgrade state for the specified upgrade ID.
    /// @param _id The unique identifier of the upgrade proposal to be approved.
    function upgradeState(bytes32 _id) public view returns (UpgradeState) {
        UpgradeStatus memory upg = upgradeStatus[_id];
        // Upgrade already executed
        if (upg.executed) {
            return UpgradeState.Done;
        }

        // Upgrade doesn't exist
        if (upg.creationTimestamp == 0) {
            return UpgradeState.None;
        }

        // Legal veto period
        uint256 legalVetoTime =
            upg.guardiansExtendedLegalVeto ? EXTENDED_LEGAL_VETO_PERIOD : STANDARD_LEGAL_VETO_PERIOD();
        if (block.timestamp < upg.creationTimestamp + legalVetoTime) {
            return UpgradeState.LegalVetoPeriod;
        }

        // Security council approval case
        if (upg.securityCouncilApprovalTimestamp != 0) {
            uint256 readyWithSecurityCouncilTimestamp = upg.securityCouncilApprovalTimestamp + UPGRADE_DELAY_PERIOD;
            return block.timestamp >= readyWithSecurityCouncilTimestamp
                ? UpgradeState.Ready
                : UpgradeState.ExecutionPending;
        }

        uint256 waitOrExpiryTimestamp = upg.creationTimestamp + legalVetoTime + UPGRADE_WAIT_OR_EXPIRE_PERIOD;
        if (block.timestamp >= waitOrExpiryTimestamp) {
            if (!upg.guardiansApproval) {
                return UpgradeState.Expired;
            }

            uint256 readyWithGuardiansTimestamp = waitOrExpiryTimestamp + UPGRADE_DELAY_PERIOD;
            return block.timestamp >= readyWithGuardiansTimestamp ? UpgradeState.Ready : UpgradeState.ExecutionPending;
        }

        return UpgradeState.Waiting;
    }

    /*//////////////////////////////////////////////////////////////
                            UPGRADE PROCESS
    //////////////////////////////////////////////////////////////*/

    /// @notice Initiates the upgrade process by verifying an L2 voting decision.
    /// @dev This function decodes and validates an upgrade proposal message from L2, setting the initial state for the upgrade process.
    /// @param _l2BatchNumber The batch number of the L2 transaction containing the upgrade proposal.
    /// @param _l2MessageIndex The index of the message within the L2 batch.
    /// @param _l2TxNumberInBatch The transaction number of the upgrade proposal in the L2 batch.
    /// @param _proof Merkle proof verifying the inclusion of the upgrade message in the L2 batch.
    /// @param _proposal The upgrade proposal details including proposed actions and the executor address.
    function startUpgrade(
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex,
        uint16 _l2TxNumberInBatch,
        bytes32[] calldata _proof,
        UpgradeProposal calldata _proposal
    ) external {
        bytes memory upgradeMessage = abi.encode(_proposal);
        IZKsyncEra.L2Message memory l2ToL1Message = IZKsyncEra.L2Message({
            txNumberInBatch: _l2TxNumberInBatch,
            sender: L2_PROTOCOL_GOVERNOR,
            data: upgradeMessage
        });
        bool success = ZKSYNC_ERA.proveL2MessageInclusion(_l2BatchNumber, _l2MessageIndex, l2ToL1Message, _proof);
        require(success, "Failed to check upgrade proposal initiation");
        require(_proposal.executor != emergencyUpgradeBoard, "Emergency Upgrade Board can't execute usual upgrade");

        bytes32 id = keccak256(upgradeMessage);
        UpgradeState upgState = upgradeState(id);
        require(upgState == UpgradeState.None, "Upgrade with this id already exists");

        upgradeStatus[id].creationTimestamp = uint48(block.timestamp);
        emit UpgradeStarted(id, _proposal);
    }

    /// @notice Extends the legal veto period by the guardians.
    /// @param _id The unique identifier of the upgrade proposal to be approved.
    function extendLegalVeto(bytes32 _id) external onlyGuardians {
        require(!upgradeStatus[_id].guardiansExtendedLegalVeto, "Legal veto period is already extended");
        UpgradeState upgState = upgradeState(_id);
        require(upgState == UpgradeState.LegalVetoPeriod, "Upgrade with this id is not in the legal veto period");
        upgradeStatus[_id].guardiansExtendedLegalVeto = true;

        emit UpgradeLegalVetoExtended(_id);
    }

    /// @notice Approves an upgrade proposal by the Security Council.
    /// @dev Transitions the state of an upgrade proposal to 'VetoPeriod' after approval by the Security Council.
    /// @param _id The unique identifier of the upgrade proposal to be approved.
    function approveUpgradeSecurityCouncil(bytes32 _id) external onlySecurityCouncil {
        UpgradeState upgState = upgradeState(_id);
        require(
            upgState == UpgradeState.Waiting,
            "Upgrade with this id is not waiting for the approval from Security Council"
        );
        upgradeStatus[_id].securityCouncilApprovalTimestamp = uint48(block.timestamp);

        emit UpgradeApprovedBySecurityCouncil(_id);
    }

    /// @notice Approves an upgrade proposal by the guardians.
    /// @dev Marks the upgrade proposal identified by `_id` as approved by guardians.
    /// @param _id The unique identifier of the upgrade proposal to approve.
    function approveUpgradeGuardians(bytes32 _id) external onlyGuardians {
        require(!upgradeStatus[_id].guardiansApproval, "Upgrade is already approved by guardians");

        UpgradeState upgState = upgradeState(_id);
        require(upgState == UpgradeState.Waiting, "Upgrade with this id is not waiting for the approval from Guardians");
        upgradeStatus[_id].guardiansApproval = true;

        emit UpgradeApprovedByGuardians(_id);
    }

    /// @notice Executes an upgrade proposal that has reached the 'Ready' state.
    /// @param _proposal The upgrade proposal to be executed, containing the target calls and optionally an executor.
    function execute(UpgradeProposal calldata _proposal) external payable {
        bytes32 id = keccak256(abi.encode(_proposal));
        UpgradeState upgState = upgradeState(id);
        // 1. Checks
        require(upgState == UpgradeState.Ready, "Upgrade is not yet ready");
        require(
            _proposal.executor == address(0) || _proposal.executor == msg.sender,
            "msg.sender is not authorized to perform the upgrade"
        );
        // 2. Effects
        upgradeStatus[id].executed = true;
        // 3. Interactions
        _execute(_proposal.calls);
        emit UpgradeExecuted(id);
    }

    /// @notice Executes an emergency upgrade proposal initiated by the emergency upgrade board.
    /// @param _proposal The upgrade proposal details including proposed actions and the executor address.
    function executeEmergencyUpgrade(UpgradeProposal calldata _proposal) external payable onlyEmergencyUpgradeBoard {
        bytes32 id = keccak256(abi.encode(_proposal));
        UpgradeState upgState = upgradeState(id);
        // 1. Checks
        require(upgState == UpgradeState.None, "Upgrade already exists");
        require(_proposal.executor == msg.sender, "msg.sender is not authorized to perform the upgrade");
        // 2. Effects
        upgradeStatus[id].executed = true;
        // Clear the freeze
        lastFreezeStatusInUpgradeCycle = FreezeStatus.None;
        protocolFrozenUntil = 0;
        _unfreeze();
        // 3. Interactions
        _execute(_proposal.calls);
        emit Unfreeze();
        emit EmergencyUpgradeExecuted(id);
    }

    /*//////////////////////////////////////////////////////////////
                            HELPERS
    //////////////////////////////////////////////////////////////*/

    /// @dev Execute an upgrade's calls.
    /// @param _calls The array of calls to be executed.
    function _execute(Call[] calldata _calls) internal {
        for (uint256 i = 0; i < _calls.length; ++i) {
            if (_calls[i].data.length > 0) {
                require(
                    _calls[i].target.code.length > 0, "Target must be a smart contract if the calldata is not empty"
                );
            }
            (bool success, bytes memory returnData) = _calls[i].target.call{value: _calls[i].value}(_calls[i].data);
            if (!success) {
                // Propagate an error if the call fails.
                assembly {
                    revert(add(returnData, 0x20), mload(returnData))
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                            FREEZABILITY
    //////////////////////////////////////////////////////////////*/

    /// @notice Initiates a soft protocol freeze.
    function softFreeze() external onlySecurityCouncil {
        require(lastFreezeStatusInUpgradeCycle == FreezeStatus.None, "Protocol already frozen");
        lastFreezeStatusInUpgradeCycle = FreezeStatus.Soft;
        protocolFrozenUntil = block.timestamp + SOFT_FREEZE_PERIOD;
        _freeze();
        emit SoftFreeze(protocolFrozenUntil);
    }

    /// @notice Initiates a hard protocol freeze.
    function hardFreeze() external onlySecurityCouncil {
        FreezeStatus freezeStatus = lastFreezeStatusInUpgradeCycle;
        require(
            freezeStatus == FreezeStatus.None || freezeStatus == FreezeStatus.Soft
                || freezeStatus == FreezeStatus.AfterSoftFreeze,
            "Protocol can't be hard frozen"
        );
        lastFreezeStatusInUpgradeCycle = FreezeStatus.Hard;
        protocolFrozenUntil = block.timestamp + HARD_FREEZE_PERIOD;
        _freeze();
        emit HardFreeze(protocolFrozenUntil);
    }

    /// @dev Reinforces the freezing state of the protocol if it is already within the frozen period. This function
    /// can be called by anyone to ensure the protocol remains in a frozen state, particularly useful if there is a need
    /// to confirm or re-apply the freeze due to partial or incomplete application during the initial freeze.
    function reinforceFreeze() external {
        require(block.timestamp <= protocolFrozenUntil, "Protocol should be already frozen");
        _freeze();
        emit ReinforceFreeze();
    }

    /// @dev Reinforces the freezing state of the specific chain if the protocol is already within the frozen period.
    /// The function is an analog of `reinforceFreeze` but only for one specific chain, needed in the
    /// rare case where the execution could get stuck at a particular ID for some unforeseen reason.
    function reinforceFreezeOneChain(uint256 _chainId) external {
        require(block.timestamp <= protocolFrozenUntil, "Protocol should be already frozen");
        STATE_TRANSITION_MANAGER.freezeChain(_chainId);
        emit ReinforceFreezeOneChain(_chainId);
    }

    /// @dev Freeze all ZKsync contracts, including bridges, state transition managers and all hyperchains.
    function _freeze() internal {
        uint256[] memory hyperchainIds = STATE_TRANSITION_MANAGER.getAllHyperchainChainIDs();
        uint256 len = hyperchainIds.length;
        for (uint256 i = 0; i < len; ++i) {
            try STATE_TRANSITION_MANAGER.freezeChain(hyperchainIds[i]) {} catch {}
        }

        try BRIDGE_HUB.pause() {} catch {}
        try SHARED_BRIDGE.pause() {} catch {}
    }

    /// @dev Unfreezes the protocol and resumes normal operations.
    function unfreeze() external onlySecurityCouncilOrProtocolFreezeExpired {
        if (lastFreezeStatusInUpgradeCycle == FreezeStatus.Soft) {
            lastFreezeStatusInUpgradeCycle = FreezeStatus.AfterSoftFreeze;
        } else if (lastFreezeStatusInUpgradeCycle == FreezeStatus.Hard) {
            lastFreezeStatusInUpgradeCycle = FreezeStatus.AfterHardFreeze;
        } else {
            revert("Unexpected last freeze status");
        }
        protocolFrozenUntil = 0;
        _unfreeze();
        emit Unfreeze();
    }

    /// @dev Reinforces the unfreeze for protocol if it is not in the freeze mode. This function can be called
    /// by anyone to ensure the protocol remains in an unfrozen state, particularly useful if there is a need
    /// to confirm or re-apply the unfreeze due to partial or incomplete application during the initial unfreeze.
    function reinforceUnfreeze() external {
        require(protocolFrozenUntil == 0, "Protocol should be already unfrozen");
        _unfreeze();
        emit ReinforceUnfreeze();
    }

    /// @dev Reinforces the unfreeze for one specific chain if the protocol is not in the freeze mode.
    /// The function is an analog of `reinforceUnfreeze` but only for one specific chain, needed in the
    /// rare case where the execution could get stuck at a particular ID for some unforeseen reason.
    function reinforceUnfreezeOneChain(uint256 _chainId) external {
        require(protocolFrozenUntil == 0, "Protocol should be already unfrozen");
        STATE_TRANSITION_MANAGER.unfreezeChain(_chainId);
        emit ReinforceUnfreezeOneChain(_chainId);
    }

    /// @dev Unfreeze all ZKsync contracts, including bridges, state transition managers and all hyperchains.
    function _unfreeze() internal {
        uint256[] memory hyperchainIds = STATE_TRANSITION_MANAGER.getAllHyperchainChainIDs();
        uint256 len = hyperchainIds.length;
        for (uint256 i = 0; i < len; ++i) {
            try STATE_TRANSITION_MANAGER.unfreezeChain(hyperchainIds[i]) {} catch {}
        }

        try BRIDGE_HUB.unpause() {} catch {}
        try SHARED_BRIDGE.unpause() {} catch {}
    }

    /*//////////////////////////////////////////////////////////////
                            SELF UPGRADES
    //////////////////////////////////////////////////////////////*/

    /// @dev Updates the address of the Security Council.
    /// @param _newSecurityCouncil The address of the new Security Council.
    function updateSecurityCouncil(address _newSecurityCouncil) external onlySelf {
        emit ChangeSecurityCouncil(securityCouncil, _newSecurityCouncil);
        securityCouncil = _newSecurityCouncil;
    }

    /// @dev Updates the address of the guardians.
    /// @param _newGuardians The address of the guardians.
    function updateGuardians(address _newGuardians) external onlySelf {
        emit ChangeGuardians(guardians, _newGuardians);
        guardians = _newGuardians;
    }

    /// @dev Updates the address of the emergency upgrade board.
    /// @param _newEmergencyUpgradeBoard The address of the guardians.
    function updateEmergencyUpgradeBoard(address _newEmergencyUpgradeBoard) external onlySelf {
        emit ChangeEmergencyUpgradeBoard(emergencyUpgradeBoard, _newEmergencyUpgradeBoard);
        emergencyUpgradeBoard = _newEmergencyUpgradeBoard;
    }

    /*//////////////////////////////////////////////////////////////
                            FALLBACK
    //////////////////////////////////////////////////////////////*/

    /// @dev Contract might receive/hold ETH as part of the maintenance process.
    receive() external payable {}
}

// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

/// @author Matter Labs
/// @custom:security-contact [email protected]
interface IZKsyncEra {
    /// @dev An arbitrary length message passed from L2
    /// @notice Under the hood it is `L2Log` sent from the special system L2 contract
    /// @param txNumberInBatch The L2 transaction number in the batch, in which the message was sent
    /// @param sender The address of the L2 account from which the message was passed
    /// @param data An arbitrary length message
    struct L2Message {
        uint16 txNumberInBatch;
        address sender;
        bytes data;
    }

    /// @notice Prove that a specific arbitrary-length message was sent in a specific L2 batch number
    /// @param _batchNumber The executed L2 batch number in which the message appeared
    /// @param _index The position in the L2 logs Merkle tree of the l2Log that was sent with the message
    /// @param _message Information about the sent message: sender address, the message itself, tx index in the L2 batch where the message was sent
    /// @param _proof Merkle proof for inclusion of L2 log that was sent with the message
    /// @return Whether the proof is valid
    function proveL2MessageInclusion(
        uint256 _batchNumber,
        uint256 _index,
        L2Message memory _message,
        bytes32[] calldata _proof
    ) external view returns (bool);

    /// @notice Request execution of L2 transaction from L1.
    /// @param _contractL2 The L2 receiver address
    /// @param _l2Value `msg.value` of L2 transaction
    /// @param _calldata The input of the L2 transaction
    /// @param _l2GasLimit Maximum amount of L2 gas that transaction can consume during execution on L2
    /// @param _l2GasPerPubdataByteLimit The maximum amount L2 gas that the operator may charge the user for single byte of pubdata.
    /// @param _factoryDeps An array of L2 bytecodes that will be marked as known on L2
    /// @param _refundRecipient The address on L2 that will receive the refund for the transaction.
    /// @dev If the L2 deposit finalization transaction fails, the `_refundRecipient` will receive the `_l2Value`.
    /// Please note, the contract may change the refund recipient's address to eliminate sending funds to addresses out of control.
    /// - If `_refundRecipient` is a contract on L1, the refund will be sent to the aliased `_refundRecipient`.
    /// - 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.
    /// - 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.
    /// @dev The address aliasing of L1 contracts as refund recipient on L2 is necessary to guarantee that the funds are controllable,
    /// since address aliasing to the from address for the L2 tx will be applied if the L1 `msg.sender` is a contract.
    /// Without address aliasing for L1 contracts as refund recipients they would not be able to make proper L2 tx requests
    /// through the Mailbox to use or withdraw the funds from L2, and the funds would be lost.
    function requestL2Transaction(
        address _contractL2,
        uint256 _l2Value,
        bytes calldata _calldata,
        uint256 _l2GasLimit,
        uint256 _l2GasPerPubdataByteLimit,
        bytes[] calldata _factoryDeps,
        address _refundRecipient
    ) external payable;
}

// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

/// @author Matter Labs
/// @custom:security-contact [email protected]
interface IStateTransitionManager {
    function freezeChain(uint256 _chainId) external;

    function unfreezeChain(uint256 _chainId) external;

    function getAllHyperchainChainIDs() external view returns (uint256[] memory);
}

// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

/// @author Matter Labs
/// @custom:security-contact [email protected]
interface IPausable {
    function pause() external;

    function unpause() external;
}

// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

/// @author Matter Labs
/// @custom:security-contact [email protected]
interface IProtocolUpgradeHandler {
    /// @dev This enumeration includes the following states:
    /// @param None Default state, indicating the upgrade has not been set.
    /// @param LegalVetoPeriod The upgrade passed L2 voting process but it is waiting for the legal veto period.
    /// @param Waiting The upgrade passed Legal Veto period but it is waiting for the approval from guardians or Security Council.
    /// @param ExecutionPending The upgrade proposal is waiting for the delay period before being ready for execution.
    /// @param Ready The upgrade proposal is ready to be executed.
    /// @param Expired The upgrade proposal was expired.
    /// @param Done The upgrade has been successfully executed.
    enum UpgradeState {
        None,
        LegalVetoPeriod,
        Waiting,
        ExecutionPending,
        Ready,
        Expired,
        Done
    }

    /// @dev Represents the status of an upgrade process, including the creation timestamp and actions made by guardians and Security Council.
    /// @param creationTimestamp The timestamp (in seconds) when the upgrade state was created.
    /// @param securityCouncilApprovalTimestamp The timestamp (in seconds) when Security Council approved the upgrade.
    /// @param guardiansApproval Indicates whether the upgrade has been approved by the guardians.
    /// @param guardiansExtendedLegalVeto Indicates whether guardians extended the legal veto period.
    /// @param executed Indicates whether the proposal is executed or not.
    struct UpgradeStatus {
        uint48 creationTimestamp;
        uint48 securityCouncilApprovalTimestamp;
        bool guardiansApproval;
        bool guardiansExtendedLegalVeto;
        bool executed;
    }

    /// @dev Represents a call to be made during an upgrade.
    /// @param target The address to which the call will be made.
    /// @param value The amount of Ether (in wei) to be sent along with the call.
    /// @param data The calldata to be executed on the `target` address.
    struct Call {
        address target;
        uint256 value;
        bytes data;
    }

    /// @dev Defines the structure of an upgrade that is executed by Protocol Upgrade Handler.
    /// @param executor The L1 address that is authorized to perform the upgrade execution (if address(0) then anyone).
    /// @param calls An array of `Call` structs, each representing a call to be made during the upgrade execution.
    /// @param salt A bytes32 value used for creating unique upgrade proposal hashes.
    struct UpgradeProposal {
        Call[] calls;
        address executor;
        bytes32 salt;
    }

    /// @dev This enumeration includes the following states:
    /// @param None Default state, indicating the freeze has not been happening in this upgrade cycle.
    /// @param Soft The protocol is/was frozen for the short time.
    /// @param Hard The protocol is/was frozen for the long time.
    /// @param AfterSoftFreeze The protocol was soft frozen, it can be hard frozen in this upgrade cycle.
    /// @param AfterHardFreeze The protocol was hard frozen, but now it can't be frozen until the upgrade.
    enum FreezeStatus {
        None,
        Soft,
        Hard,
        AfterSoftFreeze,
        AfterHardFreeze
    }

    function startUpgrade(
        uint256 _l2BatchNumber,
        uint256 _l2MessageIndex,
        uint16 _l2TxNumberInBatch,
        bytes32[] calldata _proof,
        UpgradeProposal calldata _proposal
    ) external;

    function extendLegalVeto(bytes32 _id) external;

    function approveUpgradeSecurityCouncil(bytes32 _id) external;

    function approveUpgradeGuardians(bytes32 _id) external;

    function execute(UpgradeProposal calldata _proposal) external payable;

    function executeEmergencyUpgrade(UpgradeProposal calldata _proposal) external payable;

    function softFreeze() external;

    function hardFreeze() external;

    function reinforceFreeze() external;

    function unfreeze() external;

    function reinforceFreezeOneChain(uint256 _chainId) external;

    function reinforceUnfreeze() external;

    function reinforceUnfreezeOneChain(uint256 _chainId) external;

    function upgradeState(bytes32 _id) external view returns (UpgradeState);

    function updateSecurityCouncil(address _newSecurityCouncil) external;

    function updateGuardians(address _newGuardians) external;

    function updateEmergencyUpgradeBoard(address _newEmergencyUpgradeBoard) external;

    /// @notice Emitted when the security council address is changed.
    event ChangeSecurityCouncil(address indexed _securityCouncilBefore, address indexed _securityCouncilAfter);

    /// @notice Emitted when the guardians address is changed.
    event ChangeGuardians(address indexed _guardiansBefore, address indexed _guardiansAfter);

    /// @notice Emitted when the emergency upgrade board address is changed.
    event ChangeEmergencyUpgradeBoard(
        address indexed _emergencyUpgradeBoardBefore, address indexed _emergencyUpgradeBoardAfter
    );

    /// @notice Emitted when upgrade process on L1 is started.
    event UpgradeStarted(bytes32 indexed _id, UpgradeProposal _proposal);

    /// @notice Emitted when the legal veto period is extended.
    event UpgradeLegalVetoExtended(bytes32 indexed _id);

    /// @notice Emitted when Security Council approved the upgrade.
    event UpgradeApprovedBySecurityCouncil(bytes32 indexed _id);

    /// @notice Emitted when Guardians approved the upgrade.
    event UpgradeApprovedByGuardians(bytes32 indexed _id);

    /// @notice Emitted when the upgrade is executed.
    event UpgradeExecuted(bytes32 indexed _id);

    /// @notice Emitted when the emergency upgrade is executed.
    event EmergencyUpgradeExecuted(bytes32 indexed _id);

    /// @notice Emitted when the protocol became soft frozen.
    event SoftFreeze(uint256 _protocolFrozenUntil);

    /// @notice Emitted when the protocol became hard frozen.
    event HardFreeze(uint256 _protocolFrozenUntil);

    /// @notice Emitted when someone makes an attempt to freeze the protocol when it is frozen already.
    event ReinforceFreeze();

    /// @notice Emitted when the protocol became active after the soft/hard freeze.
    event Unfreeze();

    /// @notice Emitted when someone makes an attempt to freeze the specific chain when the protocol is frozen already.
    event ReinforceFreezeOneChain(uint256 _chainId);

    /// @notice Emitted when someone makes an attempt to unfreeze the protocol when it is unfrozen already.
    event ReinforceUnfreeze();

    /// @notice Emitted when someone makes an attempt to unfreeze the specific chain when the protocol is unfrozen already.
    event ReinforceUnfreezeOneChain(uint256 _chainId);
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": false,
  "libraries": {}
}

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_securityCouncil","type":"address"},{"internalType":"address","name":"_guardians","type":"address"},{"internalType":"address","name":"_emergencyUpgradeBoard","type":"address"},{"internalType":"address","name":"_l2ProtocolGovernor","type":"address"},{"internalType":"contract IZKsyncEra","name":"_ZKsyncEra","type":"address"},{"internalType":"contract IStateTransitionManager","name":"_stateTransitionManager","type":"address"},{"internalType":"contract IPausable","name":"_bridgeHub","type":"address"},{"internalType":"contract IPausable","name":"_sharedBridge","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":[],"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 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":"SHARED_BRIDGE","outputs":[{"internalType":"contract IPausable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STATE_TRANSITION_MANAGER","outputs":[{"internalType":"contract IStateTransitionManager","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":[],"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"}]

6101206040523480156200001257600080fd5b5060405162002a2c38038062002a2c833981016040819052620000359162000166565b8787878787878787600080546001600160a01b0319166001600160a01b038a1690811782556040519091907fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f5951908290a3600180546001600160a01b0319166001600160a01b0389169081179091556040516000907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d88908290a3600280546001600160a01b0319166001600160a01b0388169081179091556040516000907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d76670908290a36001600160a01b0394851660805292841660a05290831660c052821660e052166101005250620002279950505050505050505050565b6001600160a01b03811681146200016357600080fd5b50565b600080600080600080600080610100898b0312156200018457600080fd5b885162000191816200014d565b60208a0151909850620001a4816200014d565b60408a0151909750620001b7816200014d565b60608a0151909650620001ca816200014d565b60808a0151909550620001dd816200014d565b60a08a0151909450620001f0816200014d565b60c08a015190935062000203816200014d565b60e08a015190925062000216816200014d565b809150509295985092959890939650565b60805160a05160c05160e0516101005161276c620002c06000396000818161032c01528181611afc0152611d0e01526000818161038001528181611a8f0152611ca101526000818161027c0152818161064e015281816108150152818161195d015281816119f301528181611b6f0152611c050152600081816105eb01526110510152600081816102f80152611011015261276c6000f3fe6080604052600436106101bb5760003560e01c806374f5d9d2116100ec578063c54dd6281161008a578063dbfe3e9611610064578063dbfe3e961461056c578063ea3e739b1461058c578063ec1507cb146105ac578063f12913d8146105d957600080fd5b8063c54dd6281461051b578063d370613214610530578063d6f7e8da1461055757600080fd5b80639c5392da116100c65780639c5392da1461042c578063a1dcb9b81461044c578063b429f41c1461045f578063b9d1f21a1461047f57600080fd5b806374f5d9d2146103d75780637aedf337146103f757806384a20db81461041757600080fd5b80634523da36116101595780635a81d4ba116101335780635a81d4ba1461034e5780635d4edca71461036e578063691616c5146103a25780636a28f000146103c257600080fd5b80634523da36146102d35780634717bd36146102e6578063546b6d2a1461031a57600080fd5b806327eb6c0f1161019557806327eb6c0f1461024a5780633083f0c81461026a578063314e6ebe1461029e578063407626b5146102b357600080fd5b80630855b2e1146101c757806308ee01eb146101e95780630ed505a21461022657600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101e76101e2366004611f63565b61060d565b005b3480156101f557600080fd5b50600254610209906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023257600080fd5b5061023c60055481565b60405190815260200161021d565b34801561025657600080fd5b50600054610209906001600160a01b031681565b34801561027657600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b3480156102aa57600080fd5b506101e76106ee565b3480156102bf57600080fd5b506101e76102ce366004611f63565b6107df565b6101e76102e1366004611f94565b6108aa565b3480156102f257600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b34801561032657600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b34801561035a57600080fd5b50600154610209906001600160a01b031681565b34801561037a57600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ae57600080fd5b506101e76103bd366004611fed565b610a92565b3480156103ce57600080fd5b506101e7610b0d565b3480156103e357600080fd5b506101e76103f2366004611f63565b610cb3565b34801561040357600080fd5b506101e7610412366004611fed565b610e3e565b34801561042357600080fd5b506101e7610eb9565b34801561043857600080fd5b506101e761044736600461200f565b610fda565b6101e761045a366004611f94565b6112ad565b34801561046b57600080fd5b506101e761047a366004611f63565b6113fc565b34801561048b57600080fd5b506104e161049a366004611f63565b60036020526000908152604090205465ffffffffffff80821691600160301b81049091169060ff600160601b8204811691600160681b8104821691600160701b9091041685565b6040805165ffffffffffff96871681529590941660208601529115159284019290925290151560608301521515608082015260a00161021d565b34801561052757600080fd5b506101e761156f565b34801561053c57600080fd5b5060045461054a9060ff1681565b60405161021d91906120eb565b34801561056357600080fd5b506101e76115c2565b34801561057857600080fd5b506101e7610587366004611fed565b611617565b34801561059857600080fd5b506101e76105a7366004611f63565b611691565b3480156105b857600080fd5b506105cc6105c7366004611f63565b6117be565b60405161021d9190612105565b3480156105e557600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b6005544211156106385760405162461bcd60e51b815260040161062f90612119565b60405180910390fd5b604051632b33745b60e21b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063accdd16c90602401600060405180830381600087803b15801561069a57600080fd5b505af11580156106ae573d6000803e3d6000fd5b505050507fe2b6c70f0bb14be8c1be3a3875d171dd198b1f9f2d35972501b91c0fc6c1b0ce816040516106e391815260200190565b60405180910390a150565b6000546001600160a01b031633146107185760405162461bcd60e51b815260040161062f9061215a565b60006004805460ff1690811115610731576107316120d5565b1461077e5760405162461bcd60e51b815260206004820152601760248201527f50726f746f636f6c20616c72656164792066726f7a656e000000000000000000604482015260640161062f565b6004805460ff1916600117905561079761a8c0426121b0565b6005556107a2611959565b7f24f7761883b592e1cb80bcb0b5ad54822c7ed844019f3459111f131715d1ecc96005546040516107d591815260200190565b60405180910390a1565b600554156107ff5760405162461bcd60e51b815260040161062f906121d7565b6040516351d218f760e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906351d218f790602401600060405180830381600087803b15801561086157600080fd5b505af1158015610875573d6000803e3d6000fd5b505050507fa938747b1cf8e014275de2758fc8d441002154a94bca459b291cbbbeb0c7c89d816040516106e391815260200190565b6002546001600160a01b0316331461092a5760405162461bcd60e51b815260206004820152603d60248201527f4f6e6c7920456d657267656e6379205570677261646520426f6172642069732060448201527f616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e000000606482015260840161062f565b60008160405160200161093d919061221a565b6040516020818303038152906040528051906020012090506000610960826117be565b90506000816006811115610976576109766120d5565b146109bc5760405162461bcd60e51b81526020600482015260166024820152755570677261646520616c72656164792065786973747360501b604482015260640161062f565b336109cd6040850160208601611fed565b6001600160a01b0316146109f35760405162461bcd60e51b815260040161062f9061237f565b6000828152600360205260408120805460ff60701b1916600160701b1790556004805460ff19169055600555610a27611b6b565b610a39610a3484806123d2565b611d67565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded90600090a160405182907f39f6aeadc0239b46b37917ee1c12e98f9cd3a5dea6c038efa22af67471128e5190600090a2505050565b333014610ab15760405162461bcd60e51b815260040161062f90612423565b6001546040516001600160a01b038084169216907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d8890600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331480610b33575060055415801590610b33575060055442115b610bcb5760405162461bcd60e51b815260206004820152605760248201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f77656460448201527f20746f2063616c6c20746869732066756e6374696f6e206f722074686520707260648201527f6f746f636f6c2073686f756c642062652066726f7a656e000000000000000000608482015260a40161062f565b60016004805460ff1690811115610be457610be46120d5565b03610c0357600480546003919060ff19166001835b0217905550610c7b565b60026004805460ff1690811115610c1c57610c1c6120d5565b03610c335760048054819060ff1916600182610bf9565b60405162461bcd60e51b815260206004820152601d60248201527f556e6578706563746564206c61737420667265657a6520737461747573000000604482015260640161062f565b6000600555610c88611b6b565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded90600090a1565b6001546001600160a01b03163314610cdd5760405162461bcd60e51b815260040161062f9061248e565b600081815260036020526040902054600160601b900460ff1615610d545760405162461bcd60e51b815260206004820152602860248201527f5570677261646520697320616c726561647920617070726f76656420627920676044820152677561726469616e7360c01b606482015260840161062f565b6000610d5f826117be565b90506002816006811115610d7557610d756120d5565b14610df45760405162461bcd60e51b815260206004820152604360248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d20477561726469606482015262616e7360e81b608482015260a40161062f565b600082815260036020526040808220805460ff60601b1916600160601b1790555183917f4bdba07411d36daebbfc1a5062f25d0d02c753374c8498aec76d5954c707682a91a25050565b333014610e5d5760405162461bcd60e51b815260040161062f90612423565b6002546040516001600160a01b038084169216907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d7667090600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610ee35760405162461bcd60e51b815260040161062f9061215a565b60045460ff166000816004811115610efd57610efd6120d5565b1480610f1a57506001816004811115610f1857610f186120d5565b145b80610f3657506003816004811115610f3457610f346120d5565b145b610f825760405162461bcd60e51b815260206004820152601d60248201527f50726f746f636f6c2063616e277420626520686172642066726f7a656e000000604482015260640161062f565b6004805460ff19166002179055610f9c62093a80426121b0565b600555610fa7611959565b7f8cfb4dcbe7dce698c042e43e42e1e496194abadb41ac3756f5793a9c5a8bb3e86005546040516106e391815260200190565b600081604051602001610fed919061221a565b60408051601f1981840301815260608301825261ffff881683526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166020850152838301829052915163e4948f4360e01b81529093506000917f0000000000000000000000000000000000000000000000000000000000000000169063e4948f439061108e908c908c9087908c908c9060040161250f565b602060405180830381865afa1580156110ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110cf91906125b3565b9050806111325760405162461bcd60e51b815260206004820152602b60248201527f4661696c656420746f20636865636b20757067726164652070726f706f73616c60448201526a1034b734ba34b0ba34b7b760a91b606482015260840161062f565b6002546001600160a01b031661114e6040860160208701611fed565b6001600160a01b0316036111c05760405162461bcd60e51b815260206004820152603360248201527f456d657267656e6379205570677261646520426f6172642063616e2774206578604482015272656375746520757375616c207570677261646560681b606482015260840161062f565b8251602084012060006111d2826117be565b905060008160068111156111e8576111e86120d5565b146112415760405162461bcd60e51b815260206004820152602360248201527f557067726164652077697468207468697320696420616c72656164792065786960448201526273747360e81b606482015260840161062f565b60008281526003602052604090819020805465ffffffffffff19164265ffffffffffff161790555182907f71a79729ed8b7db17b27c5dfe0ae24cf41d52b08c8dfc82592fc7db23010c8799061129890899061221a565b60405180910390a25050505050505050505050565b6000816040516020016112c0919061221a565b60405160208183030381529060405280519060200120905060006112e3826117be565b905060048160068111156112f9576112f96120d5565b146113465760405162461bcd60e51b815260206004820152601860248201527f55706772616465206973206e6f74207965742072656164790000000000000000604482015260640161062f565b60006113586040850160208601611fed565b6001600160a01b031614806113845750336113796040850160208601611fed565b6001600160a01b0316145b6113a05760405162461bcd60e51b815260040161062f9061237f565b6000828152600360205260409020805460ff60701b1916600160701b1790556113cc610a3484806123d2565b60405182907ff6224a998aea3de231cf75375faf8c3711379d54bb84c92ef9d9779dabd383a990600090a2505050565b6001546001600160a01b031633146114265760405162461bcd60e51b815260040161062f9061248e565b600081815260036020526040902054600160681b900460ff161561149a5760405162461bcd60e51b815260206004820152602560248201527f4c6567616c207665746f20706572696f6420697320616c726561647920657874604482015264195b99195960da1b606482015260840161062f565b60006114a5826117be565b905060018160068111156114bb576114bb6120d5565b146115255760405162461bcd60e51b815260206004820152603460248201527f5570677261646520776974682074686973206964206973206e6f7420696e20746044820152731a19481b1959d85b081d995d1bc81c195c9a5bd960621b606482015260840161062f565b600082815260036020526040808220805460ff60681b1916600160681b1790555183917f6679375a2761fa72f4163ccf9a92a514bfd3adff8eb1f2f17256f25834dc46ca91a25050565b6005541561158f5760405162461bcd60e51b815260040161062f906121d7565b611597611b6b565b6040517fea592eda90ea1daf1d7577bddc51f4f8425ec0332f0dd8b58aa08f8a2d1da62190600090a1565b6005544211156115e45760405162461bcd60e51b815260040161062f90612119565b6115ec611959565b6040517fbe5088092f32032505342f55f3393029ab55bd4dfcc2edad138d715f485ace6e90600090a1565b3330146116365760405162461bcd60e51b815260040161062f90612423565b600080546040516001600160a01b03808516939216917fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f595191a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146116bb5760405162461bcd60e51b815260040161062f9061215a565b60006116c6826117be565b905060028160068111156116dc576116dc6120d5565b146117625760405162461bcd60e51b815260206004820152604a60248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d205365637572696064820152691d1e4810dbdd5b98da5b60b21b608482015260a40161062f565b60008281526003602052604080822080546bffffffffffff0000000000001916600160301b4265ffffffffffff16021790555183917f4ea0d7cd48461eaf68f428942cdfb19039bd43dc723fa8875c65bec57d911ac491a25050565b6000818152600360209081526040808320815160a081018352905465ffffffffffff8082168352600160301b8204169382019390935260ff600160601b84048116151592820192909252600160681b8304821615156060820152600160701b9092041615801560808301526118365750600692915050565b805165ffffffffffff166000036118505750600092915050565b60008160600151611862576000611867565b62093a805b825190915061187f90829065ffffffffffff166121b0565b421015611890575060019392505050565b602082015165ffffffffffff16156118dc57600062015180836020015165ffffffffffff166118bf91906121b0565b9050804210156118d05760036118d3565b60045b95945050505050565b600062278d0082846000015165ffffffffffff166118fa91906121b0565b61190491906121b0565b905080421061194e57826040015161192157506005949350505050565b600061193062015180836121b0565b905080421015611941576003611944565b60045b9695505050505050565b506002949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a75b496d6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156119b9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119e191908101906125eb565b805190915060005b81811015611a8c577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663accdd16c848381518110611a3257611a326126a9565b60200260200101516040518263ffffffff1660e01b8152600401611a5891815260200190565b600060405180830381600087803b158015611a7257600080fd5b505af1925050508015611a83575060015b506001016119e9565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611ae857600080fd5b505af1925050508015611af9575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b5557600080fd5b505af1925050508015611b66575060015b505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a75b496d6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611bcb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611bf391908101906125eb565b805190915060005b81811015611c9e577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166351d218f7848381518110611c4457611c446126a9565b60200260200101516040518263ffffffff1660e01b8152600401611c6a91815260200190565b600060405180830381600087803b158015611c8457600080fd5b505af1925050508015611c95575060015b50600101611bfb565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611cfa57600080fd5b505af1925050508015611d0b575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b5557600080fd5b60005b81811015611b66576000838383818110611d8657611d866126a9565b9050602002810190611d9891906126bf565b611da69060408101906126df565b90501115611e5f576000838383818110611dc257611dc26126a9565b9050602002810190611dd491906126bf565b611de2906020810190611fed565b6001600160a01b03163b11611e5f5760405162461bcd60e51b815260206004820152603c60248201527f546172676574206d757374206265206120736d61727420636f6e74726163742060448201527f6966207468652063616c6c64617461206973206e6f7420656d70747900000000606482015260840161062f565b600080848484818110611e7457611e746126a9565b9050602002810190611e8691906126bf565b611e94906020810190611fed565b6001600160a01b0316858585818110611eaf57611eaf6126a9565b9050602002810190611ec191906126bf565b60200135868686818110611ed757611ed76126a9565b9050602002810190611ee991906126bf565b611ef79060408101906126df565b604051611f05929190612726565b60006040518083038185875af1925050503d8060008114611f42576040519150601f19603f3d011682016040523d82523d6000602084013e611f47565b606091505b509150915081611f5957805160208201fd5b5050600101611d6a565b600060208284031215611f7557600080fd5b5035919050565b600060608284031215611f8e57600080fd5b50919050565b600060208284031215611fa657600080fd5b813567ffffffffffffffff811115611fbd57600080fd5b611fc984828501611f7c565b949350505050565b80356001600160a01b0381168114611fe857600080fd5b919050565b600060208284031215611fff57600080fd5b61200882611fd1565b9392505050565b60008060008060008060a0878903121561202857600080fd5b8635955060208701359450604087013561ffff8116811461204857600080fd5b9350606087013567ffffffffffffffff8082111561206557600080fd5b818901915089601f83011261207957600080fd5b81358181111561208857600080fd5b8a60208260051b850101111561209d57600080fd5b6020830195508094505060808901359150808211156120bb57600080fd5b506120c889828a01611f7c565b9150509295509295509295565b634e487b7160e01b600052602160045260246000fd5b60208101600583106120ff576120ff6120d5565b91905290565b60208101600783106120ff576120ff6120d5565b60208082526021908201527f50726f746f636f6c2073686f756c6420626520616c72656164792066726f7a656040820152603760f91b606082015260800190565b60208082526036908201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f776564604082015275103a379031b0b636103a3434b990333ab731ba34b7b760511b606082015260800190565b808201808211156121d157634e487b7160e01b600052601160045260246000fd5b92915050565b60208082526023908201527f50726f746f636f6c2073686f756c6420626520616c726561647920756e66726f6040820152623d32b760e91b606082015260800190565b6000602080835260808084018535601e1987360301811261223a57600080fd5b8601803584820167ffffffffffffffff8083111561225757600080fd5b8260051b80360383131561226a57600080fd5b60608a890181905295849052890160a0908101956000918b0136879003607e19015b86841015612345578c8903609f1901825285358181126122ab57600080fd5b88016001600160a01b036122c08d8301611fd1565b168a526040808201358d8c015284820135603e198336030181126122e357600080fd5b90910181810191908d0135878111156122fb57600080fd5b80360383131561230a57600080fd5b85828d015280868d015280838e8e013760008c82018e0152601f01601f1916909a018b01995050948a019460019390930192908a019061228c565b5050505050505050612358838701611fd1565b6001600160a01b038116604087015292506040860135606086015280935050505092915050565b60208082526033908201527f6d73672e73656e646572206973206e6f7420617574686f72697a656420746f20604082015272706572666f726d20746865207570677261646560681b606082015260800190565b6000808335601e198436030181126123e957600080fd5b83018035915067ffffffffffffffff82111561240457600080fd5b6020019150600581901b360382131561241c57600080fd5b9250929050565b60208082526045908201527f4f6e6c7920757067726164652068616e646c657220636f6e747261637420697460408201527f73656c6620697320616c6c6f77656420746f2063616c6c20746869732066756e60608201526431ba34b7b760d91b608082015260a00190565b6020808252602f908201527f4f6e6c7920677561726469616e7320697320616c6c6f77656420746f2063616c60408201526e36103a3434b990333ab731ba34b7b760891b606082015260800190565b81835260006001600160fb1b038311156124f657600080fd5b8260051b80836020870137939093016020019392505050565b858152600060208660208401526080604084015261ffff865116608084015260018060a01b0360208701511660a08401526040860151606060c085015280518060e086015260005b818110156125745782810184015186820161010001528301612557565b5061010092506000838287010152601f19601f8201168501915050818482030160608501526125a682820186886124dd565b9998505050505050505050565b6000602082840312156125c557600080fd5b8151801515811461200857600080fd5b634e487b7160e01b600052604160045260246000fd5b600060208083850312156125fe57600080fd5b825167ffffffffffffffff8082111561261657600080fd5b818501915085601f83011261262a57600080fd5b81518181111561263c5761263c6125d5565b8060051b604051601f19603f83011681018181108582111715612661576126616125d5565b60405291825284820192508381018501918883111561267f57600080fd5b938501935b8285101561269d57845184529385019392850192612684565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e198336030181126126d557600080fd5b9190910192915050565b6000808335601e198436030181126126f657600080fd5b83018035915067ffffffffffffffff82111561271157600080fd5b60200191503681900382131561241c57600080fd5b818382376000910190815291905056fea26469706673582212207bd3cd9dbd80972c1666e1d921ea2e57fd9fe04f91c8a2af7f4c987aa4e10a2464736f6c63430008180033000000000000000000000000541e05fbe96895095e0f4b70865abac70cb12e0e000000000000000000000000e95141dd86828d23c2aa8ed518644af5e4216d79000000000000000000000000fc4cf3248a8f5fba7fa6bd67a3bb43cfc7514e5500000000000000000000000059ef1efe5e031b56a987603cd9cbafba48dd18330000000000000000000000009a6de0f62aa270a8bcb1e2610078650d539b1ef90000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a500000000000000000000000035a54c8c757806eb6820629bc82d90e056394c920000000000000000000000003e8b2fe58675126ed30d0d12dea2a9bda72d18ae

Deployed Bytecode

0x6080604052600436106101bb5760003560e01c806374f5d9d2116100ec578063c54dd6281161008a578063dbfe3e9611610064578063dbfe3e961461056c578063ea3e739b1461058c578063ec1507cb146105ac578063f12913d8146105d957600080fd5b8063c54dd6281461051b578063d370613214610530578063d6f7e8da1461055757600080fd5b80639c5392da116100c65780639c5392da1461042c578063a1dcb9b81461044c578063b429f41c1461045f578063b9d1f21a1461047f57600080fd5b806374f5d9d2146103d75780637aedf337146103f757806384a20db81461041757600080fd5b80634523da36116101595780635a81d4ba116101335780635a81d4ba1461034e5780635d4edca71461036e578063691616c5146103a25780636a28f000146103c257600080fd5b80634523da36146102d35780634717bd36146102e6578063546b6d2a1461031a57600080fd5b806327eb6c0f1161019557806327eb6c0f1461024a5780633083f0c81461026a578063314e6ebe1461029e578063407626b5146102b357600080fd5b80630855b2e1146101c757806308ee01eb146101e95780630ed505a21461022657600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101e76101e2366004611f63565b61060d565b005b3480156101f557600080fd5b50600254610209906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023257600080fd5b5061023c60055481565b60405190815260200161021d565b34801561025657600080fd5b50600054610209906001600160a01b031681565b34801561027657600080fd5b506102097f0000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a581565b3480156102aa57600080fd5b506101e76106ee565b3480156102bf57600080fd5b506101e76102ce366004611f63565b6107df565b6101e76102e1366004611f94565b6108aa565b3480156102f257600080fd5b506102097f00000000000000000000000059ef1efe5e031b56a987603cd9cbafba48dd183381565b34801561032657600080fd5b506102097f0000000000000000000000003e8b2fe58675126ed30d0d12dea2a9bda72d18ae81565b34801561035a57600080fd5b50600154610209906001600160a01b031681565b34801561037a57600080fd5b506102097f00000000000000000000000035a54c8c757806eb6820629bc82d90e056394c9281565b3480156103ae57600080fd5b506101e76103bd366004611fed565b610a92565b3480156103ce57600080fd5b506101e7610b0d565b3480156103e357600080fd5b506101e76103f2366004611f63565b610cb3565b34801561040357600080fd5b506101e7610412366004611fed565b610e3e565b34801561042357600080fd5b506101e7610eb9565b34801561043857600080fd5b506101e761044736600461200f565b610fda565b6101e761045a366004611f94565b6112ad565b34801561046b57600080fd5b506101e761047a366004611f63565b6113fc565b34801561048b57600080fd5b506104e161049a366004611f63565b60036020526000908152604090205465ffffffffffff80821691600160301b81049091169060ff600160601b8204811691600160681b8104821691600160701b9091041685565b6040805165ffffffffffff96871681529590941660208601529115159284019290925290151560608301521515608082015260a00161021d565b34801561052757600080fd5b506101e761156f565b34801561053c57600080fd5b5060045461054a9060ff1681565b60405161021d91906120eb565b34801561056357600080fd5b506101e76115c2565b34801561057857600080fd5b506101e7610587366004611fed565b611617565b34801561059857600080fd5b506101e76105a7366004611f63565b611691565b3480156105b857600080fd5b506105cc6105c7366004611f63565b6117be565b60405161021d9190612105565b3480156105e557600080fd5b506102097f0000000000000000000000009a6de0f62aa270a8bcb1e2610078650d539b1ef981565b6005544211156106385760405162461bcd60e51b815260040161062f90612119565b60405180910390fd5b604051632b33745b60e21b8152600481018290527f0000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a56001600160a01b03169063accdd16c90602401600060405180830381600087803b15801561069a57600080fd5b505af11580156106ae573d6000803e3d6000fd5b505050507fe2b6c70f0bb14be8c1be3a3875d171dd198b1f9f2d35972501b91c0fc6c1b0ce816040516106e391815260200190565b60405180910390a150565b6000546001600160a01b031633146107185760405162461bcd60e51b815260040161062f9061215a565b60006004805460ff1690811115610731576107316120d5565b1461077e5760405162461bcd60e51b815260206004820152601760248201527f50726f746f636f6c20616c72656164792066726f7a656e000000000000000000604482015260640161062f565b6004805460ff1916600117905561079761a8c0426121b0565b6005556107a2611959565b7f24f7761883b592e1cb80bcb0b5ad54822c7ed844019f3459111f131715d1ecc96005546040516107d591815260200190565b60405180910390a1565b600554156107ff5760405162461bcd60e51b815260040161062f906121d7565b6040516351d218f760e01b8152600481018290527f0000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a56001600160a01b0316906351d218f790602401600060405180830381600087803b15801561086157600080fd5b505af1158015610875573d6000803e3d6000fd5b505050507fa938747b1cf8e014275de2758fc8d441002154a94bca459b291cbbbeb0c7c89d816040516106e391815260200190565b6002546001600160a01b0316331461092a5760405162461bcd60e51b815260206004820152603d60248201527f4f6e6c7920456d657267656e6379205570677261646520426f6172642069732060448201527f616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e000000606482015260840161062f565b60008160405160200161093d919061221a565b6040516020818303038152906040528051906020012090506000610960826117be565b90506000816006811115610976576109766120d5565b146109bc5760405162461bcd60e51b81526020600482015260166024820152755570677261646520616c72656164792065786973747360501b604482015260640161062f565b336109cd6040850160208601611fed565b6001600160a01b0316146109f35760405162461bcd60e51b815260040161062f9061237f565b6000828152600360205260408120805460ff60701b1916600160701b1790556004805460ff19169055600555610a27611b6b565b610a39610a3484806123d2565b611d67565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded90600090a160405182907f39f6aeadc0239b46b37917ee1c12e98f9cd3a5dea6c038efa22af67471128e5190600090a2505050565b333014610ab15760405162461bcd60e51b815260040161062f90612423565b6001546040516001600160a01b038084169216907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d8890600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331480610b33575060055415801590610b33575060055442115b610bcb5760405162461bcd60e51b815260206004820152605760248201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f77656460448201527f20746f2063616c6c20746869732066756e6374696f6e206f722074686520707260648201527f6f746f636f6c2073686f756c642062652066726f7a656e000000000000000000608482015260a40161062f565b60016004805460ff1690811115610be457610be46120d5565b03610c0357600480546003919060ff19166001835b0217905550610c7b565b60026004805460ff1690811115610c1c57610c1c6120d5565b03610c335760048054819060ff1916600182610bf9565b60405162461bcd60e51b815260206004820152601d60248201527f556e6578706563746564206c61737420667265657a6520737461747573000000604482015260640161062f565b6000600555610c88611b6b565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded90600090a1565b6001546001600160a01b03163314610cdd5760405162461bcd60e51b815260040161062f9061248e565b600081815260036020526040902054600160601b900460ff1615610d545760405162461bcd60e51b815260206004820152602860248201527f5570677261646520697320616c726561647920617070726f76656420627920676044820152677561726469616e7360c01b606482015260840161062f565b6000610d5f826117be565b90506002816006811115610d7557610d756120d5565b14610df45760405162461bcd60e51b815260206004820152604360248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d20477561726469606482015262616e7360e81b608482015260a40161062f565b600082815260036020526040808220805460ff60601b1916600160601b1790555183917f4bdba07411d36daebbfc1a5062f25d0d02c753374c8498aec76d5954c707682a91a25050565b333014610e5d5760405162461bcd60e51b815260040161062f90612423565b6002546040516001600160a01b038084169216907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d7667090600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610ee35760405162461bcd60e51b815260040161062f9061215a565b60045460ff166000816004811115610efd57610efd6120d5565b1480610f1a57506001816004811115610f1857610f186120d5565b145b80610f3657506003816004811115610f3457610f346120d5565b145b610f825760405162461bcd60e51b815260206004820152601d60248201527f50726f746f636f6c2063616e277420626520686172642066726f7a656e000000604482015260640161062f565b6004805460ff19166002179055610f9c62093a80426121b0565b600555610fa7611959565b7f8cfb4dcbe7dce698c042e43e42e1e496194abadb41ac3756f5793a9c5a8bb3e86005546040516106e391815260200190565b600081604051602001610fed919061221a565b60408051601f1981840301815260608301825261ffff881683526001600160a01b037f00000000000000000000000059ef1efe5e031b56a987603cd9cbafba48dd183381166020850152838301829052915163e4948f4360e01b81529093506000917f0000000000000000000000009a6de0f62aa270a8bcb1e2610078650d539b1ef9169063e4948f439061108e908c908c9087908c908c9060040161250f565b602060405180830381865afa1580156110ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110cf91906125b3565b9050806111325760405162461bcd60e51b815260206004820152602b60248201527f4661696c656420746f20636865636b20757067726164652070726f706f73616c60448201526a1034b734ba34b0ba34b7b760a91b606482015260840161062f565b6002546001600160a01b031661114e6040860160208701611fed565b6001600160a01b0316036111c05760405162461bcd60e51b815260206004820152603360248201527f456d657267656e6379205570677261646520426f6172642063616e2774206578604482015272656375746520757375616c207570677261646560681b606482015260840161062f565b8251602084012060006111d2826117be565b905060008160068111156111e8576111e86120d5565b146112415760405162461bcd60e51b815260206004820152602360248201527f557067726164652077697468207468697320696420616c72656164792065786960448201526273747360e81b606482015260840161062f565b60008281526003602052604090819020805465ffffffffffff19164265ffffffffffff161790555182907f71a79729ed8b7db17b27c5dfe0ae24cf41d52b08c8dfc82592fc7db23010c8799061129890899061221a565b60405180910390a25050505050505050505050565b6000816040516020016112c0919061221a565b60405160208183030381529060405280519060200120905060006112e3826117be565b905060048160068111156112f9576112f96120d5565b146113465760405162461bcd60e51b815260206004820152601860248201527f55706772616465206973206e6f74207965742072656164790000000000000000604482015260640161062f565b60006113586040850160208601611fed565b6001600160a01b031614806113845750336113796040850160208601611fed565b6001600160a01b0316145b6113a05760405162461bcd60e51b815260040161062f9061237f565b6000828152600360205260409020805460ff60701b1916600160701b1790556113cc610a3484806123d2565b60405182907ff6224a998aea3de231cf75375faf8c3711379d54bb84c92ef9d9779dabd383a990600090a2505050565b6001546001600160a01b031633146114265760405162461bcd60e51b815260040161062f9061248e565b600081815260036020526040902054600160681b900460ff161561149a5760405162461bcd60e51b815260206004820152602560248201527f4c6567616c207665746f20706572696f6420697320616c726561647920657874604482015264195b99195960da1b606482015260840161062f565b60006114a5826117be565b905060018160068111156114bb576114bb6120d5565b146115255760405162461bcd60e51b815260206004820152603460248201527f5570677261646520776974682074686973206964206973206e6f7420696e20746044820152731a19481b1959d85b081d995d1bc81c195c9a5bd960621b606482015260840161062f565b600082815260036020526040808220805460ff60681b1916600160681b1790555183917f6679375a2761fa72f4163ccf9a92a514bfd3adff8eb1f2f17256f25834dc46ca91a25050565b6005541561158f5760405162461bcd60e51b815260040161062f906121d7565b611597611b6b565b6040517fea592eda90ea1daf1d7577bddc51f4f8425ec0332f0dd8b58aa08f8a2d1da62190600090a1565b6005544211156115e45760405162461bcd60e51b815260040161062f90612119565b6115ec611959565b6040517fbe5088092f32032505342f55f3393029ab55bd4dfcc2edad138d715f485ace6e90600090a1565b3330146116365760405162461bcd60e51b815260040161062f90612423565b600080546040516001600160a01b03808516939216917fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f595191a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146116bb5760405162461bcd60e51b815260040161062f9061215a565b60006116c6826117be565b905060028160068111156116dc576116dc6120d5565b146117625760405162461bcd60e51b815260206004820152604a60248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d205365637572696064820152691d1e4810dbdd5b98da5b60b21b608482015260a40161062f565b60008281526003602052604080822080546bffffffffffff0000000000001916600160301b4265ffffffffffff16021790555183917f4ea0d7cd48461eaf68f428942cdfb19039bd43dc723fa8875c65bec57d911ac491a25050565b6000818152600360209081526040808320815160a081018352905465ffffffffffff8082168352600160301b8204169382019390935260ff600160601b84048116151592820192909252600160681b8304821615156060820152600160701b9092041615801560808301526118365750600692915050565b805165ffffffffffff166000036118505750600092915050565b60008160600151611862576000611867565b62093a805b825190915061187f90829065ffffffffffff166121b0565b421015611890575060019392505050565b602082015165ffffffffffff16156118dc57600062015180836020015165ffffffffffff166118bf91906121b0565b9050804210156118d05760036118d3565b60045b95945050505050565b600062278d0082846000015165ffffffffffff166118fa91906121b0565b61190491906121b0565b905080421061194e57826040015161192157506005949350505050565b600061193062015180836121b0565b905080421015611941576003611944565b60045b9695505050505050565b506002949350505050565b60007f0000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a56001600160a01b031663a75b496d6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156119b9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119e191908101906125eb565b805190915060005b81811015611a8c577f0000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a56001600160a01b031663accdd16c848381518110611a3257611a326126a9565b60200260200101516040518263ffffffff1660e01b8152600401611a5891815260200190565b600060405180830381600087803b158015611a7257600080fd5b505af1925050508015611a83575060015b506001016119e9565b507f00000000000000000000000035a54c8c757806eb6820629bc82d90e056394c926001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611ae857600080fd5b505af1925050508015611af9575060015b507f0000000000000000000000003e8b2fe58675126ed30d0d12dea2a9bda72d18ae6001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b5557600080fd5b505af1925050508015611b66575060015b505050565b60007f0000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a56001600160a01b031663a75b496d6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611bcb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611bf391908101906125eb565b805190915060005b81811015611c9e577f0000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a56001600160a01b03166351d218f7848381518110611c4457611c446126a9565b60200260200101516040518263ffffffff1660e01b8152600401611c6a91815260200190565b600060405180830381600087803b158015611c8457600080fd5b505af1925050508015611c95575060015b50600101611bfb565b507f00000000000000000000000035a54c8c757806eb6820629bc82d90e056394c926001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611cfa57600080fd5b505af1925050508015611d0b575060015b507f0000000000000000000000003e8b2fe58675126ed30d0d12dea2a9bda72d18ae6001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b5557600080fd5b60005b81811015611b66576000838383818110611d8657611d866126a9565b9050602002810190611d9891906126bf565b611da69060408101906126df565b90501115611e5f576000838383818110611dc257611dc26126a9565b9050602002810190611dd491906126bf565b611de2906020810190611fed565b6001600160a01b03163b11611e5f5760405162461bcd60e51b815260206004820152603c60248201527f546172676574206d757374206265206120736d61727420636f6e74726163742060448201527f6966207468652063616c6c64617461206973206e6f7420656d70747900000000606482015260840161062f565b600080848484818110611e7457611e746126a9565b9050602002810190611e8691906126bf565b611e94906020810190611fed565b6001600160a01b0316858585818110611eaf57611eaf6126a9565b9050602002810190611ec191906126bf565b60200135868686818110611ed757611ed76126a9565b9050602002810190611ee991906126bf565b611ef79060408101906126df565b604051611f05929190612726565b60006040518083038185875af1925050503d8060008114611f42576040519150601f19603f3d011682016040523d82523d6000602084013e611f47565b606091505b509150915081611f5957805160208201fd5b5050600101611d6a565b600060208284031215611f7557600080fd5b5035919050565b600060608284031215611f8e57600080fd5b50919050565b600060208284031215611fa657600080fd5b813567ffffffffffffffff811115611fbd57600080fd5b611fc984828501611f7c565b949350505050565b80356001600160a01b0381168114611fe857600080fd5b919050565b600060208284031215611fff57600080fd5b61200882611fd1565b9392505050565b60008060008060008060a0878903121561202857600080fd5b8635955060208701359450604087013561ffff8116811461204857600080fd5b9350606087013567ffffffffffffffff8082111561206557600080fd5b818901915089601f83011261207957600080fd5b81358181111561208857600080fd5b8a60208260051b850101111561209d57600080fd5b6020830195508094505060808901359150808211156120bb57600080fd5b506120c889828a01611f7c565b9150509295509295509295565b634e487b7160e01b600052602160045260246000fd5b60208101600583106120ff576120ff6120d5565b91905290565b60208101600783106120ff576120ff6120d5565b60208082526021908201527f50726f746f636f6c2073686f756c6420626520616c72656164792066726f7a656040820152603760f91b606082015260800190565b60208082526036908201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f776564604082015275103a379031b0b636103a3434b990333ab731ba34b7b760511b606082015260800190565b808201808211156121d157634e487b7160e01b600052601160045260246000fd5b92915050565b60208082526023908201527f50726f746f636f6c2073686f756c6420626520616c726561647920756e66726f6040820152623d32b760e91b606082015260800190565b6000602080835260808084018535601e1987360301811261223a57600080fd5b8601803584820167ffffffffffffffff8083111561225757600080fd5b8260051b80360383131561226a57600080fd5b60608a890181905295849052890160a0908101956000918b0136879003607e19015b86841015612345578c8903609f1901825285358181126122ab57600080fd5b88016001600160a01b036122c08d8301611fd1565b168a526040808201358d8c015284820135603e198336030181126122e357600080fd5b90910181810191908d0135878111156122fb57600080fd5b80360383131561230a57600080fd5b85828d015280868d015280838e8e013760008c82018e0152601f01601f1916909a018b01995050948a019460019390930192908a019061228c565b5050505050505050612358838701611fd1565b6001600160a01b038116604087015292506040860135606086015280935050505092915050565b60208082526033908201527f6d73672e73656e646572206973206e6f7420617574686f72697a656420746f20604082015272706572666f726d20746865207570677261646560681b606082015260800190565b6000808335601e198436030181126123e957600080fd5b83018035915067ffffffffffffffff82111561240457600080fd5b6020019150600581901b360382131561241c57600080fd5b9250929050565b60208082526045908201527f4f6e6c7920757067726164652068616e646c657220636f6e747261637420697460408201527f73656c6620697320616c6c6f77656420746f2063616c6c20746869732066756e60608201526431ba34b7b760d91b608082015260a00190565b6020808252602f908201527f4f6e6c7920677561726469616e7320697320616c6c6f77656420746f2063616c60408201526e36103a3434b990333ab731ba34b7b760891b606082015260800190565b81835260006001600160fb1b038311156124f657600080fd5b8260051b80836020870137939093016020019392505050565b858152600060208660208401526080604084015261ffff865116608084015260018060a01b0360208701511660a08401526040860151606060c085015280518060e086015260005b818110156125745782810184015186820161010001528301612557565b5061010092506000838287010152601f19601f8201168501915050818482030160608501526125a682820186886124dd565b9998505050505050505050565b6000602082840312156125c557600080fd5b8151801515811461200857600080fd5b634e487b7160e01b600052604160045260246000fd5b600060208083850312156125fe57600080fd5b825167ffffffffffffffff8082111561261657600080fd5b818501915085601f83011261262a57600080fd5b81518181111561263c5761263c6125d5565b8060051b604051601f19603f83011681018181108582111715612661576126616125d5565b60405291825284820192508381018501918883111561267f57600080fd5b938501935b8285101561269d57845184529385019392850192612684565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e198336030181126126d557600080fd5b9190910192915050565b6000808335601e198436030181126126f657600080fd5b83018035915067ffffffffffffffff82111561271157600080fd5b60200191503681900382131561241c57600080fd5b818382376000910190815291905056fea26469706673582212207bd3cd9dbd80972c1666e1d921ea2e57fd9fe04f91c8a2af7f4c987aa4e10a2464736f6c63430008180033

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

000000000000000000000000541e05fbe96895095e0f4b70865abac70cb12e0e000000000000000000000000e95141dd86828d23c2aa8ed518644af5e4216d79000000000000000000000000fc4cf3248a8f5fba7fa6bd67a3bb43cfc7514e5500000000000000000000000059ef1efe5e031b56a987603cd9cbafba48dd18330000000000000000000000009a6de0f62aa270a8bcb1e2610078650d539b1ef90000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a500000000000000000000000035a54c8c757806eb6820629bc82d90e056394c920000000000000000000000003e8b2fe58675126ed30d0d12dea2a9bda72d18ae

-----Decoded View---------------
Arg [0] : _securityCouncil (address): 0x541E05fbe96895095E0f4b70865AbaC70cb12e0e
Arg [1] : _guardians (address): 0xe95141dd86828D23c2aA8Ed518644Af5e4216D79
Arg [2] : _emergencyUpgradeBoard (address): 0xfC4cf3248A8f5fbA7Fa6bD67a3BB43cfc7514e55
Arg [3] : _l2ProtocolGovernor (address): 0x59EF1efe5e031b56a987603cD9CBAfBA48Dd1833
Arg [4] : _ZKsyncEra (address): 0x9A6DE0f62Aa270A8bCB1e2610078650D539B1Ef9
Arg [5] : _stateTransitionManager (address): 0x4e39E90746A9ee410A8Ce173C7B96D3AfEd444a5
Arg [6] : _bridgeHub (address): 0x35A54c8C757806eB6820629bc82d90E056394C92
Arg [7] : _sharedBridge (address): 0x3E8b2fe58675126ed30d0d12dea2A9bda72D18Ae

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000541e05fbe96895095e0f4b70865abac70cb12e0e
Arg [1] : 000000000000000000000000e95141dd86828d23c2aa8ed518644af5e4216d79
Arg [2] : 000000000000000000000000fc4cf3248a8f5fba7fa6bd67a3bb43cfc7514e55
Arg [3] : 00000000000000000000000059ef1efe5e031b56a987603cd9cbafba48dd1833
Arg [4] : 0000000000000000000000009a6de0f62aa270a8bcb1e2610078650d539b1ef9
Arg [5] : 0000000000000000000000004e39e90746a9ee410a8ce173c7b96d3afed444a5
Arg [6] : 00000000000000000000000035a54c8c757806eb6820629bc82d90e056394c92
Arg [7] : 0000000000000000000000003e8b2fe58675126ed30d0d12dea2a9bda72d18ae


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
0x9B956d242e6806044877C7C1B530D475E371d544
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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