UpgradeGatekeeper

0x43cff77cd060a155dce5deb12b93b875f69f2716

Verification
Verified
v0.8.25+commit.b61c2a91
Type
Contract
4,116 bytes
ABI entries
24
10 read · 7 write
License
none

Contract information

Address
0x43cff77cd060a155dce5deb12b93b875f69f2716
Chain
Robinhood Chain (4663)
Compiler
v0.8.25+commit.b61c2a91
Optimization
Enabled
Creation tx
0x56119cbe72…b0d8ecdad3

Token

Not a token

This contract does not expose ERC-20 metadata.

Read contract (10)

approvedUpgradeNoticePeriod()uint256
getMaster()address
managedContracts(uint256)address
nextTargets(uint256)address
noticePeriodFinishTimestamp()uint256
securityCouncilAddress()address
upgradeStartTimestamp()uint256
upgradeStatus()uint8
versionId()uint256
zkLighterProxy()address

Events (6)

NewUpgradableNoticePeriodChangeNoticePeriodStartPreparationStartUpgradeCancelUpgradeComplete

ABI

[
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_securityCouncilAddress",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "_zkLighterProxy",
        "type": "address"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "versionId",
        "type": "uint256"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "upgradeable",
        "type": "address"
      }
    ],
    "name": "NewUpgradable",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "newNoticePeriod",
        "type": "uint256"
      }
    ],
    "name": "NoticePeriodChange",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "versionId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "address[]",
        "name": "newTargets",
        "type": "address[]"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "noticePeriod",
        "type": "uint256"
      }
    ],
    "name": "NoticePeriodStart",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "versionId",
        "type": "uint256"
      }
    ],
    "name": "PreparationStart",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "versionId",
        "type": "uint256"
      }
    ],
    "name": "UpgradeCancel",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "versionId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "address[]",
        "name": "newTargets",
        "type": "address[]"
      }
    ],
    "name": "UpgradeComplete",
    "type": "event"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "addr",
        "type": "address"
      }
    ],
    "name": "addUpgradeable",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "approvedUpgradeNoticePeriod",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "cancelUpgrade",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_upgradeStartTimestamp",
        "type": "uint256"
      }
    ],
    "name": "cutUpgradeNoticePeriod",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes[]",
        "name": "targetsUpgradeParameters",
        "type": "bytes[]"
      }
    ],
    "name": "finishUpgrade",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "getMaster",
    "outputs": [
      {
        "internalType": "address",
        "name": "master",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "managedContracts",
    "outputs": [
      {
        "internalType": "contract IUpgradeable",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "nextTargets",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "noticePeriodFinishTimestamp",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "securityCouncilAddress",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "startPreparation",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address[]",
        "name": "newTargets",
        "type": "address[]"
      }
    ],
    "name": "startUpgrade",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_newMaster",
        "type": "address"
      }
    ],
    "name": "transferMastership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "upgradeStartTimestamp",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "upgradeStatus",
    "outputs": [
      {
        "internalType": "enum UpgradeGatekeeper.UpgradeStatus",
        "name": "",
        "type": "uint8"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "versionId",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "zkLighterProxy",
    "outputs": [
      {
        "internalType": "contract IZkLighterDesertMode",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  }
]

Source code

// 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;
  }
}
Chain explorer3822msChain node75ms