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  }