ETH Price: $3,196.13 (-1.54%)

Contract

0x8f7a9912416e8AdC4D9c21FAe1415D3318A11897
 

Overview

ETH Balance

0.060133333332 ETH

Eth Value

$192.19 (@ $3,196.13/ETH)

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Execute219973302025-03-07 20:16:59254 days ago1741378619IN
0x8f7a9912...318A11897
0 ETH0.002232542.17997708
Start Upgrade219447822025-02-28 12:16:23261 days ago1740744983IN
0x8f7a9912...318A11897
0 ETH0.00049342.40610274
Start Upgrade217243382025-01-28 16:53:11292 days ago1738083191IN
0x8f7a9912...318A11897
0 ETH0.0010716412.38166799
Execute215808142025-01-08 16:00:35312 days ago1736352035IN
0x8f7a9912...318A11897
0 ETH0.0123677714.28960814
Transfer215808062025-01-08 15:58:59312 days ago1736351939IN
0x8f7a9912...318A11897
0.2 ETH0.0003050714.48958089
Start Upgrade215446212025-01-03 14:41:59317 days ago1735915319IN
0x8f7a9912...318A11897
0 ETH0.0029398226.14175089
Start Upgrade215446192025-01-03 14:41:35317 days ago1735915295IN
0x8f7a9912...318A11897
0 ETH0.0029069326.87223737
Start Upgrade215446092025-01-03 14:39:35317 days ago1735915175IN
0x8f7a9912...318A11897
0 ETH0.0028571825.06342874
Start Upgrade215445912025-01-03 14:35:59317 days ago1735914959IN
0x8f7a9912...318A11897
0 ETH0.002398122.17594546
Start Upgrade215445822025-01-03 14:34:11317 days ago1735914851IN
0x8f7a9912...318A11897
0 ETH0.0092263520.98663406

Latest 11 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Request L2Transa...219973302025-03-07 20:16:59254 days ago1741378619
0x8f7a9912...318A11897
0.0159 ETH
Request L2Transa...219973302025-03-07 20:16:59254 days ago1741378619
0x8f7a9912...318A11897
0.0159 ETH
Request L2Transa...219973302025-03-07 20:16:59254 days ago1741378619
0x8f7a9912...318A11897
0.0159 ETH
Request L2Transa...219973302025-03-07 20:16:59254 days ago1741378619
0x8f7a9912...318A11897
0.0159 ETH
Request L2Transa...219973302025-03-07 20:16:59254 days ago1741378619
0x8f7a9912...318A11897
0.0159 ETH
Request L2Transa...219973302025-03-07 20:16:59254 days ago1741378619
0x8f7a9912...318A11897
0.0159 ETH
Request L2Transa...219973302025-03-07 20:16:59254 days ago1741378619
0x8f7a9912...318A11897
0.0159 ETH
Request L2Transa...219973302025-03-07 20:16:59254 days ago1741378619
0x8f7a9912...318A11897
0.0159 ETH
Request L2Transa...215808142025-01-08 16:00:35312 days ago1736352035
0x8f7a9912...318A11897
0.00633333 ETH
Request L2Transa...215808142025-01-08 16:00:35312 days ago1736352035
0x8f7a9912...318A11897
0.00633333 ETH
0x61012060204860232024-08-08 19:40:59465 days ago1723146059  Contract Creation0 ETH
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code Verified (Exact Match)

Contract Name:
ProtocolUpgradeHandler

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
// 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 Security Audit

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"}]

6101206040523480156200001257600080fd5b5060405162002a1e38038062002a1e833981016040819052620000359162000156565b600080546001600160a01b0319166001600160a01b038a1690811782556040519091907fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f5951908290a3600180546001600160a01b0319166001600160a01b0389169081179091556040516000907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d88908290a3600280546001600160a01b0319166001600160a01b0388169081179091556040516000907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d76670908290a36001600160a01b0394851660805292841660a05290831660c052821660e05216610100525062000217915050565b6001600160a01b03811681146200015357600080fd5b50565b600080600080600080600080610100898b0312156200017457600080fd5b885162000181816200013d565b60208a015190985062000194816200013d565b60408a0151909750620001a7816200013d565b60608a0151909650620001ba816200013d565b60808a0151909550620001cd816200013d565b60a08a0151909450620001e0816200013d565b60c08a0151909350620001f3816200013d565b60e08a015190925062000206816200013d565b809150509295985092959890939650565b60805160a05160c05160e0516101005161276e620002b06000396000818161032c01528181611afe0152611d1001526000818161038001528181611a910152611ca301526000818161027c0152818161064e015281816108150152818161195f015281816119f501528181611b710152611c070152600081816105eb01526110510152600081816102f80152611011015261276e6000f3fe6080604052600436106101bb5760003560e01c806374f5d9d2116100ec578063c54dd6281161008a578063dbfe3e9611610064578063dbfe3e961461056c578063ea3e739b1461058c578063ec1507cb146105ac578063f12913d8146105d957600080fd5b8063c54dd6281461051b578063d370613214610530578063d6f7e8da1461055757600080fd5b80639c5392da116100c65780639c5392da1461042c578063a1dcb9b81461044c578063b429f41c1461045f578063b9d1f21a1461047f57600080fd5b806374f5d9d2146103d75780637aedf337146103f757806384a20db81461041757600080fd5b80634523da36116101595780635a81d4ba116101335780635a81d4ba1461034e5780635d4edca71461036e578063691616c5146103a25780636a28f000146103c257600080fd5b80634523da36146102d35780634717bd36146102e6578063546b6d2a1461031a57600080fd5b806327eb6c0f1161019557806327eb6c0f1461024a5780633083f0c81461026a578063314e6ebe1461029e578063407626b5146102b357600080fd5b80630855b2e1146101c757806308ee01eb146101e95780630ed505a21461022657600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101e76101e2366004611f65565b61060d565b005b3480156101f557600080fd5b50600254610209906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023257600080fd5b5061023c60055481565b60405190815260200161021d565b34801561025657600080fd5b50600054610209906001600160a01b031681565b34801561027657600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b3480156102aa57600080fd5b506101e76106ee565b3480156102bf57600080fd5b506101e76102ce366004611f65565b6107df565b6101e76102e1366004611f96565b6108aa565b3480156102f257600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b34801561032657600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b34801561035a57600080fd5b50600154610209906001600160a01b031681565b34801561037a57600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ae57600080fd5b506101e76103bd366004611fef565b610a92565b3480156103ce57600080fd5b506101e7610b0d565b3480156103e357600080fd5b506101e76103f2366004611f65565b610cb3565b34801561040357600080fd5b506101e7610412366004611fef565b610e3e565b34801561042357600080fd5b506101e7610eb9565b34801561043857600080fd5b506101e7610447366004612011565b610fda565b6101e761045a366004611f96565b6112ad565b34801561046b57600080fd5b506101e761047a366004611f65565b6113fc565b34801561048b57600080fd5b506104e161049a366004611f65565b60036020526000908152604090205465ffffffffffff80821691600160301b81049091169060ff600160601b8204811691600160681b8104821691600160701b9091041685565b6040805165ffffffffffff96871681529590941660208601529115159284019290925290151560608301521515608082015260a00161021d565b34801561052757600080fd5b506101e761156f565b34801561053c57600080fd5b5060045461054a9060ff1681565b60405161021d91906120ed565b34801561056357600080fd5b506101e76115c2565b34801561057857600080fd5b506101e7610587366004611fef565b611617565b34801561059857600080fd5b506101e76105a7366004611f65565b611691565b3480156105b857600080fd5b506105cc6105c7366004611f65565b6117be565b60405161021d9190612107565b3480156105e557600080fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b6005544211156106385760405162461bcd60e51b815260040161062f9061211b565b60405180910390fd5b604051632b33745b60e21b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063accdd16c90602401600060405180830381600087803b15801561069a57600080fd5b505af11580156106ae573d6000803e3d6000fd5b505050507fe2b6c70f0bb14be8c1be3a3875d171dd198b1f9f2d35972501b91c0fc6c1b0ce816040516106e391815260200190565b60405180910390a150565b6000546001600160a01b031633146107185760405162461bcd60e51b815260040161062f9061215c565b60006004805460ff1690811115610731576107316120d7565b1461077e5760405162461bcd60e51b815260206004820152601760248201527f50726f746f636f6c20616c72656164792066726f7a656e000000000000000000604482015260640161062f565b6004805460ff1916600117905561079761a8c0426121b2565b6005556107a261195b565b7f24f7761883b592e1cb80bcb0b5ad54822c7ed844019f3459111f131715d1ecc96005546040516107d591815260200190565b60405180910390a1565b600554156107ff5760405162461bcd60e51b815260040161062f906121d9565b6040516351d218f760e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906351d218f790602401600060405180830381600087803b15801561086157600080fd5b505af1158015610875573d6000803e3d6000fd5b505050507fa938747b1cf8e014275de2758fc8d441002154a94bca459b291cbbbeb0c7c89d816040516106e391815260200190565b6002546001600160a01b0316331461092a5760405162461bcd60e51b815260206004820152603d60248201527f4f6e6c7920456d657267656e6379205570677261646520426f6172642069732060448201527f616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e000000606482015260840161062f565b60008160405160200161093d919061221c565b6040516020818303038152906040528051906020012090506000610960826117be565b90506000816006811115610976576109766120d7565b146109bc5760405162461bcd60e51b81526020600482015260166024820152755570677261646520616c72656164792065786973747360501b604482015260640161062f565b336109cd6040850160208601611fef565b6001600160a01b0316146109f35760405162461bcd60e51b815260040161062f90612381565b6000828152600360205260408120805460ff60701b1916600160701b1790556004805460ff19169055600555610a27611b6d565b610a39610a3484806123d4565b611d69565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded90600090a160405182907f39f6aeadc0239b46b37917ee1c12e98f9cd3a5dea6c038efa22af67471128e5190600090a2505050565b333014610ab15760405162461bcd60e51b815260040161062f90612425565b6001546040516001600160a01b038084169216907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d8890600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331480610b33575060055415801590610b33575060055442115b610bcb5760405162461bcd60e51b815260206004820152605760248201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f77656460448201527f20746f2063616c6c20746869732066756e6374696f6e206f722074686520707260648201527f6f746f636f6c2073686f756c642062652066726f7a656e000000000000000000608482015260a40161062f565b60016004805460ff1690811115610be457610be46120d7565b03610c0357600480546003919060ff19166001835b0217905550610c7b565b60026004805460ff1690811115610c1c57610c1c6120d7565b03610c335760048054819060ff1916600182610bf9565b60405162461bcd60e51b815260206004820152601d60248201527f556e6578706563746564206c61737420667265657a6520737461747573000000604482015260640161062f565b6000600555610c88611b6d565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded90600090a1565b6001546001600160a01b03163314610cdd5760405162461bcd60e51b815260040161062f90612490565b600081815260036020526040902054600160601b900460ff1615610d545760405162461bcd60e51b815260206004820152602860248201527f5570677261646520697320616c726561647920617070726f76656420627920676044820152677561726469616e7360c01b606482015260840161062f565b6000610d5f826117be565b90506002816006811115610d7557610d756120d7565b14610df45760405162461bcd60e51b815260206004820152604360248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d20477561726469606482015262616e7360e81b608482015260a40161062f565b600082815260036020526040808220805460ff60601b1916600160601b1790555183917f4bdba07411d36daebbfc1a5062f25d0d02c753374c8498aec76d5954c707682a91a25050565b333014610e5d5760405162461bcd60e51b815260040161062f90612425565b6002546040516001600160a01b038084169216907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d7667090600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610ee35760405162461bcd60e51b815260040161062f9061215c565b60045460ff166000816004811115610efd57610efd6120d7565b1480610f1a57506001816004811115610f1857610f186120d7565b145b80610f3657506003816004811115610f3457610f346120d7565b145b610f825760405162461bcd60e51b815260206004820152601d60248201527f50726f746f636f6c2063616e277420626520686172642066726f7a656e000000604482015260640161062f565b6004805460ff19166002179055610f9c62093a80426121b2565b600555610fa761195b565b7f8cfb4dcbe7dce698c042e43e42e1e496194abadb41ac3756f5793a9c5a8bb3e86005546040516106e391815260200190565b600081604051602001610fed919061221c565b60408051601f1981840301815260608301825261ffff881683526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166020850152838301829052915163e4948f4360e01b81529093506000917f0000000000000000000000000000000000000000000000000000000000000000169063e4948f439061108e908c908c9087908c908c90600401612511565b602060405180830381865afa1580156110ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110cf91906125b5565b9050806111325760405162461bcd60e51b815260206004820152602b60248201527f4661696c656420746f20636865636b20757067726164652070726f706f73616c60448201526a1034b734ba34b0ba34b7b760a91b606482015260840161062f565b6002546001600160a01b031661114e6040860160208701611fef565b6001600160a01b0316036111c05760405162461bcd60e51b815260206004820152603360248201527f456d657267656e6379205570677261646520426f6172642063616e2774206578604482015272656375746520757375616c207570677261646560681b606482015260840161062f565b8251602084012060006111d2826117be565b905060008160068111156111e8576111e86120d7565b146112415760405162461bcd60e51b815260206004820152602360248201527f557067726164652077697468207468697320696420616c72656164792065786960448201526273747360e81b606482015260840161062f565b60008281526003602052604090819020805465ffffffffffff19164265ffffffffffff161790555182907f71a79729ed8b7db17b27c5dfe0ae24cf41d52b08c8dfc82592fc7db23010c8799061129890899061221c565b60405180910390a25050505050505050505050565b6000816040516020016112c0919061221c565b60405160208183030381529060405280519060200120905060006112e3826117be565b905060048160068111156112f9576112f96120d7565b146113465760405162461bcd60e51b815260206004820152601860248201527f55706772616465206973206e6f74207965742072656164790000000000000000604482015260640161062f565b60006113586040850160208601611fef565b6001600160a01b031614806113845750336113796040850160208601611fef565b6001600160a01b0316145b6113a05760405162461bcd60e51b815260040161062f90612381565b6000828152600360205260409020805460ff60701b1916600160701b1790556113cc610a3484806123d4565b60405182907ff6224a998aea3de231cf75375faf8c3711379d54bb84c92ef9d9779dabd383a990600090a2505050565b6001546001600160a01b031633146114265760405162461bcd60e51b815260040161062f90612490565b600081815260036020526040902054600160681b900460ff161561149a5760405162461bcd60e51b815260206004820152602560248201527f4c6567616c207665746f20706572696f6420697320616c726561647920657874604482015264195b99195960da1b606482015260840161062f565b60006114a5826117be565b905060018160068111156114bb576114bb6120d7565b146115255760405162461bcd60e51b815260206004820152603460248201527f5570677261646520776974682074686973206964206973206e6f7420696e20746044820152731a19481b1959d85b081d995d1bc81c195c9a5bd960621b606482015260840161062f565b600082815260036020526040808220805460ff60681b1916600160681b1790555183917f6679375a2761fa72f4163ccf9a92a514bfd3adff8eb1f2f17256f25834dc46ca91a25050565b6005541561158f5760405162461bcd60e51b815260040161062f906121d9565b611597611b6d565b6040517fea592eda90ea1daf1d7577bddc51f4f8425ec0332f0dd8b58aa08f8a2d1da62190600090a1565b6005544211156115e45760405162461bcd60e51b815260040161062f9061211b565b6115ec61195b565b6040517fbe5088092f32032505342f55f3393029ab55bd4dfcc2edad138d715f485ace6e90600090a1565b3330146116365760405162461bcd60e51b815260040161062f90612425565b600080546040516001600160a01b03808516939216917fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f595191a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146116bb5760405162461bcd60e51b815260040161062f9061215c565b60006116c6826117be565b905060028160068111156116dc576116dc6120d7565b146117625760405162461bcd60e51b815260206004820152604a60248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d205365637572696064820152691d1e4810dbdd5b98da5b60b21b608482015260a40161062f565b60008281526003602052604080822080546bffffffffffff0000000000001916600160301b4265ffffffffffff16021790555183917f4ea0d7cd48461eaf68f428942cdfb19039bd43dc723fa8875c65bec57d911ac491a25050565b6000818152600360209081526040808320815160a081018352905465ffffffffffff8082168352600160301b8204169382019390935260ff600160601b84048116151592820192909252600160681b8304821615156060820152600160701b9092041615801560808301526118365750600692915050565b805165ffffffffffff166000036118505750600092915050565b60008160600151611864576203f480611869565b62093a805b825190915061188190829065ffffffffffff166121b2565b421015611892575060019392505050565b602082015165ffffffffffff16156118de57600062015180836020015165ffffffffffff166118c191906121b2565b9050804210156118d25760036118d5565b60045b95945050505050565b600062278d0082846000015165ffffffffffff166118fc91906121b2565b61190691906121b2565b905080421061195057826040015161192357506005949350505050565b600061193262015180836121b2565b905080421015611943576003611946565b60045b9695505050505050565b506002949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a75b496d6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156119bb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119e391908101906125ed565b805190915060005b81811015611a8e577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663accdd16c848381518110611a3457611a346126ab565b60200260200101516040518263ffffffff1660e01b8152600401611a5a91815260200190565b600060405180830381600087803b158015611a7457600080fd5b505af1925050508015611a85575060015b506001016119eb565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611aea57600080fd5b505af1925050508015611afb575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b5757600080fd5b505af1925050508015611b68575060015b505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a75b496d6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611bcd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611bf591908101906125ed565b805190915060005b81811015611ca0577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166351d218f7848381518110611c4657611c466126ab565b60200260200101516040518263ffffffff1660e01b8152600401611c6c91815260200190565b600060405180830381600087803b158015611c8657600080fd5b505af1925050508015611c97575060015b50600101611bfd565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611cfc57600080fd5b505af1925050508015611d0d575060015b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b5757600080fd5b60005b81811015611b68576000838383818110611d8857611d886126ab565b9050602002810190611d9a91906126c1565b611da89060408101906126e1565b90501115611e61576000838383818110611dc457611dc46126ab565b9050602002810190611dd691906126c1565b611de4906020810190611fef565b6001600160a01b03163b11611e615760405162461bcd60e51b815260206004820152603c60248201527f546172676574206d757374206265206120736d61727420636f6e74726163742060448201527f6966207468652063616c6c64617461206973206e6f7420656d70747900000000606482015260840161062f565b600080848484818110611e7657611e766126ab565b9050602002810190611e8891906126c1565b611e96906020810190611fef565b6001600160a01b0316858585818110611eb157611eb16126ab565b9050602002810190611ec391906126c1565b60200135868686818110611ed957611ed96126ab565b9050602002810190611eeb91906126c1565b611ef99060408101906126e1565b604051611f07929190612728565b60006040518083038185875af1925050503d8060008114611f44576040519150601f19603f3d011682016040523d82523d6000602084013e611f49565b606091505b509150915081611f5b57805160208201fd5b5050600101611d6c565b600060208284031215611f7757600080fd5b5035919050565b600060608284031215611f9057600080fd5b50919050565b600060208284031215611fa857600080fd5b813567ffffffffffffffff811115611fbf57600080fd5b611fcb84828501611f7e565b949350505050565b80356001600160a01b0381168114611fea57600080fd5b919050565b60006020828403121561200157600080fd5b61200a82611fd3565b9392505050565b60008060008060008060a0878903121561202a57600080fd5b8635955060208701359450604087013561ffff8116811461204a57600080fd5b9350606087013567ffffffffffffffff8082111561206757600080fd5b818901915089601f83011261207b57600080fd5b81358181111561208a57600080fd5b8a60208260051b850101111561209f57600080fd5b6020830195508094505060808901359150808211156120bd57600080fd5b506120ca89828a01611f7e565b9150509295509295509295565b634e487b7160e01b600052602160045260246000fd5b6020810160058310612101576121016120d7565b91905290565b6020810160078310612101576121016120d7565b60208082526021908201527f50726f746f636f6c2073686f756c6420626520616c72656164792066726f7a656040820152603760f91b606082015260800190565b60208082526036908201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f776564604082015275103a379031b0b636103a3434b990333ab731ba34b7b760511b606082015260800190565b808201808211156121d357634e487b7160e01b600052601160045260246000fd5b92915050565b60208082526023908201527f50726f746f636f6c2073686f756c6420626520616c726561647920756e66726f6040820152623d32b760e91b606082015260800190565b6000602080835260808084018535601e1987360301811261223c57600080fd5b8601803584820167ffffffffffffffff8083111561225957600080fd5b8260051b80360383131561226c57600080fd5b60608a890181905295849052890160a0908101956000918b0136879003607e19015b86841015612347578c8903609f1901825285358181126122ad57600080fd5b88016001600160a01b036122c28d8301611fd3565b168a526040808201358d8c015284820135603e198336030181126122e557600080fd5b90910181810191908d0135878111156122fd57600080fd5b80360383131561230c57600080fd5b85828d015280868d015280838e8e013760008c82018e0152601f01601f1916909a018b01995050948a019460019390930192908a019061228e565b505050505050505061235a838701611fd3565b6001600160a01b038116604087015292506040860135606086015280935050505092915050565b60208082526033908201527f6d73672e73656e646572206973206e6f7420617574686f72697a656420746f20604082015272706572666f726d20746865207570677261646560681b606082015260800190565b6000808335601e198436030181126123eb57600080fd5b83018035915067ffffffffffffffff82111561240657600080fd5b6020019150600581901b360382131561241e57600080fd5b9250929050565b60208082526045908201527f4f6e6c7920757067726164652068616e646c657220636f6e747261637420697460408201527f73656c6620697320616c6c6f77656420746f2063616c6c20746869732066756e60608201526431ba34b7b760d91b608082015260a00190565b6020808252602f908201527f4f6e6c7920677561726469616e7320697320616c6c6f77656420746f2063616c60408201526e36103a3434b990333ab731ba34b7b760891b606082015260800190565b81835260006001600160fb1b038311156124f857600080fd5b8260051b80836020870137939093016020019392505050565b858152600060208660208401526080604084015261ffff865116608084015260018060a01b0360208701511660a08401526040860151606060c085015280518060e086015260005b818110156125765782810184015186820161010001528301612559565b5061010092506000838287010152601f19601f8201168501915050818482030160608501526125a882820186886124df565b9998505050505050505050565b6000602082840312156125c757600080fd5b8151801515811461200a57600080fd5b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561260057600080fd5b825167ffffffffffffffff8082111561261857600080fd5b818501915085601f83011261262c57600080fd5b81518181111561263e5761263e6125d7565b8060051b604051601f19603f83011681018181108582111715612663576126636125d7565b60405291825284820192508381018501918883111561268157600080fd5b938501935b8285101561269f57845184529385019392850192612686565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e198336030181126126d757600080fd5b9190910192915050565b6000808335601e198436030181126126f857600080fd5b83018035915067ffffffffffffffff82111561271357600080fd5b60200191503681900382131561241e57600080fd5b818382376000910190815291905056fea2646970667358221220c748916f9d47ab75cae280a60f2cd17b90aee0eb8988c987ab8af7d1b9980ceb64736f6c63430008180033000000000000000000000000bdffcc71fe84020238f2990a6d2954e87355de0d000000000000000000000000d677e09324f8bb3cc64f009973693f751c33a888000000000000000000000000defd1edee3e8c5965216bd59c866f7f5307c9b290000000000000000000000003701fb675bcd4a85eb11a2467628bbe193f6e6a800000000000000000000000032400084c286cf3e17e7b677ea9583e60a000324000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb5213000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb

Deployed Bytecode

0x6080604052600436106101bb5760003560e01c806374f5d9d2116100ec578063c54dd6281161008a578063dbfe3e9611610064578063dbfe3e961461056c578063ea3e739b1461058c578063ec1507cb146105ac578063f12913d8146105d957600080fd5b8063c54dd6281461051b578063d370613214610530578063d6f7e8da1461055757600080fd5b80639c5392da116100c65780639c5392da1461042c578063a1dcb9b81461044c578063b429f41c1461045f578063b9d1f21a1461047f57600080fd5b806374f5d9d2146103d75780637aedf337146103f757806384a20db81461041757600080fd5b80634523da36116101595780635a81d4ba116101335780635a81d4ba1461034e5780635d4edca71461036e578063691616c5146103a25780636a28f000146103c257600080fd5b80634523da36146102d35780634717bd36146102e6578063546b6d2a1461031a57600080fd5b806327eb6c0f1161019557806327eb6c0f1461024a5780633083f0c81461026a578063314e6ebe1461029e578063407626b5146102b357600080fd5b80630855b2e1146101c757806308ee01eb146101e95780630ed505a21461022657600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101e76101e2366004611f65565b61060d565b005b3480156101f557600080fd5b50600254610209906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023257600080fd5b5061023c60055481565b60405190815260200161021d565b34801561025657600080fd5b50600054610209906001600160a01b031681565b34801561027657600080fd5b506102097f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c81565b3480156102aa57600080fd5b506101e76106ee565b3480156102bf57600080fd5b506101e76102ce366004611f65565b6107df565b6101e76102e1366004611f96565b6108aa565b3480156102f257600080fd5b506102097f0000000000000000000000003701fb675bcd4a85eb11a2467628bbe193f6e6a881565b34801561032657600080fd5b506102097f000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb81565b34801561035a57600080fd5b50600154610209906001600160a01b031681565b34801561037a57600080fd5b506102097f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb521381565b3480156103ae57600080fd5b506101e76103bd366004611fef565b610a92565b3480156103ce57600080fd5b506101e7610b0d565b3480156103e357600080fd5b506101e76103f2366004611f65565b610cb3565b34801561040357600080fd5b506101e7610412366004611fef565b610e3e565b34801561042357600080fd5b506101e7610eb9565b34801561043857600080fd5b506101e7610447366004612011565b610fda565b6101e761045a366004611f96565b6112ad565b34801561046b57600080fd5b506101e761047a366004611f65565b6113fc565b34801561048b57600080fd5b506104e161049a366004611f65565b60036020526000908152604090205465ffffffffffff80821691600160301b81049091169060ff600160601b8204811691600160681b8104821691600160701b9091041685565b6040805165ffffffffffff96871681529590941660208601529115159284019290925290151560608301521515608082015260a00161021d565b34801561052757600080fd5b506101e761156f565b34801561053c57600080fd5b5060045461054a9060ff1681565b60405161021d91906120ed565b34801561056357600080fd5b506101e76115c2565b34801561057857600080fd5b506101e7610587366004611fef565b611617565b34801561059857600080fd5b506101e76105a7366004611f65565b611691565b3480156105b857600080fd5b506105cc6105c7366004611f65565b6117be565b60405161021d9190612107565b3480156105e557600080fd5b506102097f00000000000000000000000032400084c286cf3e17e7b677ea9583e60a00032481565b6005544211156106385760405162461bcd60e51b815260040161062f9061211b565b60405180910390fd5b604051632b33745b60e21b8152600481018290527f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b03169063accdd16c90602401600060405180830381600087803b15801561069a57600080fd5b505af11580156106ae573d6000803e3d6000fd5b505050507fe2b6c70f0bb14be8c1be3a3875d171dd198b1f9f2d35972501b91c0fc6c1b0ce816040516106e391815260200190565b60405180910390a150565b6000546001600160a01b031633146107185760405162461bcd60e51b815260040161062f9061215c565b60006004805460ff1690811115610731576107316120d7565b1461077e5760405162461bcd60e51b815260206004820152601760248201527f50726f746f636f6c20616c72656164792066726f7a656e000000000000000000604482015260640161062f565b6004805460ff1916600117905561079761a8c0426121b2565b6005556107a261195b565b7f24f7761883b592e1cb80bcb0b5ad54822c7ed844019f3459111f131715d1ecc96005546040516107d591815260200190565b60405180910390a1565b600554156107ff5760405162461bcd60e51b815260040161062f906121d9565b6040516351d218f760e01b8152600481018290527f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b0316906351d218f790602401600060405180830381600087803b15801561086157600080fd5b505af1158015610875573d6000803e3d6000fd5b505050507fa938747b1cf8e014275de2758fc8d441002154a94bca459b291cbbbeb0c7c89d816040516106e391815260200190565b6002546001600160a01b0316331461092a5760405162461bcd60e51b815260206004820152603d60248201527f4f6e6c7920456d657267656e6379205570677261646520426f6172642069732060448201527f616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e000000606482015260840161062f565b60008160405160200161093d919061221c565b6040516020818303038152906040528051906020012090506000610960826117be565b90506000816006811115610976576109766120d7565b146109bc5760405162461bcd60e51b81526020600482015260166024820152755570677261646520616c72656164792065786973747360501b604482015260640161062f565b336109cd6040850160208601611fef565b6001600160a01b0316146109f35760405162461bcd60e51b815260040161062f90612381565b6000828152600360205260408120805460ff60701b1916600160701b1790556004805460ff19169055600555610a27611b6d565b610a39610a3484806123d4565b611d69565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded90600090a160405182907f39f6aeadc0239b46b37917ee1c12e98f9cd3a5dea6c038efa22af67471128e5190600090a2505050565b333014610ab15760405162461bcd60e51b815260040161062f90612425565b6001546040516001600160a01b038084169216907ffbb8d9e9607c95042daed3ce66316805e80c575253e2b5a83eb10cb97ac23d8890600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331480610b33575060055415801590610b33575060055442115b610bcb5760405162461bcd60e51b815260206004820152605760248201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f77656460448201527f20746f2063616c6c20746869732066756e6374696f6e206f722074686520707260648201527f6f746f636f6c2073686f756c642062652066726f7a656e000000000000000000608482015260a40161062f565b60016004805460ff1690811115610be457610be46120d7565b03610c0357600480546003919060ff19166001835b0217905550610c7b565b60026004805460ff1690811115610c1c57610c1c6120d7565b03610c335760048054819060ff1916600182610bf9565b60405162461bcd60e51b815260206004820152601d60248201527f556e6578706563746564206c61737420667265657a6520737461747573000000604482015260640161062f565b6000600555610c88611b6d565b6040517f2f05ba71d0df11bf5fa562a6569d70c4f80da84284badbe015ce1456063d0ded90600090a1565b6001546001600160a01b03163314610cdd5760405162461bcd60e51b815260040161062f90612490565b600081815260036020526040902054600160601b900460ff1615610d545760405162461bcd60e51b815260206004820152602860248201527f5570677261646520697320616c726561647920617070726f76656420627920676044820152677561726469616e7360c01b606482015260840161062f565b6000610d5f826117be565b90506002816006811115610d7557610d756120d7565b14610df45760405162461bcd60e51b815260206004820152604360248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d20477561726469606482015262616e7360e81b608482015260a40161062f565b600082815260036020526040808220805460ff60601b1916600160601b1790555183917f4bdba07411d36daebbfc1a5062f25d0d02c753374c8498aec76d5954c707682a91a25050565b333014610e5d5760405162461bcd60e51b815260040161062f90612425565b6002546040516001600160a01b038084169216907f892b24306024c8b484d205b00cd0b9b7ff3f38781a6ed6686c60ef2c59d7667090600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610ee35760405162461bcd60e51b815260040161062f9061215c565b60045460ff166000816004811115610efd57610efd6120d7565b1480610f1a57506001816004811115610f1857610f186120d7565b145b80610f3657506003816004811115610f3457610f346120d7565b145b610f825760405162461bcd60e51b815260206004820152601d60248201527f50726f746f636f6c2063616e277420626520686172642066726f7a656e000000604482015260640161062f565b6004805460ff19166002179055610f9c62093a80426121b2565b600555610fa761195b565b7f8cfb4dcbe7dce698c042e43e42e1e496194abadb41ac3756f5793a9c5a8bb3e86005546040516106e391815260200190565b600081604051602001610fed919061221c565b60408051601f1981840301815260608301825261ffff881683526001600160a01b037f0000000000000000000000003701fb675bcd4a85eb11a2467628bbe193f6e6a881166020850152838301829052915163e4948f4360e01b81529093506000917f00000000000000000000000032400084c286cf3e17e7b677ea9583e60a000324169063e4948f439061108e908c908c9087908c908c90600401612511565b602060405180830381865afa1580156110ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110cf91906125b5565b9050806111325760405162461bcd60e51b815260206004820152602b60248201527f4661696c656420746f20636865636b20757067726164652070726f706f73616c60448201526a1034b734ba34b0ba34b7b760a91b606482015260840161062f565b6002546001600160a01b031661114e6040860160208701611fef565b6001600160a01b0316036111c05760405162461bcd60e51b815260206004820152603360248201527f456d657267656e6379205570677261646520426f6172642063616e2774206578604482015272656375746520757375616c207570677261646560681b606482015260840161062f565b8251602084012060006111d2826117be565b905060008160068111156111e8576111e86120d7565b146112415760405162461bcd60e51b815260206004820152602360248201527f557067726164652077697468207468697320696420616c72656164792065786960448201526273747360e81b606482015260840161062f565b60008281526003602052604090819020805465ffffffffffff19164265ffffffffffff161790555182907f71a79729ed8b7db17b27c5dfe0ae24cf41d52b08c8dfc82592fc7db23010c8799061129890899061221c565b60405180910390a25050505050505050505050565b6000816040516020016112c0919061221c565b60405160208183030381529060405280519060200120905060006112e3826117be565b905060048160068111156112f9576112f96120d7565b146113465760405162461bcd60e51b815260206004820152601860248201527f55706772616465206973206e6f74207965742072656164790000000000000000604482015260640161062f565b60006113586040850160208601611fef565b6001600160a01b031614806113845750336113796040850160208601611fef565b6001600160a01b0316145b6113a05760405162461bcd60e51b815260040161062f90612381565b6000828152600360205260409020805460ff60701b1916600160701b1790556113cc610a3484806123d4565b60405182907ff6224a998aea3de231cf75375faf8c3711379d54bb84c92ef9d9779dabd383a990600090a2505050565b6001546001600160a01b031633146114265760405162461bcd60e51b815260040161062f90612490565b600081815260036020526040902054600160681b900460ff161561149a5760405162461bcd60e51b815260206004820152602560248201527f4c6567616c207665746f20706572696f6420697320616c726561647920657874604482015264195b99195960da1b606482015260840161062f565b60006114a5826117be565b905060018160068111156114bb576114bb6120d7565b146115255760405162461bcd60e51b815260206004820152603460248201527f5570677261646520776974682074686973206964206973206e6f7420696e20746044820152731a19481b1959d85b081d995d1bc81c195c9a5bd960621b606482015260840161062f565b600082815260036020526040808220805460ff60681b1916600160681b1790555183917f6679375a2761fa72f4163ccf9a92a514bfd3adff8eb1f2f17256f25834dc46ca91a25050565b6005541561158f5760405162461bcd60e51b815260040161062f906121d9565b611597611b6d565b6040517fea592eda90ea1daf1d7577bddc51f4f8425ec0332f0dd8b58aa08f8a2d1da62190600090a1565b6005544211156115e45760405162461bcd60e51b815260040161062f9061211b565b6115ec61195b565b6040517fbe5088092f32032505342f55f3393029ab55bd4dfcc2edad138d715f485ace6e90600090a1565b3330146116365760405162461bcd60e51b815260040161062f90612425565b600080546040516001600160a01b03808516939216917fe55ac8ae7914efca1278b8ed4ae21728d06ad9f6e7637bb2c905aacf2a6f595191a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146116bb5760405162461bcd60e51b815260040161062f9061215c565b60006116c6826117be565b905060028160068111156116dc576116dc6120d7565b146117625760405162461bcd60e51b815260206004820152604a60248201527f5570677261646520776974682074686973206964206973206e6f74207761697460448201527f696e6720666f722074686520617070726f76616c2066726f6d205365637572696064820152691d1e4810dbdd5b98da5b60b21b608482015260a40161062f565b60008281526003602052604080822080546bffffffffffff0000000000001916600160301b4265ffffffffffff16021790555183917f4ea0d7cd48461eaf68f428942cdfb19039bd43dc723fa8875c65bec57d911ac491a25050565b6000818152600360209081526040808320815160a081018352905465ffffffffffff8082168352600160301b8204169382019390935260ff600160601b84048116151592820192909252600160681b8304821615156060820152600160701b9092041615801560808301526118365750600692915050565b805165ffffffffffff166000036118505750600092915050565b60008160600151611864576203f480611869565b62093a805b825190915061188190829065ffffffffffff166121b2565b421015611892575060019392505050565b602082015165ffffffffffff16156118de57600062015180836020015165ffffffffffff166118c191906121b2565b9050804210156118d25760036118d5565b60045b95945050505050565b600062278d0082846000015165ffffffffffff166118fc91906121b2565b61190691906121b2565b905080421061195057826040015161192357506005949350505050565b600061193262015180836121b2565b905080421015611943576003611946565b60045b9695505050505050565b506002949350505050565b60007f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b031663a75b496d6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156119bb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119e391908101906125ed565b805190915060005b81811015611a8e577f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b031663accdd16c848381518110611a3457611a346126ab565b60200260200101516040518263ffffffff1660e01b8152600401611a5a91815260200190565b600060405180830381600087803b158015611a7457600080fd5b505af1925050508015611a85575060015b506001016119eb565b507f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611aea57600080fd5b505af1925050508015611afb575060015b507f000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb6001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b5757600080fd5b505af1925050508015611b68575060015b505050565b60007f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b031663a75b496d6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611bcd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611bf591908101906125ed565b805190915060005b81811015611ca0577f000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c6001600160a01b03166351d218f7848381518110611c4657611c466126ab565b60200260200101516040518263ffffffff1660e01b8152600401611c6c91815260200190565b600060405180830381600087803b158015611c8657600080fd5b505af1925050508015611c97575060015b50600101611bfd565b507f000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb52136001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611cfc57600080fd5b505af1925050508015611d0d575060015b507f000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb6001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b5757600080fd5b60005b81811015611b68576000838383818110611d8857611d886126ab565b9050602002810190611d9a91906126c1565b611da89060408101906126e1565b90501115611e61576000838383818110611dc457611dc46126ab565b9050602002810190611dd691906126c1565b611de4906020810190611fef565b6001600160a01b03163b11611e615760405162461bcd60e51b815260206004820152603c60248201527f546172676574206d757374206265206120736d61727420636f6e74726163742060448201527f6966207468652063616c6c64617461206973206e6f7420656d70747900000000606482015260840161062f565b600080848484818110611e7657611e766126ab565b9050602002810190611e8891906126c1565b611e96906020810190611fef565b6001600160a01b0316858585818110611eb157611eb16126ab565b9050602002810190611ec391906126c1565b60200135868686818110611ed957611ed96126ab565b9050602002810190611eeb91906126c1565b611ef99060408101906126e1565b604051611f07929190612728565b60006040518083038185875af1925050503d8060008114611f44576040519150601f19603f3d011682016040523d82523d6000602084013e611f49565b606091505b509150915081611f5b57805160208201fd5b5050600101611d6c565b600060208284031215611f7757600080fd5b5035919050565b600060608284031215611f9057600080fd5b50919050565b600060208284031215611fa857600080fd5b813567ffffffffffffffff811115611fbf57600080fd5b611fcb84828501611f7e565b949350505050565b80356001600160a01b0381168114611fea57600080fd5b919050565b60006020828403121561200157600080fd5b61200a82611fd3565b9392505050565b60008060008060008060a0878903121561202a57600080fd5b8635955060208701359450604087013561ffff8116811461204a57600080fd5b9350606087013567ffffffffffffffff8082111561206757600080fd5b818901915089601f83011261207b57600080fd5b81358181111561208a57600080fd5b8a60208260051b850101111561209f57600080fd5b6020830195508094505060808901359150808211156120bd57600080fd5b506120ca89828a01611f7e565b9150509295509295509295565b634e487b7160e01b600052602160045260246000fd5b6020810160058310612101576121016120d7565b91905290565b6020810160078310612101576121016120d7565b60208082526021908201527f50726f746f636f6c2073686f756c6420626520616c72656164792066726f7a656040820152603760f91b606082015260800190565b60208082526036908201527f4f6e6c7920536563757269747920436f756e63696c20697320616c6c6f776564604082015275103a379031b0b636103a3434b990333ab731ba34b7b760511b606082015260800190565b808201808211156121d357634e487b7160e01b600052601160045260246000fd5b92915050565b60208082526023908201527f50726f746f636f6c2073686f756c6420626520616c726561647920756e66726f6040820152623d32b760e91b606082015260800190565b6000602080835260808084018535601e1987360301811261223c57600080fd5b8601803584820167ffffffffffffffff8083111561225957600080fd5b8260051b80360383131561226c57600080fd5b60608a890181905295849052890160a0908101956000918b0136879003607e19015b86841015612347578c8903609f1901825285358181126122ad57600080fd5b88016001600160a01b036122c28d8301611fd3565b168a526040808201358d8c015284820135603e198336030181126122e557600080fd5b90910181810191908d0135878111156122fd57600080fd5b80360383131561230c57600080fd5b85828d015280868d015280838e8e013760008c82018e0152601f01601f1916909a018b01995050948a019460019390930192908a019061228e565b505050505050505061235a838701611fd3565b6001600160a01b038116604087015292506040860135606086015280935050505092915050565b60208082526033908201527f6d73672e73656e646572206973206e6f7420617574686f72697a656420746f20604082015272706572666f726d20746865207570677261646560681b606082015260800190565b6000808335601e198436030181126123eb57600080fd5b83018035915067ffffffffffffffff82111561240657600080fd5b6020019150600581901b360382131561241e57600080fd5b9250929050565b60208082526045908201527f4f6e6c7920757067726164652068616e646c657220636f6e747261637420697460408201527f73656c6620697320616c6c6f77656420746f2063616c6c20746869732066756e60608201526431ba34b7b760d91b608082015260a00190565b6020808252602f908201527f4f6e6c7920677561726469616e7320697320616c6c6f77656420746f2063616c60408201526e36103a3434b990333ab731ba34b7b760891b606082015260800190565b81835260006001600160fb1b038311156124f857600080fd5b8260051b80836020870137939093016020019392505050565b858152600060208660208401526080604084015261ffff865116608084015260018060a01b0360208701511660a08401526040860151606060c085015280518060e086015260005b818110156125765782810184015186820161010001528301612559565b5061010092506000838287010152601f19601f8201168501915050818482030160608501526125a882820186886124df565b9998505050505050505050565b6000602082840312156125c757600080fd5b8151801515811461200a57600080fd5b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561260057600080fd5b825167ffffffffffffffff8082111561261857600080fd5b818501915085601f83011261262c57600080fd5b81518181111561263e5761263e6125d7565b8060051b604051601f19603f83011681018181108582111715612663576126636125d7565b60405291825284820192508381018501918883111561268157600080fd5b938501935b8285101561269f57845184529385019392850192612686565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e198336030181126126d757600080fd5b9190910192915050565b6000808335601e198436030181126126f857600080fd5b83018035915067ffffffffffffffff82111561271357600080fd5b60200191503681900382131561241e57600080fd5b818382376000910190815291905056fea2646970667358221220c748916f9d47ab75cae280a60f2cd17b90aee0eb8988c987ab8af7d1b9980ceb64736f6c63430008180033

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

000000000000000000000000bdffcc71fe84020238f2990a6d2954e87355de0d000000000000000000000000d677e09324f8bb3cc64f009973693f751c33a888000000000000000000000000defd1edee3e8c5965216bd59c866f7f5307c9b290000000000000000000000003701fb675bcd4a85eb11a2467628bbe193f6e6a800000000000000000000000032400084c286cf3e17e7b677ea9583e60a000324000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb5213000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb

-----Decoded View---------------
Arg [0] : _securityCouncil (address): 0xBDFfCC71FE84020238F2990a6D2954e87355De0D
Arg [1] : _guardians (address): 0xD677e09324F8Bb3cC64F009973693f751c33A888
Arg [2] : _emergencyUpgradeBoard (address): 0xdEFd1eDEE3E8c5965216bd59C866f7f5307C9b29
Arg [3] : _l2ProtocolGovernor (address): 0x3701fB675bCd4A85eb11A2467628BBe193F6e6A8
Arg [4] : _ZKsyncEra (address): 0x32400084C286CF3E17e7B677ea9583e60a000324
Arg [5] : _stateTransitionManager (address): 0xc2eE6b6af7d616f6e27ce7F4A451Aedc2b0F5f5C
Arg [6] : _bridgeHub (address): 0x303a465B659cBB0ab36eE643eA362c509EEb5213
Arg [7] : _sharedBridge (address): 0xD7f9f54194C633F36CCD5F3da84ad4a1c38cB2cB

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000bdffcc71fe84020238f2990a6d2954e87355de0d
Arg [1] : 000000000000000000000000d677e09324f8bb3cc64f009973693f751c33a888
Arg [2] : 000000000000000000000000defd1edee3e8c5965216bd59c866f7f5307c9b29
Arg [3] : 0000000000000000000000003701fb675bcd4a85eb11a2467628bbe193f6e6a8
Arg [4] : 00000000000000000000000032400084c286cf3e17e7b677ea9583e60a000324
Arg [5] : 000000000000000000000000c2ee6b6af7d616f6e27ce7f4a451aedc2b0f5f5c
Arg [6] : 000000000000000000000000303a465b659cbb0ab36ee643ea362c509eeb5213
Arg [7] : 000000000000000000000000d7f9f54194c633f36ccd5f3da84ad4a1c38cb2cb


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
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.