Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x94da8A995D0D82Ef0fE7E509C6D76c22603B6f67
Balance 0 ETH
Nonce 1
Code Size 4116 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

4116 bytes
0x608060409080825260049081361015610016575f80fd5b5f3560e01c9081631e52192714610d53575080632539162414610d36578063253b153b146108c457806331a94da314610695578063389b8b3a1461054557806355f29166146104645780635a99719e1461041e5780636b131e06146103f9578063999f0be2146102eb578063a836f4c9146102a8578063ac0d925c1461028a578063c3d1770614610259578063c3f59687146101bd578063c727927f1461017a578063c8a446671461015d578063d4d543c51461011e5763f1ce598e146100db575f80fd5b3461011a57602036600319011261011a57359060025482101561011a576001600160a01b0361010b602093610dfd565b92905490519260031b1c168152f35b5f80fd5b50903461011a575f36600319011261011a5760ff60035416905190600381101561014a57602092508152f35b602183634e487b7160e01b5f525260245ffd5b823461011a575f36600319011261011a576020905f549051908152f35b823461011a575f36600319011261011a57602090516001600160a01b037f00000000000000000000000092b12c9d85bf7bd2ef5d2f53f4cd4ce0be432045168152f35b503461011a57602036600319011261011a576101d7610d9e565b916101e133610f65565b6001600160a01b03831615610216577fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103839055005b906020606492519162461bcd60e51b8352820152600260248201527f31640000000000000000000000000000000000000000000000000000000000006044820152fd5b503461011a57602036600319011261011a57359060055482101561011a576001600160a01b0361010b602093610db4565b823461011a575f36600319011261011a576020906006549051908152f35b823461011a575f36600319011261011a57602090516001600160a01b037f0000000000000000000000003b4d794a66304f130a4db8f2551b0070dfcf5ca7168152f35b50903461011a57602036600319011261011a57610306610d9e565b9061031033610f65565b60ff6003541660038110156103e6576103a457506002546001600160a01b03918216926801000000000000000082101561039157508060016103559201600255610dfd565b819291549060031b9184831b921b19161790556006547fecfd8b4d8bfc0590001d923f6db32faaad4c3d96097734fe5950f43980dabfc45f80a3005b604190634e487b7160e01b5f525260245ffd5b5162461bcd60e51b8152602081840152600560248201527f61706331310000000000000000000000000000000000000000000000000000006044820152606490fd5b602184634e487b7160e01b5f525260245ffd5b823461011a575f36600319011261011a57602090610415610e81565b90519015158152f35b823461011a575f36600319011261011a576020906001600160a01b037fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354915191168152f35b503461011a575f36600319011261011a5761047e33610f65565b60035460ff8116600381101561014a5715610502577ff2b18f8abbd8a0d0c1fb8245146eedf5304887b12f6395b548ca238e054a148360205f94621baf809081875551908152a18260015560ff1916600355556104d9610e32565b6006547f55cd34119fd31f1a8cc60aad1098023b450274eef2294e3e1b6dd452d58ce6fd5f80a2005b506020606492519162461bcd60e51b8352820152600560248201527f63707531310000000000000000000000000000000000000000000000000000006044820152fd5b503461011a57602036600319011261011a57600154801561065257813503610610576001600160a01b037f00000000000000000000000092b12c9d85bf7bd2ef5d2f53f4cd4ce0be4320451633036105ce57505f546105a057005b60207ff2b18f8abbd8a0d0c1fb8245146eedf5304887b12f6395b548ca238e054a1483915f8055515f8152a1005b6020606492519162461bcd60e51b8352820152600260248201527f70330000000000000000000000000000000000000000000000000000000000006044820152fd5b6020606492519162461bcd60e51b8352820152600260248201527f70320000000000000000000000000000000000000000000000000000000000006044820152fd5b506020606492519162461bcd60e51b8352820152600260248201527f70310000000000000000000000000000000000000000000000000000000000006044820152fd5b50903461011a576020908160031936011261011a5767ffffffffffffffff91833583811161011a576106ca9036908601610d6d565b9390946106d633610f65565b6003549160ff8316600381101561014a57610882576002548603610840576001809342825560ff1916176003554282558511610391576801000000000000000085116103915750600554846005558085106107fe575b50928460055f525f905b8282106107b55750506006549381845194808601908652526060840195915f5b81811061078b575f85870152867fabce748366d7d01473824f1bee75dc176759f56b88f00253e4a10d7528ca806f878a0388a2005b909192968735906001600160a01b03821680920361011a5790815284019684019291908201610756565b8095929535916001600160a01b038316830361011a578484920192817f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db001550190949194610736565b81857f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db092830192015b82811061083557505061072c565b5f8155018290610827565b6064828587519162461bcd60e51b8352820152600560248201527f73707531320000000000000000000000000000000000000000000000000000006044820152fd5b6064828587519162461bcd60e51b8352820152600560248201527f73707531310000000000000000000000000000000000000000000000000000006044820152fd5b503461011a576020918260031936011261011a5767ffffffffffffffff90823582811161011a576108f89036908501610d6d565b909461090333610f65565b60039360ff85541685811015610d23576002809103610ce1576002548403610c9f576001600160a01b039385517f02cfb56300000000000000000000000000000000000000000000000000000000815284818a81897f0000000000000000000000003b4d794a66304f130a4db8f2551b0070dfcf5ca7165afa908115610c95575f91610c3d575b50610bfb5790977ff2b18f8abbd8a0d0c1fb8245146eedf5304887b12f6395b548ca238e054a148384621baf80805f558851908152a16001985f8a55895f905b610a99575b50505050506006545f198114610a86579580919392960192836006558251928184019082855260055480925284019760055f527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0925f915b838310610a6f57505050505050807f48bc8be43b04d57da4f0d65c05db98278a94d9e90b7348d5d2705cc78c9a9d2e915f960390a2805460ff1916905555610a6d610e32565b005b845481168b52998101999385019391850191610a27565b601186634e487b7160e01b5f525260245ffd5b81549085811691821015610bf557859188610ab383610db4565b9054908d1b1c169081610ae6575b505016848114610ad3578a018a6109ca565b60118a634e487b7160e01b5f525260245ffd5b9091925085898c610af686610dfd565b9054911b1c16911015610be257681fffffffffffffffe08360051b16850135601e198636030181121561011a5785019182359288841161011a57890190833603821361011a57823b1561011a578b928e5f809486518098819682957f6fc491400000000000000000000000000000000000000000000000000000000084528301526024988983015280604483015280606493848401378181018301849052601f01601f191681010301925af18015610bd857908793929115610ac1579091928211610bc75750885284905f80610ac1565b60418c634e487b7160e01b5f52525ffd5b8a513d5f823e3d90fd5b60328c634e487b7160e01b5f525260245ffd5b506109cf565b6064888588519162461bcd60e51b8352820152600560248201527f66707531330000000000000000000000000000000000000000000000000000006044820152fd5b9050843d8611610c8e575b601f8101601f1916820185811183821017610c7b57869183918a528101031261011a5751801515810361011a575f61098a565b60418b634e487b7160e01b5f525260245ffd5b503d610c48565b87513d5f823e3d90fd5b6064878487519162461bcd60e51b8352820152600560248201527f66707531320000000000000000000000000000000000000000000000000000006044820152fd5b6064878487519162461bcd60e51b8352820152600560248201527f66707531310000000000000000000000000000000000000000000000000000006044820152fd5b602187634e487b7160e01b5f525260245ffd5b50903461011a575f36600319011261011a57602091549051908152f35b3461011a575f36600319011261011a576020906001548152f35b9181601f8401121561011a5782359167ffffffffffffffff831161011a576020808501948460051b01011161011a57565b600435906001600160a01b038216820361011a57565b600554811015610de95760055f527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db001905f90565b634e487b7160e01b5f52603260045260245ffd5b600254811015610de95760025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01905f90565b6005545f60055580610e415750565b60055f527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0908101905b818110610e76575050565b5f8155600101610e6b565b610e8a33610f65565b60035460ff81166003811015610f5157600103610f0d576004544210610f085760ff19166002176003556001545f548101908110610ef457421061011a576006547fd2b7d4a4a2b38481e36a9b8198af8b427261011fd199b7a1b7cb8f437aa25acd5f80a2600190565b634e487b7160e01b5f52601160045260245ffd5b505f90565b606460405162461bcd60e51b815260206004820152600560248201527f75677031310000000000000000000000000000000000000000000000000000006044820152fd5b634e487b7160e01b5f52602160045260245ffd5b6001600160a01b03807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035416911603610f9a57565b606460405162461bcd60e51b815260206004820152600260248201527f31630000000000000000000000000000000000000000000000000000000000006044820152fdfea264697066735822122012eb6af821620109335e391b200016e975f60124760da25948f2682767ef332f64736f6c63430008190033

Verified Source Code Full Match

Compiler: v0.8.25+commit.b61c2a91 EVM: cancun Optimization: Yes (1000 runs)
IZkLighterDesertMode.sol 12 lines
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.8.25;

/// @title zkLighter DesertMode Interface
/// @author zkLighter Team
interface IZkLighterDesertMode {
  /// @notice thrown when DesertMode is active
  error ZkLighter_DesertModeActive();

  function desertMode() external view returns (bool);
}
IUpgradeable.sol 12 lines
// SPDX-License-Identifier: MIT OR Apache-2.0

pragma solidity 0.8.25;

/// @title Interface of the upgradeable contract
/// @author Matter Labs (https://github.com/matter-labs/zksync/blob/master/contracts/contracts/Upgradeable.sol)
interface IUpgradeable {
  /// @notice Upgrades target of upgradeable contract
  /// @param newTarget New target
  /// @param newTargetInitializationParameters New target initialization parameters
  function upgradeTarget(address newTarget, bytes calldata newTargetInitializationParameters) external;
}
IUpgradeEvents.sol 26 lines
// SPDX-License-Identifier: MIT OR Apache-2.0

pragma solidity 0.8.25;

/// @title Upgrade events
/// @author Matter Labs (https://github.com/matter-labs/zksync/blob/master/contracts/contracts/Events.sol)
interface IUpgradeEvents {
  /// @notice Event emitted when new upgradeable contract is added to upgrade gatekeeper's list of managed contracts
  event NewUpgradable(uint256 indexed versionId, address indexed upgradeable);

  /// @notice Upgrade mode enter event
  event NoticePeriodStart(
    uint256 indexed versionId,
    address[] newTargets,
    uint256 noticePeriod // notice period (in seconds)
  );

  /// @notice Upgrade mode cancel event
  event UpgradeCancel(uint256 indexed versionId);

  /// @notice Upgrade mode preparation status event
  event PreparationStart(uint256 indexed versionId);

  /// @notice Upgrade mode complete event
  event UpgradeComplete(uint256 indexed versionId, address[] newTargets);
}
Ownable.sol 50 lines
// SPDX-License-Identifier: MIT OR Apache-2.0

pragma solidity 0.8.25;

/// @title Ownable Contract
/// @author Matter Labs (https://github.com/matter-labs/zksync/blob/master/contracts/contracts/Ownable.sol)
contract Ownable {
  /// @dev Storage position of the masters address (keccak256('eip1967.proxy.admin') - 1)
  bytes32 private constant MASTER_POSITION = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

  /// @notice Contract constructor
  /// @dev Sets msg sender address as masters address
  /// @param masterAddress Master address
  constructor(address masterAddress) {
    require(masterAddress != address(0), "1b"); // oro11 - master address can't be zero address
    setMaster(masterAddress);
  }

  /// @notice Check if specified address is master
  /// @param _address Address to check
  function requireMaster(address _address) internal view {
    require(_address == getMaster(), "1c"); // oro11 - only by master
  }

  /// @notice Returns contract masters address
  /// @return master Master's address
  function getMaster() public view returns (address master) {
    bytes32 position = MASTER_POSITION;
    assembly {
      master := sload(position)
    }
  }

  /// @dev Sets new masters address
  /// @param _newMaster New master's address
  function setMaster(address _newMaster) internal {
    bytes32 position = MASTER_POSITION;
    assembly {
      sstore(position, _newMaster)
    }
  }

  /// @notice Transfer mastership of the contract to new master
  /// @param _newMaster New masters address
  function transferMastership(address _newMaster) external {
    requireMaster(msg.sender);
    require(_newMaster != address(0), "1d"); // otp11 - new masters address can't be zero address
    setMaster(_newMaster);
  }
}
UpgradeGatekeeper.sol 123 lines
// SPDX-License-Identifier: MIT OR Apache-2.0

pragma solidity 0.8.25;

import "./IUpgradeEvents.sol";
import "./Ownable.sol";
import "./IUpgradeable.sol";
import "../UpgradeableMaster.sol";

/// @title Upgrade Gatekeeper Contract
/// @author Matter Labs (https://github.com/matter-labs/zksync/blob/master/contracts/contracts/UpgradeGatekeeper.sol)
/// Modified to implement UpgradeableMaster, since Proxy no longer implements the interface
contract UpgradeGatekeeper is UpgradeableMaster, IUpgradeEvents, Ownable {
  /// @notice Array of addresses of upgradeable contracts managed by the gatekeeper
  IUpgradeable[] public managedContracts;

  /// @notice Upgrade mode statuses
  enum UpgradeStatus {
    Idle,
    NoticePeriod,
    Preparation
  }

  UpgradeStatus public upgradeStatus;

  /// @notice Notice period finish timestamp (as seconds since unix epoch)
  /// @dev Will be equal to zero in case of not active upgrade mode
  uint256 public noticePeriodFinishTimestamp;

  /// @notice Addresses of the next versions of the contracts to be upgraded (if element of this array is equal to zero address it means that appropriate upgradeable contract wouldn't be upgraded this time)
  /// @dev Will be empty in case of not active upgrade mode
  address[] public nextTargets;

  /// @notice Version id of contracts
  uint256 public versionId;

  /// @notice Contract constructor
  /// @param _securityCouncilAddress Security council address
  /// @param _zkLighterProxy ZkLighter proxy address for desert mode checks to disable upgrades
  /// @dev Calls Ownable contract constructor
  constructor(
    address _securityCouncilAddress,
    address _zkLighterProxy
  ) UpgradeableMaster(_securityCouncilAddress, _zkLighterProxy) Ownable(msg.sender) {
    versionId = 0;
  }

  /// @notice Adds a new upgradeable contract to the list of contracts managed by the gatekeeper
  /// @param addr Address of upgradeable contract to add
  function addUpgradeable(address addr) external {
    requireMaster(msg.sender);
    require(upgradeStatus == UpgradeStatus.Idle, "apc11"); /// apc11 - upgradeable contract can't be added during upgrade

    managedContracts.push(IUpgradeable(addr));
    emit NewUpgradable(versionId, addr);
  }

  /// @notice Starts upgrade (activates notice period)
  /// @param newTargets New managed contracts targets (if element of this array is equal to zero address it means that appropriate upgradeable contract wouldn't be upgraded this time)
  function startUpgrade(address[] calldata newTargets) external {
    requireMaster(msg.sender);
    require(upgradeStatus == UpgradeStatus.Idle, "spu11"); // spu11 - unable to activate active upgrade mode
    require(newTargets.length == managedContracts.length, "spu12"); // spu12 - number of new targets must be equal to the number of managed contracts

    uint256 noticePeriod = getNoticePeriod();
    upgradeNoticePeriodStarted();
    upgradeStatus = UpgradeStatus.NoticePeriod;
    noticePeriodFinishTimestamp = block.timestamp + noticePeriod;
    nextTargets = newTargets;
    emit NoticePeriodStart(versionId, newTargets, noticePeriod);
  }

  /// @notice Cancels upgrade
  function cancelUpgrade() external {
    requireMaster(msg.sender);
    require(upgradeStatus != UpgradeStatus.Idle, "cpu11"); // cpu11 - unable to cancel not active upgrade mode

    upgradeCanceled();
    upgradeStatus = UpgradeStatus.Idle;
    noticePeriodFinishTimestamp = 0;
    delete nextTargets;
    emit UpgradeCancel(versionId);
  }

  /// @notice Activates preparation status
  /// @return Bool flag indicating that preparation status has been successfully activated
  function startPreparation() external returns (bool) {
    requireMaster(msg.sender);
    require(upgradeStatus == UpgradeStatus.NoticePeriod, "ugp11"); // ugp11 - unable to activate preparation status in case of not active notice period status

    if (block.timestamp >= noticePeriodFinishTimestamp) {
      upgradeStatus = UpgradeStatus.Preparation;
      upgradePreparationStarted();
      emit PreparationStart(versionId);
      return true;
    } else {
      return false;
    }
  }

  /// @notice Finishes upgrade
  /// @param targetsUpgradeParameters New targets upgrade parameters per each upgradeable contract
  function finishUpgrade(bytes[] calldata targetsUpgradeParameters) external {
    requireMaster(msg.sender);
    require(upgradeStatus == UpgradeStatus.Preparation, "fpu11"); // fpu11 - unable to finish upgrade without preparation status active
    require(targetsUpgradeParameters.length == managedContracts.length, "fpu12"); // fpu12 - number of new targets upgrade parameters must be equal to the number of managed contracts
    require(isReadyForUpgrade(), "fpu13"); // fpu13 - main contract is not ready for upgrade
    upgradeFinishes();

    for (uint64 i = 0; i < managedContracts.length; i++) {
      address newTarget = nextTargets[i];
      if (newTarget != address(0)) {
        managedContracts[i].upgradeTarget(newTarget, targetsUpgradeParameters[i]);
      }
    }
    versionId++;
    emit UpgradeComplete(versionId, nextTargets);

    upgradeStatus = UpgradeStatus.Idle;
    noticePeriodFinishTimestamp = 0;
    delete nextTargets;
  }
}
UpgradeableMaster.sol 98 lines
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.8.25;

import "./interfaces/IZkLighterDesertMode.sol";

/// @title Upgradeable Master Contract
/// @author zkLighter Team
/// @dev UpgradeableMaster is used by the UpgradeGatekeeper when upgrading contracts.
/// It is controlled by the security council. The whole state of the contract is read only.
/// It's indented to be inherited by the UpgradeGatekeeper. Due to this, all methods which are used in the flow of
/// deploying updates are internal.
/// It has 2 main roles:
/// - It delays the deployment of upgrades by at most 3 weeks, in case the upgrade is malicious.
/// This gives users enough time to withdraw the funds using full exit operation from the system.
/// - It stops any upgrade if the system has entered desert mode.
contract UpgradeableMaster {
  /// @notice Notice period changed
  event NoticePeriodChange(uint256 newNoticePeriod);

  /// @dev Notice period before activation of the upgrade (in seconds)
  /// @dev NOTE: Gives users enough time to send full exit requests if the upgrade is malicious
  uint256 internal constant UPGRADE_NOTICE_PERIOD = 3 weeks;

  /// @dev Upgrade notice period, possibly shorten by the security council
  uint256 public approvedUpgradeNoticePeriod;

  /// @dev Upgrade start timestamp
  /// @dev Will be equal to zero if there is no active upgrade
  uint256 public upgradeStartTimestamp;

  /// @dev Instead of keeping a list of council members and requiring approval from all of them,
  /// keep just one council member to simplify the workflow. The council member itself could be a multi signature wallet
  address public immutable securityCouncilAddress;

  /// @dev zkLighter contract used to detect if system is in desert mode. If desert mode is detected, upgrades are not allowed
  IZkLighterDesertMode public immutable zkLighterProxy;

  constructor(address _securityCouncilAddress, address _zkLighterProxy) {
    require(_zkLighterProxy != address(0), "c1");
    securityCouncilAddress = _securityCouncilAddress;
    zkLighterProxy = IZkLighterDesertMode(_zkLighterProxy);
    approvedUpgradeNoticePeriod = UPGRADE_NOTICE_PERIOD;
    emit NoticePeriodChange(approvedUpgradeNoticePeriod);
  }

  /// @notice Minimum notice period before setting the activation preparation for the upgrade
  function getNoticePeriod() internal pure returns (uint256) {
    return 0;
  }

  /// @notice Sets the upgradeStartTimestamp when an upgrade starts
  function upgradeNoticePeriodStarted() internal {
    upgradeStartTimestamp = block.timestamp;
  }

  /// @notice Checks if the upgrade preparation has started for the current upgrade
  function upgradePreparationStarted() internal view {
    require(block.timestamp >= upgradeStartTimestamp + approvedUpgradeNoticePeriod);
  }

  /// @dev Clears the current upgrade when upgrade is finished or canceled
  function clearUpgradeStatus() internal {
    approvedUpgradeNoticePeriod = UPGRADE_NOTICE_PERIOD;
    emit NoticePeriodChange(approvedUpgradeNoticePeriod);
    upgradeStartTimestamp = 0;
  }

  /// @notice Clears the upgrade status when the upgrade is canceled
  function upgradeCanceled() internal {
    clearUpgradeStatus();
  }

  /// @notice Clears the upgrade status when the upgrade is finished
  function upgradeFinishes() internal {
    clearUpgradeStatus();
  }

  /// @notice Checks if the contract can be upgraded (does not allow upgrades in desert mode)
  /// @return bool flag indicating that contract is ready for upgrade
  function isReadyForUpgrade() internal view returns (bool) {
    return !zkLighterProxy.desertMode();
  }

  /// @notice Allows security council to decrease upgrade notice period time to 0
  /// @dev Can only be called after the start of the upgrade (getNoticePeriod)
  function cutUpgradeNoticePeriod(uint256 _upgradeStartTimestamp) external {
    require(upgradeStartTimestamp != 0, "p1");
    require(upgradeStartTimestamp == _upgradeStartTimestamp, "p2"); // given target is not the active upgrade
    require(msg.sender == securityCouncilAddress, "p3"); // only security council can call this

    // decrease upgrade notice period time to zero
    if (approvedUpgradeNoticePeriod > 0) {
      approvedUpgradeNoticePeriod = 0;
      emit NoticePeriodChange(approvedUpgradeNoticePeriod);
    }
  }
}

Read Contract

approvedUpgradeNoticePeriod 0xc8a44667 → uint256
getMaster 0x5a99719e → address
managedContracts 0xf1ce598e → address
nextTargets 0xc3d17706 → address
noticePeriodFinishTimestamp 0x25391624 → uint256
securityCouncilAddress 0xc727927f → address
upgradeStartTimestamp 0x1e521927 → uint256
upgradeStatus 0xd4d543c5 → uint8
versionId 0xac0d925c → uint256
zkLighterProxy 0xa836f4c9 → address

Write Contract 7 functions

These functions modify contract state and require a wallet transaction to execute.

addUpgradeable 0x999f0be2
address addr
cancelUpgrade 0x55f29166
No parameters
cutUpgradeNoticePeriod 0x389b8b3a
uint256 _upgradeStartTimestamp
finishUpgrade 0x253b153b
bytes[] targetsUpgradeParameters
startPreparation 0x6b131e06
No parameters
returns: bool
startUpgrade 0x31a94da3
address[] newTargets
transferMastership 0xc3f59687
address _newMaster

Recent Transactions

No transactions found for this address