github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/src/L1/ProtocolVersions.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity 0.8.15; 3 4 import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; 5 import { ISemver } from "src/universal/ISemver.sol"; 6 import { Storage } from "src/libraries/Storage.sol"; 7 import { Constants } from "src/libraries/Constants.sol"; 8 9 /// @notice ProtocolVersion is a numeric identifier of the protocol version. 10 type ProtocolVersion is uint256; 11 12 /// @title ProtocolVersions 13 /// @notice The ProtocolVersions contract is used to manage superchain protocol version information. 14 contract ProtocolVersions is OwnableUpgradeable, ISemver { 15 /// @notice Enum representing different types of updates. 16 /// @custom:value REQUIRED_PROTOCOL_VERSION Represents an update to the required protocol version. 17 /// @custom:value RECOMMENDED_PROTOCOL_VERSION Represents an update to the recommended protocol version. 18 enum UpdateType { 19 REQUIRED_PROTOCOL_VERSION, 20 RECOMMENDED_PROTOCOL_VERSION 21 } 22 23 /// @notice Version identifier, used for upgrades. 24 uint256 public constant VERSION = 0; 25 26 /// @notice Storage slot that the required protocol version is stored at. 27 bytes32 public constant REQUIRED_SLOT = bytes32(uint256(keccak256("protocolversion.required")) - 1); 28 29 /// @notice Storage slot that the recommended protocol version is stored at. 30 bytes32 public constant RECOMMENDED_SLOT = bytes32(uint256(keccak256("protocolversion.recommended")) - 1); 31 32 /// @notice Emitted when configuration is updated. 33 /// @param version ProtocolVersion version. 34 /// @param updateType Type of update. 35 /// @param data Encoded update data. 36 event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); 37 38 /// @notice Semantic version. 39 /// @custom:semver 1.0.0 40 string public constant version = "1.0.0"; 41 42 /// @notice Constructs the ProtocolVersion contract. Cannot set 43 /// the owner to `address(0)` due to the Ownable contract's 44 /// implementation, so set it to `address(0xdEaD)` 45 /// A zero version is considered empty and is ignored by nodes. 46 constructor() { 47 initialize({ 48 _owner: address(0xdEaD), 49 _required: ProtocolVersion.wrap(uint256(0)), 50 _recommended: ProtocolVersion.wrap(uint256(0)) 51 }); 52 } 53 54 /// @notice Initializer. 55 /// @param _owner Initial owner of the contract. 56 /// @param _required Required protocol version to operate on this chain. 57 /// @param _recommended Recommended protocol version to operate on thi chain. 58 function initialize(address _owner, ProtocolVersion _required, ProtocolVersion _recommended) public initializer { 59 __Ownable_init(); 60 transferOwnership(_owner); 61 _setRequired(_required); 62 _setRecommended(_recommended); 63 } 64 65 /// @notice High level getter for the required protocol version. 66 /// @return out_ Required protocol version to sync to the head of the chain. 67 function required() external view returns (ProtocolVersion out_) { 68 out_ = ProtocolVersion.wrap(Storage.getUint(REQUIRED_SLOT)); 69 } 70 71 /// @notice Updates the required protocol version. Can only be called by the owner. 72 /// @param _required New required protocol version. 73 function setRequired(ProtocolVersion _required) external onlyOwner { 74 _setRequired(_required); 75 } 76 77 /// @notice Internal function for updating the required protocol version. 78 /// @param _required New required protocol version. 79 function _setRequired(ProtocolVersion _required) internal { 80 Storage.setUint(REQUIRED_SLOT, ProtocolVersion.unwrap(_required)); 81 82 bytes memory data = abi.encode(_required); 83 emit ConfigUpdate(VERSION, UpdateType.REQUIRED_PROTOCOL_VERSION, data); 84 } 85 86 /// @notice High level getter for the recommended protocol version. 87 /// @return out_ Recommended protocol version to sync to the head of the chain. 88 function recommended() external view returns (ProtocolVersion out_) { 89 out_ = ProtocolVersion.wrap(Storage.getUint(RECOMMENDED_SLOT)); 90 } 91 92 /// @notice Updates the recommended protocol version. Can only be called by the owner. 93 /// @param _recommended New recommended protocol version. 94 function setRecommended(ProtocolVersion _recommended) external onlyOwner { 95 _setRecommended(_recommended); 96 } 97 98 /// @notice Internal function for updating the recommended protocol version. 99 /// @param _recommended New recommended protocol version. 100 function _setRecommended(ProtocolVersion _recommended) internal { 101 Storage.setUint(RECOMMENDED_SLOT, ProtocolVersion.unwrap(_recommended)); 102 103 bytes memory data = abi.encode(_recommended); 104 emit ConfigUpdate(VERSION, UpdateType.RECOMMENDED_PROTOCOL_VERSION, data); 105 } 106 }