You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**Motivation:**
Certora ReleaseManager audit fixes for Hourglass Part 1 and Part 2.
**Modifications:**
* `I-01. isValidRelease() and getLatestUpgradeByTime() may panic when no
releases exist` : Added `NoReleases()` custom error to those 2 functions
in the case of no error.
* `I-04. Unused imports can be removed`: Removed unused imports
* Support for signalling instant upgrades by setting `upgradeByTime` to
`0`.
* Updated unit tests
* Updated docs
* Updated bindings
**Result:**
Bug free code.
Copy file name to clipboardExpand all lines: docs/core/ReleaseManager.md
+30-7Lines changed: 30 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,6 +31,7 @@ An AVS in the context of `ReleaseManager` is defined as the `address` of the con
31
31
32
32
***Latest Release Validity**: Only the latest release for an operator set is considered valid. Previous releases become obsolete as soon as a new release is published.
33
33
***Upgrade Deadlines**: The `upgradeByTime` timestamp (in Unix time) is a suggested deadline and is not enforced on-chain or off-chain. It serves as a communication mechanism for AVSs to indicate when operators should complete their upgrades.
34
+
***Instant Upgrades**: When `upgradeByTime` is set to 0, this signals an instant upgrade requirement.
34
35
***Multiple Releases in Same Block**: If multiple releases are published in the same block with the same `upgradeByTime`, the last transaction processed in that block will determine the latest valid release.
35
36
36
37
---
@@ -58,7 +59,8 @@ struct Artifact {
58
59
/**
59
60
* @notice Represents a release containing multiple artifacts and an upgrade deadline.
60
61
* @param artifacts Array of artifacts included in this release.
61
-
* @param upgradeByTime Timestamp by which operators must upgrade to this release.
62
+
* @param upgradeByTime Timestamp by which operators must upgrade to this release.
63
+
* A value of 0 signals an instant upgrade requirement.
* @notice Publishes a new release for an operator set.
95
+
* @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade.
93
96
* @param operatorSet The operator set this release is for.
94
97
* @param release The release that was published.
95
98
* @return releaseId The index of the newly published release.
@@ -107,6 +110,8 @@ _Note: this method can be called directly by an AVS, or by a caller authorized b
107
110
108
111
AVSs use this method to publish new software releases for their operator sets. Each release contains one or more artifacts that represent the software components operators must run (e.g., validator clients, network monitors, etc.). The AVS specifies a deadline (`upgradeByTime`) by which all operators in the operator set must upgrade to the new release.
109
112
113
+
**Special Case - Instant Upgrades**: Setting `upgradeByTime` to 0 signals that this is an instant upgrade that operators should apply immediately. This is typically used for critical security patches or emergency updates.
114
+
110
115
The `releaseId` returned is the zero-based index of the release in the operator set's release array. This ID can be used to query the release later using [`getRelease`](#getrelease).
111
116
112
117
*Effects*:
@@ -117,7 +122,8 @@ The `releaseId` returned is the zero-based index of the release in the operator
117
122
118
123
*Requirements*:
119
124
* Caller MUST be authorized, either as the AVS itself or an admin/appointee (see [`PermissionController.md`](../permissions/PermissionController.md))
120
-
*`release.upgradeByTime` MUST be greater than or equal to the current block timestamp
125
+
* Operator set MUST have published metadata URI via `updateOperatorSetMetadataURI`
126
+
*`release.upgradeByTime` MUST be either 0 (instant upgrade) or greater than or equal to the current block timestamp
121
127
---
122
128
123
129
### View Functions
@@ -149,6 +155,7 @@ Returns the total number of releases that have been published for the specified
149
155
```solidity
150
156
/**
151
157
* @notice Returns a specific release by index.
158
+
* @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade.
152
159
* @param operatorSet The operator set to query.
153
160
* @param releaseId The id of the release to get.
154
161
* @return The release at the specified index.
@@ -166,13 +173,15 @@ Retrieves a specific release by its ID for a given operator set. The `releaseId`
166
173
167
174
*Returns*:
168
175
* The complete `Release` struct including all artifacts and the upgrade deadline
176
+
* If `upgradeByTime` is 0, this indicates an instant upgrade requirement
169
177
* Reverts if `releaseId` is out of bounds
170
178
171
179
#### `getLatestRelease`
172
180
173
181
```solidity
174
182
/**
175
183
* @notice Returns the latest release for an operator set.
184
+
* @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade.
176
185
* @param operatorSet The operator set to query.
177
186
* @return The id of the latest release.
178
187
* @return The latest release.
@@ -188,14 +197,16 @@ function getLatestRelease(
188
197
Retrieves the most recently published release for an operator set. This is typically the release that operators should be running or upgrading to.
189
198
190
199
*Returns*:
191
-
* The latest `Release` struct from the operator set's release array
192
-
* Reverts if no releases have been published for the operator set
200
+
* The release ID and the latest `Release` struct from the operator set's release array
201
+
* If `upgradeByTime` is 0, this indicates an instant upgrade requirement
202
+
* Reverts with `NoReleases()` if no releases have been published for the operator set
193
203
194
204
#### `getLatestUpgradeByTime`
195
205
196
206
```solidity
197
207
/**
198
208
* @notice Returns the upgrade by time for the latest release.
209
+
* @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade.
199
210
* @param operatorSet The operator set to query.
200
211
* @return The upgrade by time for the latest release.
201
212
*/
@@ -204,14 +215,15 @@ function getLatestUpgradeByTime(
204
215
)
205
216
external
206
217
view
207
-
returns (uint256)
218
+
returns (uint32)
208
219
```
209
220
210
221
A convenience function that returns just the upgrade deadline from the latest release. This can be useful for quickly checking when operators must complete their upgrades.
211
222
212
223
*Returns*:
213
224
* The `upgradeByTime` timestamp from the latest release
214
-
* Reverts if no releases have been published for the operator set
225
+
* A value of 0 indicates an instant upgrade requirement
226
+
* Reverts with `NoReleases()` if no releases have been published for the operator set
215
227
216
228
#### `isValidRelease`
217
229
@@ -238,6 +250,17 @@ Checks whether a given release ID corresponds to the latest release for an opera
238
250
*Returns*:
239
251
*`true` if the `releaseId` matches the latest release index
240
252
*`false` if the `releaseId` refers to an older release
241
-
* Reverts if the operator set has no releases
253
+
* Reverts with `NoReleases()` if the operator set has no releases
254
+
255
+
---
256
+
257
+
## Error Definitions
258
+
259
+
The `ReleaseManager` defines the following custom errors:
260
+
261
+
*`MustPublishMetadataURI()`: Thrown when attempting to publish a release for an operator set that hasn't published its metadata URI via `updateOperatorSetMetadataURI`.
262
+
*`InvalidUpgradeByTime()`: Thrown when the `upgradeByTime` is in the past (not including 0, which is valid for instant upgrades).
263
+
*`InvalidMetadataURI()`: Thrown when the metadata URI is empty.
264
+
*`NoReleases()`: Thrown when querying release information for an operator set that has no published releases.
0 commit comments