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