1
1
// SPDX-License-Identifier: MIT
2
- // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade .sol)
2
+ // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Utils .sol)
3
3
4
- pragma solidity ^ 0.8.19 ;
4
+ pragma solidity ^ 0.8.20 ;
5
5
6
6
import "../beacon/IBeacon.sol " ;
7
7
import "../../interfaces/IERC1967.sol " ;
@@ -15,7 +15,24 @@ import "../../utils/StorageSlot.sol";
15
15
*
16
16
* _Available since v4.1._
17
17
*/
18
- abstract contract ERC1967Upgrade is IERC1967 {
18
+ library ERC1967Utils {
19
+ // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
20
+ // This will be fixed in Solidity 0.8.21. At that point we should remove these events.
21
+ /**
22
+ * @dev Emitted when the implementation is upgraded.
23
+ */
24
+ event Upgraded (address indexed implementation );
25
+
26
+ /**
27
+ * @dev Emitted when the admin account has changed.
28
+ */
29
+ event AdminChanged (address previousAdmin , address newAdmin );
30
+
31
+ /**
32
+ * @dev Emitted when the beacon is changed.
33
+ */
34
+ event BeaconUpgraded (address indexed beacon );
35
+
19
36
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
20
37
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143 ;
21
38
@@ -24,7 +41,8 @@ abstract contract ERC1967Upgrade is IERC1967 {
24
41
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
25
42
* validated in the constructor.
26
43
*/
27
- bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc ;
44
+ // solhint-disable-next-line private-vars-leading-underscore
45
+ bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc ;
28
46
29
47
/**
30
48
* @dev The `implementation` of the proxy is invalid.
@@ -49,8 +67,8 @@ abstract contract ERC1967Upgrade is IERC1967 {
49
67
/**
50
68
* @dev Returns the current implementation address.
51
69
*/
52
- function _getImplementation () internal view returns (address ) {
53
- return StorageSlot.getAddressSlot (_IMPLEMENTATION_SLOT ).value;
70
+ function getImplementation () internal view returns (address ) {
71
+ return StorageSlot.getAddressSlot (IMPLEMENTATION_SLOT ).value;
54
72
}
55
73
56
74
/**
@@ -60,26 +78,26 @@ abstract contract ERC1967Upgrade is IERC1967 {
60
78
if (newImplementation.code.length == 0 ) {
61
79
revert ERC1967InvalidImplementation (newImplementation);
62
80
}
63
- StorageSlot.getAddressSlot (_IMPLEMENTATION_SLOT ).value = newImplementation;
81
+ StorageSlot.getAddressSlot (IMPLEMENTATION_SLOT ).value = newImplementation;
64
82
}
65
83
66
84
/**
67
85
* @dev Perform implementation upgrade
68
86
*
69
- * Emits an {Upgraded} event.
87
+ * Emits an {IERC1967- Upgraded} event.
70
88
*/
71
- function _upgradeTo (address newImplementation ) internal {
89
+ function upgradeTo (address newImplementation ) internal {
72
90
_setImplementation (newImplementation);
73
91
emit Upgraded (newImplementation);
74
92
}
75
93
76
94
/**
77
95
* @dev Perform implementation upgrade with additional setup call.
78
96
*
79
- * Emits an {Upgraded} event.
97
+ * Emits an {IERC1967- Upgraded} event.
80
98
*/
81
- function _upgradeToAndCall (address newImplementation , bytes memory data , bool forceCall ) internal {
82
- _upgradeTo (newImplementation);
99
+ function upgradeToAndCall (address newImplementation , bytes memory data , bool forceCall ) internal {
100
+ upgradeTo (newImplementation);
83
101
if (data.length > 0 || forceCall) {
84
102
Address.functionDelegateCall (newImplementation, data);
85
103
}
@@ -88,24 +106,24 @@ abstract contract ERC1967Upgrade is IERC1967 {
88
106
/**
89
107
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
90
108
*
91
- * Emits an {Upgraded} event.
109
+ * Emits an {IERC1967- Upgraded} event.
92
110
*/
93
- function _upgradeToAndCallUUPS (address newImplementation , bytes memory data , bool forceCall ) internal {
111
+ function upgradeToAndCallUUPS (address newImplementation , bytes memory data , bool forceCall ) internal {
94
112
// Upgrades from old implementations will perform a rollback test. This test requires the new
95
113
// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
96
114
// this special case will break upgrade paths from old UUPS implementation to new ones.
97
115
if (StorageSlot.getBooleanSlot (_ROLLBACK_SLOT).value) {
98
116
_setImplementation (newImplementation);
99
117
} else {
100
118
try IERC1822Proxiable (newImplementation).proxiableUUID () returns (bytes32 slot ) {
101
- if (slot != _IMPLEMENTATION_SLOT ) {
119
+ if (slot != IMPLEMENTATION_SLOT ) {
102
120
revert ERC1967UnsupportedProxiableUUID (slot);
103
121
}
104
122
} catch {
105
123
// The implementation is not UUPS
106
124
revert ERC1967InvalidImplementation (newImplementation);
107
125
}
108
- _upgradeToAndCall (newImplementation, data, forceCall);
126
+ upgradeToAndCall (newImplementation, data, forceCall);
109
127
}
110
128
}
111
129
@@ -114,7 +132,8 @@ abstract contract ERC1967Upgrade is IERC1967 {
114
132
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
115
133
* validated in the constructor.
116
134
*/
117
- bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 ;
135
+ // solhint-disable-next-line private-vars-leading-underscore
136
+ bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 ;
118
137
119
138
/**
120
139
* @dev Returns the current admin.
@@ -123,8 +142,8 @@ abstract contract ERC1967Upgrade is IERC1967 {
123
142
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
124
143
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
125
144
*/
126
- function _getAdmin () internal view returns (address ) {
127
- return StorageSlot.getAddressSlot (_ADMIN_SLOT ).value;
145
+ function getAdmin () internal view returns (address ) {
146
+ return StorageSlot.getAddressSlot (ADMIN_SLOT ).value;
128
147
}
129
148
130
149
/**
@@ -134,30 +153,31 @@ abstract contract ERC1967Upgrade is IERC1967 {
134
153
if (newAdmin == address (0 )) {
135
154
revert ERC1967InvalidAdmin (address (0 ));
136
155
}
137
- StorageSlot.getAddressSlot (_ADMIN_SLOT ).value = newAdmin;
156
+ StorageSlot.getAddressSlot (ADMIN_SLOT ).value = newAdmin;
138
157
}
139
158
140
159
/**
141
160
* @dev Changes the admin of the proxy.
142
161
*
143
- * Emits an {AdminChanged} event.
162
+ * Emits an {IERC1967- AdminChanged} event.
144
163
*/
145
- function _changeAdmin (address newAdmin ) internal {
146
- emit AdminChanged (_getAdmin (), newAdmin);
164
+ function changeAdmin (address newAdmin ) internal {
165
+ emit AdminChanged (getAdmin (), newAdmin);
147
166
_setAdmin (newAdmin);
148
167
}
149
168
150
169
/**
151
170
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
152
- * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
171
+ * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1) and is validated in the constructor.
153
172
*/
154
- bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50 ;
173
+ // solhint-disable-next-line private-vars-leading-underscore
174
+ bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50 ;
155
175
156
176
/**
157
177
* @dev Returns the current beacon.
158
178
*/
159
- function _getBeacon () internal view returns (address ) {
160
- return StorageSlot.getAddressSlot (_BEACON_SLOT ).value;
179
+ function getBeacon () internal view returns (address ) {
180
+ return StorageSlot.getAddressSlot (BEACON_SLOT ).value;
161
181
}
162
182
163
183
/**
@@ -173,16 +193,16 @@ abstract contract ERC1967Upgrade is IERC1967 {
173
193
revert ERC1967InvalidImplementation (beaconImplementation);
174
194
}
175
195
176
- StorageSlot.getAddressSlot (_BEACON_SLOT ).value = newBeacon;
196
+ StorageSlot.getAddressSlot (BEACON_SLOT ).value = newBeacon;
177
197
}
178
198
179
199
/**
180
200
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
181
201
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
182
202
*
183
- * Emits a { BeaconUpgraded} event.
203
+ * Emits an {IERC1967- BeaconUpgraded} event.
184
204
*/
185
- function _upgradeBeaconToAndCall (address newBeacon , bytes memory data , bool forceCall ) internal {
205
+ function upgradeBeaconToAndCall (address newBeacon , bytes memory data , bool forceCall ) internal {
186
206
_setBeacon (newBeacon);
187
207
emit BeaconUpgraded (newBeacon);
188
208
if (data.length > 0 || forceCall) {
0 commit comments