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
- Creator
- 0xC4C01f20f3…600bF41bBC
- 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