From 500eff1ced4102193f70a9a5c922aa94419edc63 Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Wed, 13 Aug 2025 18:28:40 -0400 Subject: [PATCH 1/5] fix: release manager no releases --- src/contracts/core/ReleaseManager.sol | 6 +++++- src/test/unit/ReleaseManagerUnit.t.sol | 9 +++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/contracts/core/ReleaseManager.sol b/src/contracts/core/ReleaseManager.sol index 6c571c6120..771f8deb07 100644 --- a/src/contracts/core/ReleaseManager.sol +++ b/src/contracts/core/ReleaseManager.sol @@ -89,13 +89,17 @@ contract ReleaseManager is Initializable, ReleaseManagerStorage, PermissionContr OperatorSet memory operatorSet ) external view returns (uint32) { Release[] storage releases = _operatorSetReleases[operatorSet.key()]; + require(releases.length > 0, NoReleases()); + uint256 latestReleaseId = releases.length - 1; return releases[latestReleaseId].upgradeByTime; } /// @inheritdoc IReleaseManager function isValidRelease(OperatorSet memory operatorSet, uint256 releaseId) external view returns (bool) { - return releaseId == getTotalReleases(operatorSet) - 1; + uint256 totalReleases = getTotalReleases(operatorSet); + require(totalReleases > 0, NoReleases()); + return releaseId == totalReleases - 1; } /// @inheritdoc IReleaseManager diff --git a/src/test/unit/ReleaseManagerUnit.t.sol b/src/test/unit/ReleaseManagerUnit.t.sol index 5989eeece0..3348a8449f 100644 --- a/src/test/unit/ReleaseManagerUnit.t.sol +++ b/src/test/unit/ReleaseManagerUnit.t.sol @@ -330,8 +330,7 @@ contract ReleaseManagerUnitTests_getRelease is ReleaseManagerUnitTests { contract ReleaseManagerUnitTests_getLatestRelease is ReleaseManagerUnitTests { function test_revert_getLatestRelease_noReleases() public { - // Should revert with underflow - vm.expectRevert(); + vm.expectRevert(NoReleases.selector); releaseManager.getLatestRelease(defaultOperatorSet); } @@ -444,8 +443,7 @@ contract ReleaseManagerUnitTests_EdgeCases is ReleaseManagerUnitTests { contract ReleaseManagerUnitTests_getLatestUpgradeByTime is ReleaseManagerUnitTests { function test_revert_getLatestUpgradeByTime_noReleases() public { - // Should revert with underflow - vm.expectRevert(); + vm.expectRevert(NoReleases.selector); releaseManager.getLatestUpgradeByTime(defaultOperatorSet); } @@ -471,8 +469,7 @@ contract ReleaseManagerUnitTests_getLatestUpgradeByTime is ReleaseManagerUnitTes contract ReleaseManagerUnitTests_isValidRelease is ReleaseManagerUnitTests { function test_revert_isValidRelease_noReleases() public { - // Should revert with underflow - vm.expectRevert(); + vm.expectRevert(NoReleases.selector); releaseManager.isValidRelease(defaultOperatorSet, 0); } From 391bd6c9853c601fc01e655811f58d9a691707a3 Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Wed, 13 Aug 2025 18:58:52 -0400 Subject: [PATCH 2/5] feat: instant upgrade --- src/contracts/core/ReleaseManager.sol | 2 +- src/contracts/interfaces/IReleaseManager.sol | 4 ++++ src/test/unit/ReleaseManagerUnit.t.sol | 25 +++++++++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/contracts/core/ReleaseManager.sol b/src/contracts/core/ReleaseManager.sol index 771f8deb07..35fa604f88 100644 --- a/src/contracts/core/ReleaseManager.sol +++ b/src/contracts/core/ReleaseManager.sol @@ -35,7 +35,7 @@ contract ReleaseManager is Initializable, ReleaseManagerStorage, PermissionContr Release[] storage releases = _operatorSetReleases[operatorSet.key()]; require(bytes(_operatorSetMetadataURI[operatorSet.key()]).length != 0, MustPublishMetadataURI()); - require(release.upgradeByTime >= block.timestamp, InvalidUpgradeByTime()); + require(release.upgradeByTime == 0 || release.upgradeByTime >= block.timestamp, InvalidUpgradeByTime()); // New release id is the length of the array before this call. releaseId = releases.length; diff --git a/src/contracts/interfaces/IReleaseManager.sol b/src/contracts/interfaces/IReleaseManager.sol index b4fea3e548..dc7d5477af 100644 --- a/src/contracts/interfaces/IReleaseManager.sol +++ b/src/contracts/interfaces/IReleaseManager.sol @@ -56,6 +56,7 @@ interface IReleaseManager is IReleaseManagerErrors, IReleaseManagerEvents { */ /// @notice Publishes a new release for an operator set. + /// @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade. /// @param operatorSet The operator set this release is for. /// @param release The release that was published. /// @return releaseId The index of the newly published release. @@ -83,12 +84,14 @@ interface IReleaseManager is IReleaseManagerErrors, IReleaseManagerEvents { ) external view returns (uint256); /// @notice Returns a specific release by index. + /// @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade. /// @param operatorSet The operator set to query. /// @param releaseId The id of the release to get. /// @return The release at the specified index. function getRelease(OperatorSet memory operatorSet, uint256 releaseId) external view returns (Release memory); /// @notice Returns the latest release for an operator set. + /// @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade. /// @param operatorSet The operator set to query. /// @return The id of the latest release. /// @return The latest release. @@ -97,6 +100,7 @@ interface IReleaseManager is IReleaseManagerErrors, IReleaseManagerEvents { ) external view returns (uint256, Release memory); /// @notice Returns the upgrade by time for the latest release. + /// @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade. /// @param operatorSet The operator set to query. /// @return The upgrade by time for the latest release. function getLatestUpgradeByTime( diff --git a/src/test/unit/ReleaseManagerUnit.t.sol b/src/test/unit/ReleaseManagerUnit.t.sol index 3348a8449f..6d2bc6ab96 100644 --- a/src/test/unit/ReleaseManagerUnit.t.sol +++ b/src/test/unit/ReleaseManagerUnit.t.sol @@ -41,6 +41,8 @@ contract ReleaseManagerUnitTests is EigenLayerUnitTestSetup, IReleaseManagerErro function setUp() public virtual override { EigenLayerUnitTestSetup.setUp(); + vm.warp(1 days); + // Deploy ReleaseManager releaseManager = new ReleaseManager(permissionController, "1.0.0"); @@ -127,7 +129,15 @@ contract ReleaseManagerUnitTests_publishRelease is ReleaseManagerUnitTests { releaseManager.publishRelease(defaultOperatorSet, pastRelease); } - function test_revert_upgradeByTimeEqualToNow() public { + function test_UpgradeByTimeEqualToZero() public { + // Create release with upgradeByTime 0 + Release memory instantUpgradeRelease = _createRelease(defaultArtifacts, 0); + + uint releaseId = releaseManager.publishRelease(defaultOperatorSet, instantUpgradeRelease); + assertEq(releaseId, 0, "first release should have ID 0"); + } + + function test_UpgradeByTimeEqualToNow() public { // Create release with current timestamp (edge case) Release memory currentRelease = _createRelease(defaultArtifacts, uint32(block.timestamp)); @@ -163,6 +173,19 @@ contract ReleaseManagerUnitTests_publishRelease is ReleaseManagerUnitTests { assertEq(releaseManager.getTotalReleases(defaultOperatorSet), 1, "should have 1 release"); } + function testFuzz_publishUpgradeByTime(uint upgradeByTime) public { + upgradeByTime = bound(upgradeByTime, 0, type(uint32).max); + Release memory release = _createReleaseWithArtifacts(2, uint32(upgradeByTime)); + + if (upgradeByTime > 0 && upgradeByTime < block.timestamp) { + vm.expectRevert(InvalidUpgradeByTime.selector); + _publishRelease(defaultOperatorSet, release); + } else { + uint releaseId = _publishRelease(defaultOperatorSet, release); + assertEq(releaseId, 0, "first release should have ID 0"); + } + } + function testFuzz_publishMultipleReleases(uint numReleases) public { numReleases = bound(numReleases, 1, FUZZ_MAX_RELEASES); From cff01532852c1d6222f2c69db5580399b2bccb28 Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Wed, 13 Aug 2025 19:03:46 -0400 Subject: [PATCH 3/5] chore: remove unnecessary import --- src/contracts/core/ReleaseManagerStorage.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/src/contracts/core/ReleaseManagerStorage.sol b/src/contracts/core/ReleaseManagerStorage.sol index 1be2f78e99..149355b5ab 100644 --- a/src/contracts/core/ReleaseManagerStorage.sol +++ b/src/contracts/core/ReleaseManagerStorage.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.27; import "../interfaces/IReleaseManager.sol"; -import "../interfaces/IAllocationManager.sol"; abstract contract ReleaseManagerStorage is IReleaseManager { // Mutables From 125657183dca09dbba3311c90886a19ef14d8afc Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Wed, 13 Aug 2025 19:07:34 -0400 Subject: [PATCH 4/5] chore: updated bindings --- pkg/bindings/ReleaseManager/binding.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/bindings/ReleaseManager/binding.go b/pkg/bindings/ReleaseManager/binding.go index cf0dabb12a..52737b0390 100644 --- a/pkg/bindings/ReleaseManager/binding.go +++ b/pkg/bindings/ReleaseManager/binding.go @@ -50,7 +50,7 @@ type OperatorSet struct { // ReleaseManagerMetaData contains all meta data concerning the ReleaseManager contract. var ReleaseManagerMetaData = &bind.MetaData{ ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_permissionController\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"},{\"name\":\"_version\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getLatestRelease\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getLatestUpgradeByTime\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMetadataURI\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRelease\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"releaseId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTotalReleases\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isValidRelease\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"releaseId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"permissionController\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPermissionController\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"publishMetadataURI\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"publishRelease\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"release\",\"type\":\"tuple\",\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"outputs\":[{\"name\":\"releaseId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MetadataURIPublished\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"indexed\":true,\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"metadataURI\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ReleasePublished\",\"inputs\":[{\"name\":\"operatorSet\",\"type\":\"tuple\",\"indexed\":true,\"internalType\":\"structOperatorSet\",\"components\":[{\"name\":\"avs\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"releaseId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"release\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIReleaseManagerTypes.Release\",\"components\":[{\"name\":\"artifacts\",\"type\":\"tuple[]\",\"internalType\":\"structIReleaseManagerTypes.Artifact[]\",\"components\":[{\"name\":\"digest\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registry\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"name\":\"upgradeByTime\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"InvalidMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPermissions\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidShortString\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidUpgradeByTime\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MustPublishMetadataURI\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoReleases\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StringTooLong\",\"inputs\":[{\"name\":\"str\",\"type\":\"string\",\"internalType\":\"string\"}]}]", - Bin: "0x60c060405234801561000f575f5ffd5b5060405161162638038061162683398101604081905261002e9161016a565b6001600160a01b0382166080528061004581610058565b60a0525061005161009e565b5050610294565b5f5f829050601f8151111561008b578260405163305a27a960e01b81526004016100829190610239565b60405180910390fd5b80516100968261026e565b179392505050565b5f54610100900460ff16156101055760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608401610082565b5f5460ff90811614610154575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b634e487b7160e01b5f52604160045260245ffd5b5f5f6040838503121561017b575f5ffd5b82516001600160a01b0381168114610191575f5ffd5b60208401519092506001600160401b038111156101ac575f5ffd5b8301601f810185136101bc575f5ffd5b80516001600160401b038111156101d5576101d5610156565b604051601f8201601f19908116603f011681016001600160401b038111828210171561020357610203610156565b60405281815282820160200187101561021a575f5ffd5b8160208401602083015e5f602083830101528093505050509250929050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b8051602080830151919081101561028e575f198160200360031b1b821691505b50919050565b60805160a05161136b6102bb5f395f61044e01525f818160cd015261094b015261136b5ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806366f409f71161006357806366f409f7146101545780637c09ea8214610175578063a9e0ed6814610188578063b053b56d146101b0578063d30eeb88146101c3575f5ffd5b80633acab5fc1461009f5780634657e26a146100c85780634840a67c14610107578063517e40681461011c57806354fd4d501461013f575b5f5ffd5b6100b26100ad366004610ac8565b6101e4565b6040516100bf9190610bb4565b60405180910390f35b6100ef7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100bf565b61011a610115366004610be3565b610348565b005b61012f61012a366004610ac8565b610428565b60405190151581526020016100bf565b610147610447565b6040516100bf9190610c62565b610167610162366004610c74565b610477565b6040519081526020016100bf565b610167610183366004610c8e565b61049a565b61019b610196366004610c74565b6105f5565b60405163ffffffff90911681526020016100bf565b6101476101be366004610c74565b610659565b6101d66101d1366004610c74565b610702565b6040516100bf929190610cda565b60408051808201909152606081525f602082015260015f610204856108aa565b81526020019081526020015f20828154811061022257610222610cfa565b905f5260205f2090600202016040518060400160405290815f8201805480602002602001604051908101604052809291908181526020015f905b82821015610325578382905f5260205f2090600202016040518060400160405290815f820154815260200160018201805461029690610d0e565b80601f01602080910402602001604051908101604052809291908181526020018280546102c290610d0e565b801561030d5780601f106102e45761010080835404028352916020019161030d565b820191905f5260205f20905b8154815290600101906020018083116102f057829003601f168201915b5050505050815250508152602001906001019061025c565b505050908252506001919091015463ffffffff1660209091015290505b92915050565b6103556020840184610d40565b61035e8161090d565b61037b5760405163932d94f760e01b815260040160405180910390fd5b5f82900361039c57604051630eec403f60e41b815260040160405180910390fd5b828260025f6103b86103b3368a90038a018a610c74565b6108aa565b81526020019081526020015f2091826103d2929190610db0565b50836040516103e19190610e6a565b60405180910390207f209e95fbe8dd14c5e1fbf791ee0a83234f45f20cb85504c7068d5ca0d6224588848460405161041a929190610ec9565b60405180910390a250505050565b5f600161043484610477565b61043e9190610ef0565b90911492915050565b60606104727f00000000000000000000000000000000000000000000000000000000000000006109b7565b905090565b5f60015f610484846108aa565b815260208101919091526040015f205492915050565b5f6104a86020840184610d40565b6104b18161090d565b6104ce5760405163932d94f760e01b815260040160405180910390fd5b5f6001816104e46103b336899003890189610c74565b81526020019081526020015f20905060025f61050a878036038101906103b39190610c74565b81526020019081526020015f20805461052290610d0e565b90505f036105435760405163413e6e5760e11b815260040160405180910390fd5b426105546040860160208701610f03565b63ffffffff1610156105795760405163325ec75f60e01b815260040160405180910390fd5b80546001810182555f828152602090209093508490600285020161059d8282611041565b505082856040516105ae9190610e6a565b60405180910390207f2decd15222f7c4a8c3d4d2e14dcfdc5a0b52eb2d4b81796bfd010ee5cd972fd3866040516105e591906111cc565b60405180910390a3505092915050565b5f5f60015f610603856108aa565b81526020019081526020015f2090505f600182805490506106249190610ef0565b905081818154811061063857610638610cfa565b5f91825260209091206001600290920201015463ffffffff16949350505050565b606060025f610667846108aa565b81526020019081526020015f20805461067f90610d0e565b80601f01602080910402602001604051908101604052809291908181526020018280546106ab90610d0e565b80156106f65780601f106106cd576101008083540402835291602001916106f6565b820191905f5260205f20905b8154815290600101906020018083116106d957829003601f168201915b50505050509050919050565b60408051808201909152606081525f60208201819052905f60015f610726866108aa565b81526020019081526020015f2090505f81805490501161075957604051637a31a0a160e11b815260040160405180910390fd5b80545f9061076990600190610ef0565b90508082828154811061077e5761077e610cfa565b905f5260205f209060020201806040518060400160405290815f8201805480602002602001604051908101604052809291908181526020015f905b82821015610882578382905f5260205f2090600202016040518060400160405290815f82015481526020016001820180546107f390610d0e565b80601f016020809104026020016040519081016040528092919081815260200182805461081f90610d0e565b801561086a5780601f106108415761010080835404028352916020019161086a565b820191905f5260205f20905b81548152906001019060200180831161084d57829003601f168201915b505050505081525050815260200190600101906107b9565b505050908252506001919091015463ffffffff16602090910152919791965090945050505050565b5f815f0151826020015163ffffffff166040516020016108f592919060609290921b6bffffffffffffffffffffffff1916825260a01b6001600160a01b031916601482015260200190565b604051602081830303815290604052610342906112f3565b604051631beb2b9760e31b81526001600160a01b0382811660048301523360248301523060448301525f80356001600160e01b0319166064840152917f00000000000000000000000000000000000000000000000000000000000000009091169063df595cb8906084016020604051808303815f875af1158015610993573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103429190611316565b60605f6109c3836109f4565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f60ff8216601f81111561034257604051632cd44ac360e21b815260040160405180910390fd5b634e487b7160e01b5f52604160045260245ffd5b80356001600160a01b0381168114610a45575f5ffd5b919050565b63ffffffff81168114610a5b575f5ffd5b50565b8035610a4581610a4a565b5f60408284031215610a79575f5ffd5b6040516040810181811067ffffffffffffffff82111715610a9c57610a9c610a1b565b604052905080610aab83610a2f565b81526020830135610abb81610a4a565b6020919091015292915050565b5f5f60608385031215610ad9575f5ffd5b610ae38484610a69565b946040939093013593505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6040830182516040855281815180845260608701915060608160051b88010193506020830192505f5b81811015610b9157605f198886030183528351805186526020810151905060406020870152610b7b6040870182610af1565b9550506020938401939290920191600101610b49565b505050506020830151610bac602086018263ffffffff169052565b509392505050565b602081525f610bc66020830184610b1f565b9392505050565b5f60408284031215610bdd575f5ffd5b50919050565b5f5f5f60608486031215610bf5575f5ffd5b610bff8585610bcd565b9250604084013567ffffffffffffffff811115610c1a575f5ffd5b8401601f81018613610c2a575f5ffd5b803567ffffffffffffffff811115610c40575f5ffd5b866020828401011115610c51575f5ffd5b939660209190910195509293505050565b602081525f610bc66020830184610af1565b5f60408284031215610c84575f5ffd5b610bc68383610a69565b5f5f60608385031215610c9f575f5ffd5b610ca98484610bcd565b9150604083013567ffffffffffffffff811115610cc4575f5ffd5b610cd085828601610bcd565b9150509250929050565b828152604060208201525f610cf26040830184610b1f565b949350505050565b634e487b7160e01b5f52603260045260245ffd5b600181811c90821680610d2257607f821691505b602082108103610bdd57634e487b7160e01b5f52602260045260245ffd5b5f60208284031215610d50575f5ffd5b610bc682610a2f565b5b81811015610d6d575f8155600101610d5a565b5050565b601f821115610dab57805f5260205f20601f840160051c81016020851015610d965750805b610da8601f850160051c830182610d59565b50505b505050565b67ffffffffffffffff831115610dc857610dc8610a1b565b610ddc83610dd68354610d0e565b83610d71565b5f601f841160018114610e0d575f8515610df65750838201355b5f19600387901b1c1916600186901b178355610da8565b5f83815260208120601f198716915b82811015610e3c5786850135825560209485019460019092019101610e1c565b5086821015610e58575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6001600160a01b03610e7b83610a2f565b1681525f6020830135610e8d81610a4a565b63ffffffff16602083015250604001919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f610cf2602083018486610ea1565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561034257610342610edc565b5f60208284031215610f13575f5ffd5b8135610bc681610a4a565b5f8235603e19833603018112610f32575f5ffd5b9190910192915050565b81358155600181016020830135601e19843603018112610f5a575f5ffd5b8301803567ffffffffffffffff81118015610f73575f5ffd5b813603602084011315610f84575f5ffd5b5f905050610f9c81610f968554610d0e565b85610d71565b5f601f821160018114610fd0575f8315610fb95750838201602001355b5f19600385901b1c1916600184901b17855561102c565b5f85815260208120601f198516915b8281101561100157602085880181013583559485019460019092019101610fdf565b5084821015611020575f1960f88660031b161c19602085880101351681555b505060018360011b0185555b50505050505050565b5f813561034281610a4a565b8135601e19833603018112611054575f5ffd5b8201803567ffffffffffffffff81111561106c575f5ffd5b6020820191508060051b3603821315611083575f5ffd5b6801000000000000000081111561109c5761109c610a1b565b825481845580821015611160576001600160ff1b03811681146110c1576110c1610edc565b6001600160ff1b03821682146110d9576110d9610edc565b835f5260205f208160011b81018360011b820191505b8082101561115d575f825560018201805461110990610d0e565b801561115057601f811160018114611123575f835561114e565b5f83815260209020611140601f840160051c820160018301610d59565b505f83815260208120818555555b505b50506002820191506110ef565b50505b505f8381526020812083915b8381101561119d576111876111818487610f1e565b83610f3c565b602092909201916002919091019060010161116c565b5050505050610d6d6111b160208401611035565b6001830163ffffffff821663ffffffff198254161781555050565b602081525f606082018335601e198536030181126111e8575f5ffd5b840180356020820167ffffffffffffffff821115611204575f5ffd5b8160051b803603821315611216575f5ffd5b604060208801529382905260809386018401935f908701605e1936869003015b848310156112d057888703607f190182528335818112611254575f5ffd5b860160208101358852604081013536829003603e19018112611274575f5ffd5b0160408101906020013567ffffffffffffffff811115611292575f5ffd5b8036038213156112a0575f5ffd5b604060208a01526112b560408a018284610ea1565b98505050602084019350602082019150600183019250611236565b5050505050506112e260208501610a5e565b63ffffffff81166040850152610bac565b80516020808301519190811015610bdd575f1960209190910360031b1b16919050565b5f60208284031215611326575f5ffd5b81518015158114610bc6575f5ffdfea26469706673582212206f95f65c17c774133426c7f33fa0eb275499e1a13fc809307867f97b3fc16bf764736f6c634300081b0033", + Bin: "0x60c060405234801561000f575f5ffd5b5060405161168938038061168983398101604081905261002e9161016a565b6001600160a01b0382166080528061004581610058565b60a0525061005161009e565b5050610294565b5f5f829050601f8151111561008b578260405163305a27a960e01b81526004016100829190610239565b60405180910390fd5b80516100968261026e565b179392505050565b5f54610100900460ff16156101055760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608401610082565b5f5460ff90811614610154575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b634e487b7160e01b5f52604160045260245ffd5b5f5f6040838503121561017b575f5ffd5b82516001600160a01b0381168114610191575f5ffd5b60208401519092506001600160401b038111156101ac575f5ffd5b8301601f810185136101bc575f5ffd5b80516001600160401b038111156101d5576101d5610156565b604051601f8201601f19908116603f011681016001600160401b038111828210171561020357610203610156565b60405281815282820160200187101561021a575f5ffd5b8160208401602083015e5f602083830101528093505050509250929050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b8051602080830151919081101561028e575f198160200360031b1b821691505b50919050565b60805160a0516113ce6102bb5f395f61047101525f818160cd01526109ae01526113ce5ff3fe608060405234801561000f575f5ffd5b506004361061009b575f3560e01c806366f409f71161006357806366f409f7146101545780637c09ea8214610175578063a9e0ed6814610188578063b053b56d146101b0578063d30eeb88146101c3575f5ffd5b80633acab5fc1461009f5780634657e26a146100c85780634840a67c14610107578063517e40681461011c57806354fd4d501461013f575b5f5ffd5b6100b26100ad366004610b2b565b6101e4565b6040516100bf9190610c17565b60405180910390f35b6100ef7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100bf565b61011a610115366004610c46565b610348565b005b61012f61012a366004610b2b565b610428565b60405190151581526020016100bf565b61014761046a565b6040516100bf9190610cc5565b610167610162366004610cd7565b61049a565b6040519081526020016100bf565b610167610183366004610cf1565b6104bd565b61019b610196366004610cd7565b610636565b60405163ffffffff90911681526020016100bf565b6101476101be366004610cd7565b6106bc565b6101d66101d1366004610cd7565b610765565b6040516100bf929190610d3d565b60408051808201909152606081525f602082015260015f6102048561090d565b81526020019081526020015f20828154811061022257610222610d5d565b905f5260205f2090600202016040518060400160405290815f8201805480602002602001604051908101604052809291908181526020015f905b82821015610325578382905f5260205f2090600202016040518060400160405290815f820154815260200160018201805461029690610d71565b80601f01602080910402602001604051908101604052809291908181526020018280546102c290610d71565b801561030d5780601f106102e45761010080835404028352916020019161030d565b820191905f5260205f20905b8154815290600101906020018083116102f057829003601f168201915b5050505050815250508152602001906001019061025c565b505050908252506001919091015463ffffffff1660209091015290505b92915050565b6103556020840184610da3565b61035e81610970565b61037b5760405163932d94f760e01b815260040160405180910390fd5b5f82900361039c57604051630eec403f60e41b815260040160405180910390fd5b828260025f6103b86103b3368a90038a018a610cd7565b61090d565b81526020019081526020015f2091826103d2929190610e13565b50836040516103e19190610ecd565b60405180910390207f209e95fbe8dd14c5e1fbf791ee0a83234f45f20cb85504c7068d5ca0d6224588848460405161041a929190610f2c565b60405180910390a250505050565b5f5f6104338461049a565b90505f811161045557604051637a31a0a160e11b815260040160405180910390fd5b610460600182610f53565b9092149392505050565b60606104957f0000000000000000000000000000000000000000000000000000000000000000610a1a565b905090565b5f60015f6104a78461090d565b815260208101919091526040015f205492915050565b5f6104cb6020840184610da3565b6104d481610970565b6104f15760405163932d94f760e01b815260040160405180910390fd5b5f6001816105076103b336899003890189610cd7565b81526020019081526020015f20905060025f61052d878036038101906103b39190610cd7565b81526020019081526020015f20805461054590610d71565b90505f036105665760405163413e6e5760e11b815260040160405180910390fd5b6105766040850160208601610f66565b63ffffffff16158061059d5750426105946040860160208701610f66565b63ffffffff1610155b6105ba5760405163325ec75f60e01b815260040160405180910390fd5b80546001810182555f82815260209020909350849060028502016105de82826110a4565b505082856040516105ef9190610ecd565b60405180910390207f2decd15222f7c4a8c3d4d2e14dcfdc5a0b52eb2d4b81796bfd010ee5cd972fd386604051610626919061122f565b60405180910390a3505092915050565b5f5f60015f6106448561090d565b81526020019081526020015f2090505f81805490501161067757604051637a31a0a160e11b815260040160405180910390fd5b80545f9061068790600190610f53565b905081818154811061069b5761069b610d5d565b5f91825260209091206001600290920201015463ffffffff16949350505050565b606060025f6106ca8461090d565b81526020019081526020015f2080546106e290610d71565b80601f016020809104026020016040519081016040528092919081815260200182805461070e90610d71565b80156107595780601f1061073057610100808354040283529160200191610759565b820191905f5260205f20905b81548152906001019060200180831161073c57829003601f168201915b50505050509050919050565b60408051808201909152606081525f60208201819052905f60015f6107898661090d565b81526020019081526020015f2090505f8180549050116107bc57604051637a31a0a160e11b815260040160405180910390fd5b80545f906107cc90600190610f53565b9050808282815481106107e1576107e1610d5d565b905f5260205f209060020201806040518060400160405290815f8201805480602002602001604051908101604052809291908181526020015f905b828210156108e5578382905f5260205f2090600202016040518060400160405290815f820154815260200160018201805461085690610d71565b80601f016020809104026020016040519081016040528092919081815260200182805461088290610d71565b80156108cd5780601f106108a4576101008083540402835291602001916108cd565b820191905f5260205f20905b8154815290600101906020018083116108b057829003601f168201915b5050505050815250508152602001906001019061081c565b505050908252506001919091015463ffffffff16602090910152919791965090945050505050565b5f815f0151826020015163ffffffff1660405160200161095892919060609290921b6bffffffffffffffffffffffff1916825260a01b6001600160a01b031916601482015260200190565b60405160208183030381529060405261034290611356565b604051631beb2b9760e31b81526001600160a01b0382811660048301523360248301523060448301525f80356001600160e01b0319166064840152917f00000000000000000000000000000000000000000000000000000000000000009091169063df595cb8906084016020604051808303815f875af11580156109f6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103429190611379565b60605f610a2683610a57565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f60ff8216601f81111561034257604051632cd44ac360e21b815260040160405180910390fd5b634e487b7160e01b5f52604160045260245ffd5b80356001600160a01b0381168114610aa8575f5ffd5b919050565b63ffffffff81168114610abe575f5ffd5b50565b8035610aa881610aad565b5f60408284031215610adc575f5ffd5b6040516040810181811067ffffffffffffffff82111715610aff57610aff610a7e565b604052905080610b0e83610a92565b81526020830135610b1e81610aad565b6020919091015292915050565b5f5f60608385031215610b3c575f5ffd5b610b468484610acc565b946040939093013593505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6040830182516040855281815180845260608701915060608160051b88010193506020830192505f5b81811015610bf457605f198886030183528351805186526020810151905060406020870152610bde6040870182610b54565b9550506020938401939290920191600101610bac565b505050506020830151610c0f602086018263ffffffff169052565b509392505050565b602081525f610c296020830184610b82565b9392505050565b5f60408284031215610c40575f5ffd5b50919050565b5f5f5f60608486031215610c58575f5ffd5b610c628585610c30565b9250604084013567ffffffffffffffff811115610c7d575f5ffd5b8401601f81018613610c8d575f5ffd5b803567ffffffffffffffff811115610ca3575f5ffd5b866020828401011115610cb4575f5ffd5b939660209190910195509293505050565b602081525f610c296020830184610b54565b5f60408284031215610ce7575f5ffd5b610c298383610acc565b5f5f60608385031215610d02575f5ffd5b610d0c8484610c30565b9150604083013567ffffffffffffffff811115610d27575f5ffd5b610d3385828601610c30565b9150509250929050565b828152604060208201525f610d556040830184610b82565b949350505050565b634e487b7160e01b5f52603260045260245ffd5b600181811c90821680610d8557607f821691505b602082108103610c4057634e487b7160e01b5f52602260045260245ffd5b5f60208284031215610db3575f5ffd5b610c2982610a92565b5b81811015610dd0575f8155600101610dbd565b5050565b601f821115610e0e57805f5260205f20601f840160051c81016020851015610df95750805b610e0b601f850160051c830182610dbc565b50505b505050565b67ffffffffffffffff831115610e2b57610e2b610a7e565b610e3f83610e398354610d71565b83610dd4565b5f601f841160018114610e70575f8515610e595750838201355b5f19600387901b1c1916600186901b178355610e0b565b5f83815260208120601f198716915b82811015610e9f5786850135825560209485019460019092019101610e7f565b5086821015610ebb575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6001600160a01b03610ede83610a92565b1681525f6020830135610ef081610aad565b63ffffffff16602083015250604001919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f610d55602083018486610f04565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561034257610342610f3f565b5f60208284031215610f76575f5ffd5b8135610c2981610aad565b5f8235603e19833603018112610f95575f5ffd5b9190910192915050565b81358155600181016020830135601e19843603018112610fbd575f5ffd5b8301803567ffffffffffffffff81118015610fd6575f5ffd5b813603602084011315610fe7575f5ffd5b5f905050610fff81610ff98554610d71565b85610dd4565b5f601f821160018114611033575f831561101c5750838201602001355b5f19600385901b1c1916600184901b17855561108f565b5f85815260208120601f198516915b8281101561106457602085880181013583559485019460019092019101611042565b5084821015611083575f1960f88660031b161c19602085880101351681555b505060018360011b0185555b50505050505050565b5f813561034281610aad565b8135601e198336030181126110b7575f5ffd5b8201803567ffffffffffffffff8111156110cf575f5ffd5b6020820191508060051b36038213156110e6575f5ffd5b680100000000000000008111156110ff576110ff610a7e565b8254818455808210156111c3576001600160ff1b038116811461112457611124610f3f565b6001600160ff1b038216821461113c5761113c610f3f565b835f5260205f208160011b81018360011b820191505b808210156111c0575f825560018201805461116c90610d71565b80156111b357601f811160018114611186575f83556111b1565b5f838152602090206111a3601f840160051c820160018301610dbc565b505f83815260208120818555555b505b5050600282019150611152565b50505b505f8381526020812083915b83811015611200576111ea6111e48487610f81565b83610f9f565b60209290920191600291909101906001016111cf565b5050505050610dd061121460208401611098565b6001830163ffffffff821663ffffffff198254161781555050565b602081525f606082018335601e1985360301811261124b575f5ffd5b840180356020820167ffffffffffffffff821115611267575f5ffd5b8160051b803603821315611279575f5ffd5b604060208801529382905260809386018401935f908701605e1936869003015b8483101561133357888703607f1901825283358181126112b7575f5ffd5b860160208101358852604081013536829003603e190181126112d7575f5ffd5b0160408101906020013567ffffffffffffffff8111156112f5575f5ffd5b803603821315611303575f5ffd5b604060208a015261131860408a018284610f04565b98505050602084019350602082019150600183019250611299565b50505050505061134560208501610ac1565b63ffffffff81166040850152610c0f565b80516020808301519190811015610c40575f1960209190910360031b1b16919050565b5f60208284031215611389575f5ffd5b81518015158114610c29575f5ffdfea2646970667358221220f1938456ad8d2d303bf481c8f8ea6843aca2e496f62bad34d6803681f2c3b74164736f6c634300081b0033", } // ReleaseManagerABI is the input ABI used to generate the binding from. From e093c1a9649c4ca235c1ba6d108c6c147b48f4ff Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Wed, 13 Aug 2025 19:16:15 -0400 Subject: [PATCH 5/5] docs: updated release manager docs --- docs/core/ReleaseManager.md | 37 ++++++++++++++++---- src/contracts/interfaces/IReleaseManager.sol | 2 +- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/docs/core/ReleaseManager.md b/docs/core/ReleaseManager.md index be620a49d7..f3d7c08459 100644 --- a/docs/core/ReleaseManager.md +++ b/docs/core/ReleaseManager.md @@ -31,6 +31,7 @@ An AVS in the context of `ReleaseManager` is defined as the `address` of the con * **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. * **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. +* **Instant Upgrades**: When `upgradeByTime` is set to 0, this signals an instant upgrade requirement. * **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. --- @@ -58,7 +59,8 @@ struct Artifact { /** * @notice Represents a release containing multiple artifacts and an upgrade deadline. * @param artifacts Array of artifacts included in this release. - * @param upgradeByTime Timestamp by which operators must upgrade to this release. + * @param upgradeByTime Timestamp by which operators must upgrade to this release. + * A value of 0 signals an instant upgrade requirement. */ struct Release { Artifact[] artifacts; @@ -90,6 +92,7 @@ mapping(bytes32 operatorSetKey => Release[]) internal _operatorSetReleases; ```solidity /** * @notice Publishes a new release for an operator set. + * @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade. * @param operatorSet The operator set this release is for. * @param release The release that was published. * @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 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. +**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. + 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). *Effects*: @@ -117,7 +122,8 @@ The `releaseId` returned is the zero-based index of the release in the operator *Requirements*: * Caller MUST be authorized, either as the AVS itself or an admin/appointee (see [`PermissionController.md`](../permissions/PermissionController.md)) -* `release.upgradeByTime` MUST be greater than or equal to the current block timestamp +* Operator set MUST have published metadata URI via `updateOperatorSetMetadataURI` +* `release.upgradeByTime` MUST be either 0 (instant upgrade) or greater than or equal to the current block timestamp --- ### View Functions @@ -149,6 +155,7 @@ Returns the total number of releases that have been published for the specified ```solidity /** * @notice Returns a specific release by index. + * @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade. * @param operatorSet The operator set to query. * @param releaseId The id of the release to get. * @return The release at the specified index. @@ -166,6 +173,7 @@ Retrieves a specific release by its ID for a given operator set. The `releaseId` *Returns*: * The complete `Release` struct including all artifacts and the upgrade deadline +* If `upgradeByTime` is 0, this indicates an instant upgrade requirement * Reverts if `releaseId` is out of bounds #### `getLatestRelease` @@ -173,6 +181,7 @@ Retrieves a specific release by its ID for a given operator set. The `releaseId` ```solidity /** * @notice Returns the latest release for an operator set. + * @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade. * @param operatorSet The operator set to query. * @return The id of the latest release. * @return The latest release. @@ -188,14 +197,16 @@ function getLatestRelease( Retrieves the most recently published release for an operator set. This is typically the release that operators should be running or upgrading to. *Returns*: -* The latest `Release` struct from the operator set's release array -* Reverts if no releases have been published for the operator set +* The release ID and the latest `Release` struct from the operator set's release array +* If `upgradeByTime` is 0, this indicates an instant upgrade requirement +* Reverts with `NoReleases()` if no releases have been published for the operator set #### `getLatestUpgradeByTime` ```solidity /** * @notice Returns the upgrade by time for the latest release. + * @dev If the upgradeByTime is 0, the release is meant to signal an instant upgrade. * @param operatorSet The operator set to query. * @return The upgrade by time for the latest release. */ @@ -204,14 +215,15 @@ function getLatestUpgradeByTime( ) external view - returns (uint256) + returns (uint32) ``` 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. *Returns*: * The `upgradeByTime` timestamp from the latest release -* Reverts if no releases have been published for the operator set +* A value of 0 indicates an instant upgrade requirement +* Reverts with `NoReleases()` if no releases have been published for the operator set #### `isValidRelease` @@ -238,6 +250,17 @@ Checks whether a given release ID corresponds to the latest release for an opera *Returns*: * `true` if the `releaseId` matches the latest release index * `false` if the `releaseId` refers to an older release -* Reverts if the operator set has no releases +* Reverts with `NoReleases()` if the operator set has no releases + +--- + +## Error Definitions + +The `ReleaseManager` defines the following custom errors: + +* `MustPublishMetadataURI()`: Thrown when attempting to publish a release for an operator set that hasn't published its metadata URI via `updateOperatorSetMetadataURI`. +* `InvalidUpgradeByTime()`: Thrown when the `upgradeByTime` is in the past (not including 0, which is valid for instant upgrades). +* `InvalidMetadataURI()`: Thrown when the metadata URI is empty. +* `NoReleases()`: Thrown when querying release information for an operator set that has no published releases. --- diff --git a/src/contracts/interfaces/IReleaseManager.sol b/src/contracts/interfaces/IReleaseManager.sol index dc7d5477af..8cf45c8493 100644 --- a/src/contracts/interfaces/IReleaseManager.sol +++ b/src/contracts/interfaces/IReleaseManager.sol @@ -28,7 +28,7 @@ interface IReleaseManagerTypes { /// @notice Represents a release containing multiple artifacts and an upgrade deadline. /// @param artifacts Array of artifacts included in this release. - /// @param upgradeByTime Timestamp by which operators must upgrade to this release. + /// @param upgradeByTime Timestamp by which operators must upgrade to this release. A value of 0 signals an instant upgrade requirement. struct Release { Artifact[] artifacts; uint32 upgradeByTime;