From 31cd1b131f0db6066e6d085d2e7c35b065eeb459 Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Fri, 21 Nov 2025 15:04:33 -0500 Subject: [PATCH 1/6] chore: rewards v2.2 upgrade scripts --- .../1-deployRewardsCoordinatorImpl.s.sol | 215 +++++++++++++++++ .../2-queueRewardsCoordinatorUpgrade.s.sol | 123 ++++++++++ .../3-executeRewardsCoordinatorUpgrade.s.sol | 224 ++++++++++++++++++ .../v1.10.0-rewards-v2.2/upgrade.json | 19 ++ 4 files changed, 581 insertions(+) create mode 100644 script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol create mode 100644 script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol create mode 100644 script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol create mode 100644 script/releases/v1.10.0-rewards-v2.2/upgrade.json diff --git a/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol b/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol new file mode 100644 index 0000000000..b2bbccf79d --- /dev/null +++ b/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import {EOADeployer} from "zeus-templates/templates/EOADeployer.sol"; +import "../Env.sol"; + +/** + * @title DeployRewardsCoordinatorImpl + * @notice Deploy new RewardsCoordinator implementation with Rewards v2.2 support. + * This adds support for: + * - Unique stake rewards submissions (rewards linear to allocated unique stake) + * - Total stake rewards submissions (rewards linear to total stake) + */ +contract DeployRewardsCoordinatorImpl is EOADeployer { + using Env for *; + + /// forgefmt: disable-next-item + function _runAsEOA() internal override { + // Only execute on source chains with version 1.9.0 + if (!(Env.isSourceChain() && Env._strEq(Env.envVersion(), "1.9.0"))) { + return; + } + + vm.startBroadcast(); + + // Deploy RewardsCoordinator implementation with the new MAX_FUTURE_LENGTH + deployImpl({ + name: type(RewardsCoordinator).name, + deployedTo: address( + new RewardsCoordinator( + IRewardsCoordinatorTypes.RewardsCoordinatorConstructorParams({ + delegationManager: Env.proxy.delegationManager(), + strategyManager: Env.proxy.strategyManager(), + allocationManager: Env.proxy.allocationManager(), + pauserRegistry: Env.impl.pauserRegistry(), + permissionController: Env.proxy.permissionController(), + CALCULATION_INTERVAL_SECONDS: Env.CALCULATION_INTERVAL_SECONDS(), + MAX_REWARDS_DURATION: Env.MAX_REWARDS_DURATION(), + MAX_RETROACTIVE_LENGTH: Env.MAX_RETROACTIVE_LENGTH(), + MAX_FUTURE_LENGTH: 63072000, // 730 days (2 years) + GENESIS_REWARDS_TIMESTAMP: Env.GENESIS_REWARDS_TIMESTAMP(), + version: Env.deployVersion() + }) + ) + ) + }); + + // Update the MAX_FUTURE_LENGTH environment variable + zUpdateUint32("REWARDS_COORDINATOR_MAX_FUTURE_LENGTH", 63072000); + + vm.stopBroadcast(); + } + + function testScript() public virtual { + if (!(Env.isSourceChain() && Env._strEq(Env.envVersion(), "1.9.0"))) { + return; + } + + // Deploy the new RewardsCoordinator implementation + runAsEOA(); + + _validateNewImplAddress(); + _validateProxyAdmin(); + _validateImplConstructor(); + _validateImplInitialized(); + _validateVersion(); + _validateNewFunctionality(); + _validateStorageLayout(); + } + + /// @dev Validate that the new RewardsCoordinator impl address is distinct from the current one + function _validateNewImplAddress() internal view { + address currentImpl = Env._getProxyImpl(address(Env.proxy.rewardsCoordinator())); + address newImpl = address(Env.impl.rewardsCoordinator()); + + assertFalse(currentImpl == newImpl, "RewardsCoordinator impl should be different from current implementation"); + } + + /// @dev Validate that the RewardsCoordinator proxy is still owned by the correct ProxyAdmin + function _validateProxyAdmin() internal view { + address pa = Env.proxyAdmin(); + + assertTrue( + Env._getProxyAdmin(address(Env.proxy.rewardsCoordinator())) == pa, "RewardsCoordinator proxyAdmin incorrect" + ); + } + + /// @dev Validate the immutables set in the new RewardsCoordinator implementation constructor + function _validateImplConstructor() internal view { + RewardsCoordinator rewardsCoordinatorImpl = Env.impl.rewardsCoordinator(); + + // Validate version + assertEq( + keccak256(bytes(rewardsCoordinatorImpl.version())), + keccak256(bytes(Env.deployVersion())), + "RewardsCoordinator impl version mismatch" + ); + + // Validate core dependencies + assertTrue( + address(rewardsCoordinatorImpl.delegationManager()) == address(Env.proxy.delegationManager()), + "RewardsCoordinator delegationManager mismatch" + ); + assertTrue( + address(rewardsCoordinatorImpl.strategyManager()) == address(Env.proxy.strategyManager()), + "RewardsCoordinator strategyManager mismatch" + ); + assertTrue( + address(rewardsCoordinatorImpl.allocationManager()) == address(Env.proxy.allocationManager()), + "RewardsCoordinator allocationManager mismatch" + ); + + // Validate reward parameters + assertEq( + rewardsCoordinatorImpl.CALCULATION_INTERVAL_SECONDS(), + Env.CALCULATION_INTERVAL_SECONDS(), + "CALCULATION_INTERVAL_SECONDS mismatch" + ); + assertEq( + rewardsCoordinatorImpl.MAX_REWARDS_DURATION(), Env.MAX_REWARDS_DURATION(), "MAX_REWARDS_DURATION mismatch" + ); + assertEq( + rewardsCoordinatorImpl.MAX_RETROACTIVE_LENGTH(), + Env.MAX_RETROACTIVE_LENGTH(), + "MAX_RETROACTIVE_LENGTH mismatch" + ); + assertEq( + rewardsCoordinatorImpl.MAX_FUTURE_LENGTH(), + 63_072_000, + "MAX_FUTURE_LENGTH should be 730 days (63072000 seconds)" + ); + assertEq( + rewardsCoordinatorImpl.GENESIS_REWARDS_TIMESTAMP(), + Env.GENESIS_REWARDS_TIMESTAMP(), + "GENESIS_REWARDS_TIMESTAMP mismatch" + ); + } + + /// @dev Validate that the new implementation cannot be initialized (should revert) + function _validateImplInitialized() internal { + bytes memory errInit = "Initializable: contract is already initialized"; + + RewardsCoordinator rewardsCoordinatorImpl = Env.impl.rewardsCoordinator(); + + vm.expectRevert(errInit); + rewardsCoordinatorImpl.initialize( + address(0), // initialOwner + 0, // initialPausedStatus + address(0), // rewardsUpdater + 0, // activationDelay + 0 // defaultSplitBips + ); + } + + /// @dev Validate the version is correctly set + function _validateVersion() internal view { + assertEq( + keccak256(bytes(Env.impl.rewardsCoordinator().version())), + keccak256(bytes(Env.deployVersion())), + "RewardsCoordinator version should match deploy version" + ); + } + + /// @dev Validate new Rewards v2.2 functionality + function _validateNewFunctionality() internal view { + RewardsCoordinator rewardsCoordinatorImpl = Env.impl.rewardsCoordinator(); + + // The new functions exist (this will fail to compile if they don't exist) + // Just checking that the contract has the expected interface + bytes4 createUniqueStakeSelector = rewardsCoordinatorImpl.createUniqueStakeRewardsSubmission.selector; + bytes4 createTotalStakeSelector = rewardsCoordinatorImpl.createTotalStakeRewardsSubmission.selector; + + // Verify the selectors are non-zero (functions exist) + assertTrue(createUniqueStakeSelector != bytes4(0), "createUniqueStakeRewardsSubmission function should exist"); + assertTrue(createTotalStakeSelector != bytes4(0), "createTotalStakeRewardsSubmission function should exist"); + + // Check new pause constants are defined + // These are internal constants, so we can't directly access them, but we can verify + // the contract compiles with them and that the pause functionality would work + } + + /// @dev Validate storage layout changes + function _validateStorageLayout() internal view { + // The storage gap was reduced from 35 to 33 slots to accommodate the new mappings: + // - isUniqueStakeRewardsSubmissionHash (1 slot) + // - isTotalStakeRewardsSubmissionHash (1 slot) + // This validation ensures the contract is compiled with the expected storage layout + + // We can't directly access the storage gap, but we can ensure the contract + // compiles and deploys successfully, which validates the storage layout is correct + RewardsCoordinator rewardsCoordinatorImpl = Env.impl.rewardsCoordinator(); + + // Verify we can access the existing public mappings + // This validates that storage layout hasn't been corrupted + + // Check that we can call view functions that access storage + address testAvs = address(0x1234); + bytes32 testHash = keccak256("test"); + + // These calls should not revert, validating storage is accessible + bool isRewardsSubmission = rewardsCoordinatorImpl.isAVSRewardsSubmissionHash(testAvs, testHash); + bool isOperatorDirected = rewardsCoordinatorImpl.isOperatorDirectedAVSRewardsSubmissionHash(testAvs, testHash); + bool isOperatorSet = + rewardsCoordinatorImpl.isOperatorDirectedOperatorSetRewardsSubmissionHash(testAvs, testHash); + bool isUniqueStake = rewardsCoordinatorImpl.isUniqueStakeRewardsSubmissionHash(testAvs, testHash); + bool isTotalStake = rewardsCoordinatorImpl.isTotalStakeRewardsSubmissionHash(testAvs, testHash); + + // All should be false for a random hash + assertFalse(isRewardsSubmission, "Random hash should not be a rewards submission"); + assertFalse(isOperatorDirected, "Random hash should not be operator directed"); + assertFalse(isOperatorSet, "Random hash should not be operator set"); + assertFalse(isUniqueStake, "Random hash should not be unique stake"); + assertFalse(isTotalStake, "Random hash should not be total stake"); + } +} diff --git a/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol new file mode 100644 index 0000000000..9861a4c44e --- /dev/null +++ b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import {DeployRewardsCoordinatorImpl} from "./1-deployRewardsCoordinatorImpl.s.sol"; +import "../Env.sol"; + +import {MultisigBuilder} from "zeus-templates/templates/MultisigBuilder.sol"; +import {MultisigCall, Encode} from "zeus-templates/utils/Encode.sol"; + +import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol"; + +/** + * @title QueueRewardsCoordinatorUpgrade + * @notice Queue the RewardsCoordinator upgrade transaction in the Timelock via the Operations Multisig. + * This queues the upgrade to add Rewards v2.2 support: + * - Unique stake rewards (linear to allocated unique stake) + * - Total stake rewards (linear to total stake) + * - Updated MAX_FUTURE_LENGTH to 730 days + */ +contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordinatorImpl { + using Env for *; + using Encode for *; + + function _runAsMultisig() internal virtual override prank(Env.opsMultisig()) { + if (!(Env.isSourceChain() && Env._strEq(Env.envVersion(), "1.9.0"))) { + return; + } + + bytes memory calldata_to_executor = _getCalldataToExecutor(); + + TimelockController timelock = Env.timelockController(); + timelock.schedule({ + target: Env.executorMultisig(), + value: 0, + data: calldata_to_executor, + predecessor: 0, + salt: 0, + delay: timelock.getMinDelay() + }); + } + + /// @dev Get the calldata to be sent from the timelock to the executor + function _getCalldataToExecutor() internal returns (bytes memory) { + /// forgefmt: disable-next-item + MultisigCall[] storage executorCalls = Encode.newMultisigCalls().append({ + to: Env.proxyAdmin(), + data: Encode.proxyAdmin.upgrade({ + proxy: address(Env.proxy.rewardsCoordinator()), + impl: address(Env.impl.rewardsCoordinator()) + }) + }); + + return Encode.gnosisSafe.execTransaction({ + from: address(Env.timelockController()), + to: Env.multiSendCallOnly(), + op: Encode.Operation.DelegateCall, + data: Encode.multiSend(executorCalls) + }); + } + + function testScript() public virtual override { + if (!(Env.isSourceChain() && Env._strEq(Env.envVersion(), "1.9.0"))) { + return; + } + + // 1 - Deploy. The new RewardsCoordinator implementation has been deployed + runAsEOA(); + + TimelockController timelock = Env.timelockController(); + bytes memory calldata_to_executor = _getCalldataToExecutor(); + bytes32 txHash = timelock.hashOperation({ + target: Env.executorMultisig(), + value: 0, + data: calldata_to_executor, + predecessor: 0, + salt: 0 + }); + + // Ensure transaction is not already queued + assertFalse(timelock.isOperationPending(txHash), "Transaction should not be queued yet"); + assertFalse(timelock.isOperationReady(txHash), "Transaction should not be ready"); + assertFalse(timelock.isOperationDone(txHash), "Transaction should not be complete"); + + // 2 - Queue the transaction + _runAsMultisig(); + _unsafeResetHasPranked(); // reset hasPranked so we can use it again + + // Verify transaction is queued + assertTrue(timelock.isOperationPending(txHash), "Transaction should be queued"); + assertFalse(timelock.isOperationReady(txHash), "Transaction should NOT be ready immediately"); + assertFalse(timelock.isOperationDone(txHash), "Transaction should NOT be complete"); + + // Validate that timelock delay is properly configured + uint256 minDelay = timelock.getMinDelay(); + assertTrue(minDelay > 0, "Timelock delay should be greater than 0"); + + // Validate proxy state before upgrade + _validatePreUpgradeState(); + } + + /// @dev Validate the state before the upgrade + function _validatePreUpgradeState() internal view { + RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); + + // Validate current implementation is different from new implementation + address currentImpl = Env._getProxyImpl(address(rewardsCoordinator)); + address newImpl = address(Env.impl.rewardsCoordinator()); + assertTrue(currentImpl != newImpl, "Current and new implementations should be different"); + + // Validate current MAX_FUTURE_LENGTH is different from new value + // Note: We access this through the proxy, which still points to the old implementation + uint32 currentMaxFutureLength = rewardsCoordinator.MAX_FUTURE_LENGTH(); + assertTrue(currentMaxFutureLength != 63_072_000, "Current MAX_FUTURE_LENGTH should not be 730 days yet"); + + // Note: Cannot check version() on old implementation as it may not have this function + // The upgrade is needed to add new functions and update MAX_FUTURE_LENGTH + + // Validate that we're upgrading from the correct version + // We can't directly call them since they don't exist, but we can verify the upgrade is needed + // by checking that we're indeed on the right version + assertEq(Env.envVersion(), "1.9.0", "Should be on version 1.9.0 before upgrade"); + } +} diff --git a/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol new file mode 100644 index 0000000000..1d38b2c446 --- /dev/null +++ b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import "../Env.sol"; +import {QueueRewardsCoordinatorUpgrade} from "./2-queueRewardsCoordinatorUpgrade.s.sol"; +import {Encode} from "zeus-templates/utils/Encode.sol"; + +/** + * @title ExecuteRewardsCoordinatorUpgrade + * @notice Execute the queued RewardsCoordinator upgrade after the timelock delay. + * This completes the upgrade to add Rewards v2.2 support: + * - Unique stake rewards (linear to allocated unique stake) + * - Total stake rewards (linear to total stake) + * - Updated MAX_FUTURE_LENGTH to 730 days (63072000 seconds) + */ +contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { + using Env for *; + using Encode for *; + + function _runAsMultisig() internal override prank(Env.protocolCouncilMultisig()) { + if (!(Env.isSourceChain() && Env._strEq(Env.envVersion(), "1.9.0"))) { + return; + } + + bytes memory calldata_to_executor = _getCalldataToExecutor(); + TimelockController timelock = Env.timelockController(); + + timelock.execute({ + target: Env.executorMultisig(), + value: 0, + payload: calldata_to_executor, + predecessor: 0, + salt: 0 + }); + } + + function testScript() public virtual override { + if (!(Env.isSourceChain() && Env._strEq(Env.envVersion(), "1.9.0"))) { + return; + } + + // 1 - Deploy. The new RewardsCoordinator implementation has been deployed + runAsEOA(); + + TimelockController timelock = Env.timelockController(); + bytes memory calldata_to_executor = _getCalldataToExecutor(); + bytes32 txHash = timelock.hashOperation({ + target: Env.executorMultisig(), + value: 0, + data: calldata_to_executor, + predecessor: 0, + salt: 0 + }); + + // 2 - Queue. Check that the operation IS ready + QueueRewardsCoordinatorUpgrade._runAsMultisig(); + _unsafeResetHasPranked(); // reset hasPranked so we can use it again + + assertTrue(timelock.isOperationPending(txHash), "Transaction should be queued"); + assertFalse(timelock.isOperationReady(txHash), "Transaction should NOT be ready immediately"); + assertFalse(timelock.isOperationDone(txHash), "Transaction should NOT be complete"); + + // 3 - Warp past the timelock delay + vm.warp(block.timestamp + timelock.getMinDelay()); + assertTrue(timelock.isOperationReady(txHash), "Transaction should be ready for execution"); + + // 4 - Execute the upgrade + execute(); + assertTrue(timelock.isOperationDone(txHash), "v1.10.0 RewardsCoordinator upgrade should be complete"); + + // 5 - Validate the upgrade was successful + _validateUpgradeComplete(); + _validateProxyAdmin(); + _validateProxyConstructor(); + _validateProxyInitialized(); + _validateNewFunctionalityThroughProxy(); + _validateStoragePreservation(); + } + + /// @dev Validate that the RewardsCoordinator proxy now points to the new implementation + function _validateUpgradeComplete() internal view { + address currentImpl = Env._getProxyImpl(address(Env.proxy.rewardsCoordinator())); + address expectedImpl = address(Env.impl.rewardsCoordinator()); + + assertTrue(currentImpl == expectedImpl, "RewardsCoordinator proxy should point to new implementation"); + } + + /// @dev Validate the proxy's constructor values through the proxy + function _validateProxyConstructor() internal view { + RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); + + // Validate version + assertEq( + keccak256(bytes(rewardsCoordinator.version())), + keccak256(bytes(Env.deployVersion())), + "RewardsCoordinator version mismatch" + ); + + // Validate core dependencies + assertTrue( + address(rewardsCoordinator.delegationManager()) == address(Env.proxy.delegationManager()), + "RewardsCoordinator delegationManager mismatch" + ); + assertTrue( + address(rewardsCoordinator.strategyManager()) == address(Env.proxy.strategyManager()), + "RewardsCoordinator strategyManager mismatch" + ); + assertTrue( + address(rewardsCoordinator.allocationManager()) == address(Env.proxy.allocationManager()), + "RewardsCoordinator allocationManager mismatch" + ); + + // Validate reward parameters + assertEq( + rewardsCoordinator.CALCULATION_INTERVAL_SECONDS(), + Env.CALCULATION_INTERVAL_SECONDS(), + "CALCULATION_INTERVAL_SECONDS mismatch" + ); + assertEq(rewardsCoordinator.MAX_REWARDS_DURATION(), Env.MAX_REWARDS_DURATION(), "MAX_REWARDS_DURATION mismatch"); + assertEq( + rewardsCoordinator.MAX_RETROACTIVE_LENGTH(), Env.MAX_RETROACTIVE_LENGTH(), "MAX_RETROACTIVE_LENGTH mismatch" + ); + + // Validate the updated MAX_FUTURE_LENGTH + assertEq( + rewardsCoordinator.MAX_FUTURE_LENGTH(), + 63_072_000, + "MAX_FUTURE_LENGTH should be 730 days (63072000 seconds)" + ); + + assertEq( + rewardsCoordinator.GENESIS_REWARDS_TIMESTAMP(), + Env.GENESIS_REWARDS_TIMESTAMP(), + "GENESIS_REWARDS_TIMESTAMP mismatch" + ); + } + + /// @dev Validate that the proxy is still initialized and cannot be re-initialized + function _validateProxyInitialized() internal { + RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); + + // Validate that key state variables are still set (proving initialization is preserved) + address owner = rewardsCoordinator.owner(); + assertTrue(owner != address(0), "Owner should still be set"); + + address rewardsUpdater = rewardsCoordinator.rewardsUpdater(); + assertTrue(rewardsUpdater != address(0), "RewardsUpdater should still be set"); + + // Attempt to re-initialize should fail + bytes memory errInit = "Initializable: contract is already initialized"; + vm.expectRevert(errInit); + rewardsCoordinator.initialize( + address(0x1234), // initialOwner + 0, // initialPausedStatus + address(0x9ABC), // rewardsUpdater + 0, // activationDelay + 0 // defaultSplitBips + ); + } + + /// @dev Validate new Rewards v2.2 functionality through the proxy + function _validateNewFunctionalityThroughProxy() internal view { + RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); + + // The new functions should be accessible through the proxy + bytes4 createUniqueStakeSelector = rewardsCoordinator.createUniqueStakeRewardsSubmission.selector; + bytes4 createTotalStakeSelector = rewardsCoordinator.createTotalStakeRewardsSubmission.selector; + + // Verify the selectors are non-zero (functions exist) + assertTrue( + createUniqueStakeSelector != bytes4(0), "createUniqueStakeRewardsSubmission function should exist on proxy" + ); + assertTrue( + createTotalStakeSelector != bytes4(0), "createTotalStakeRewardsSubmission function should exist on proxy" + ); + + // Test that we can access the new storage mappings + address testAvs = address(0xDEAD); + bytes32 testHash = keccak256("test_rewards_v2.2"); + + // These should all return false for test values, but accessing them validates the storage layout + bool isUniqueStake = rewardsCoordinator.isUniqueStakeRewardsSubmissionHash(testAvs, testHash); + bool isTotalStake = rewardsCoordinator.isTotalStakeRewardsSubmissionHash(testAvs, testHash); + + assertFalse(isUniqueStake, "Test hash should not be a unique stake submission"); + assertFalse(isTotalStake, "Test hash should not be a total stake submission"); + } + + /// @dev Validate that existing storage is preserved after upgrade + function _validateStoragePreservation() internal view { + RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); + + // Check that existing storage mappings are still accessible + address testAvs = address(0xBEEF); + bytes32 testHash = keccak256("existing_storage_test"); + + // These calls should not revert, validating that storage layout is preserved + bool isRewardsSubmission = rewardsCoordinator.isAVSRewardsSubmissionHash(testAvs, testHash); + bool isOperatorDirected = rewardsCoordinator.isOperatorDirectedAVSRewardsSubmissionHash(testAvs, testHash); + bool isOperatorSetRewards = + rewardsCoordinator.isOperatorDirectedOperatorSetRewardsSubmissionHash(testAvs, testHash); + + // All should be false for test values + assertFalse(isRewardsSubmission, "Test hash should not be a rewards submission"); + assertFalse(isOperatorDirected, "Test hash should not be operator directed"); + assertFalse(isOperatorSetRewards, "Test hash should not be operator set rewards"); + + // Check that core state variables are preserved + uint256 currRewardsCalculationEndTimestamp = rewardsCoordinator.currRewardsCalculationEndTimestamp(); + // Note: This may be 0 in test environments, which is acceptable + assertTrue(currRewardsCalculationEndTimestamp >= 0, "currRewardsCalculationEndTimestamp should be accessible"); + + // Check that submission nonce is accessible + uint256 nonce = rewardsCoordinator.submissionNonce(testAvs); + // Nonce should be 0 for a test address, but accessing it validates storage + assertEq(nonce, 0, "Nonce for test AVS should be 0"); + + // Validate distribution roots are still accessible + uint256 distributionRootCount = rewardsCoordinator.getDistributionRootsLength(); + // There should be some distribution roots if this is an existing deployment + // If it's 0, that's also fine for a test environment + assertTrue(distributionRootCount >= 0, "Distribution roots should be accessible"); + } +} diff --git a/script/releases/v1.10.0-rewards-v2.2/upgrade.json b/script/releases/v1.10.0-rewards-v2.2/upgrade.json new file mode 100644 index 0000000000..05d1f68665 --- /dev/null +++ b/script/releases/v1.10.0-rewards-v2.2/upgrade.json @@ -0,0 +1,19 @@ +{ + "name": "rewards-v2.2-v1.10.0", + "from": "1.9.0", + "to": "1.10.0", + "phases": [ + { + "type": "eoa", + "filename": "1-deployRewardsCoordinatorImpl.s.sol" + }, + { + "type": "multisig", + "filename": "2-queueRewardsCoordinatorUpgrade.s.sol" + }, + { + "type": "multisig", + "filename": "3-executeRewardsCoordinatorUpgrade.s.sol" + } + ] +} \ No newline at end of file From dcd304ddbb4467a5d1469323e71dec4720a3cdc7 Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Fri, 21 Nov 2025 17:31:25 -0500 Subject: [PATCH 2/6] fix: rebase --- .../1-deployRewardsCoordinatorImpl.s.sol | 25 +++++-------------- .../2-queueRewardsCoordinatorUpgrade.s.sol | 4 ++- .../3-executeRewardsCoordinatorUpgrade.s.sol | 11 +++----- 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol b/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol index b2bbccf79d..2fbb282648 100644 --- a/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.12; import {EOADeployer} from "zeus-templates/templates/EOADeployer.sol"; import "../Env.sol"; +import "../TestUtils.sol"; /** * @title DeployRewardsCoordinatorImpl @@ -13,6 +14,7 @@ import "../Env.sol"; */ contract DeployRewardsCoordinatorImpl is EOADeployer { using Env for *; + using TestUtils for *; /// forgefmt: disable-next-item function _runAsEOA() internal override { @@ -38,8 +40,7 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { MAX_REWARDS_DURATION: Env.MAX_REWARDS_DURATION(), MAX_RETROACTIVE_LENGTH: Env.MAX_RETROACTIVE_LENGTH(), MAX_FUTURE_LENGTH: 63072000, // 730 days (2 years) - GENESIS_REWARDS_TIMESTAMP: Env.GENESIS_REWARDS_TIMESTAMP(), - version: Env.deployVersion() + GENESIS_REWARDS_TIMESTAMP: Env.GENESIS_REWARDS_TIMESTAMP() }) ) ) @@ -63,14 +64,13 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { _validateProxyAdmin(); _validateImplConstructor(); _validateImplInitialized(); - _validateVersion(); _validateNewFunctionality(); _validateStorageLayout(); } /// @dev Validate that the new RewardsCoordinator impl address is distinct from the current one function _validateNewImplAddress() internal view { - address currentImpl = Env._getProxyImpl(address(Env.proxy.rewardsCoordinator())); + address currentImpl = TestUtils._getProxyImpl(address(Env.proxy.rewardsCoordinator())); address newImpl = address(Env.impl.rewardsCoordinator()); assertFalse(currentImpl == newImpl, "RewardsCoordinator impl should be different from current implementation"); @@ -81,7 +81,7 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { address pa = Env.proxyAdmin(); assertTrue( - Env._getProxyAdmin(address(Env.proxy.rewardsCoordinator())) == pa, "RewardsCoordinator proxyAdmin incorrect" + TestUtils._getProxyAdmin(address(Env.proxy.rewardsCoordinator())) == pa, "RewardsCoordinator proxyAdmin incorrect" ); } @@ -89,12 +89,7 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { function _validateImplConstructor() internal view { RewardsCoordinator rewardsCoordinatorImpl = Env.impl.rewardsCoordinator(); - // Validate version - assertEq( - keccak256(bytes(rewardsCoordinatorImpl.version())), - keccak256(bytes(Env.deployVersion())), - "RewardsCoordinator impl version mismatch" - ); + // Note: version() function has been removed in this upgrade // Validate core dependencies assertTrue( @@ -152,14 +147,6 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { ); } - /// @dev Validate the version is correctly set - function _validateVersion() internal view { - assertEq( - keccak256(bytes(Env.impl.rewardsCoordinator().version())), - keccak256(bytes(Env.deployVersion())), - "RewardsCoordinator version should match deploy version" - ); - } /// @dev Validate new Rewards v2.2 functionality function _validateNewFunctionality() internal view { diff --git a/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol index 9861a4c44e..53822aeff8 100644 --- a/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.12; import {DeployRewardsCoordinatorImpl} from "./1-deployRewardsCoordinatorImpl.s.sol"; import "../Env.sol"; +import "../TestUtils.sol"; import {MultisigBuilder} from "zeus-templates/templates/MultisigBuilder.sol"; import {MultisigCall, Encode} from "zeus-templates/utils/Encode.sol"; @@ -20,6 +21,7 @@ import {TimelockController} from "@openzeppelin/contracts/governance/TimelockCon contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordinatorImpl { using Env for *; using Encode for *; + using TestUtils for *; function _runAsMultisig() internal virtual override prank(Env.opsMultisig()) { if (!(Env.isSourceChain() && Env._strEq(Env.envVersion(), "1.9.0"))) { @@ -103,7 +105,7 @@ contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordin RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); // Validate current implementation is different from new implementation - address currentImpl = Env._getProxyImpl(address(rewardsCoordinator)); + address currentImpl = TestUtils._getProxyImpl(address(rewardsCoordinator)); address newImpl = address(Env.impl.rewardsCoordinator()); assertTrue(currentImpl != newImpl, "Current and new implementations should be different"); diff --git a/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol index 1d38b2c446..c907b2a70b 100644 --- a/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.12; import "../Env.sol"; +import "../TestUtils.sol"; import {QueueRewardsCoordinatorUpgrade} from "./2-queueRewardsCoordinatorUpgrade.s.sol"; import {Encode} from "zeus-templates/utils/Encode.sol"; @@ -16,6 +17,7 @@ import {Encode} from "zeus-templates/utils/Encode.sol"; contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { using Env for *; using Encode for *; + using TestUtils for *; function _runAsMultisig() internal override prank(Env.protocolCouncilMultisig()) { if (!(Env.isSourceChain() && Env._strEq(Env.envVersion(), "1.9.0"))) { @@ -79,7 +81,7 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { /// @dev Validate that the RewardsCoordinator proxy now points to the new implementation function _validateUpgradeComplete() internal view { - address currentImpl = Env._getProxyImpl(address(Env.proxy.rewardsCoordinator())); + address currentImpl = TestUtils._getProxyImpl(address(Env.proxy.rewardsCoordinator())); address expectedImpl = address(Env.impl.rewardsCoordinator()); assertTrue(currentImpl == expectedImpl, "RewardsCoordinator proxy should point to new implementation"); @@ -89,12 +91,7 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { function _validateProxyConstructor() internal view { RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); - // Validate version - assertEq( - keccak256(bytes(rewardsCoordinator.version())), - keccak256(bytes(Env.deployVersion())), - "RewardsCoordinator version mismatch" - ); + // Note: version() function has been removed in this upgrade // Validate core dependencies assertTrue( From 65f546048773a99170070425e7f1fe07b0a235ab Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Fri, 21 Nov 2025 18:14:19 -0500 Subject: [PATCH 3/6] fix: cleanup --- .../1-deployRewardsCoordinatorImpl.s.sol | 61 ++++++++++++------ .../2-queueRewardsCoordinatorUpgrade.s.sol | 5 +- .../3-executeRewardsCoordinatorUpgrade.s.sol | 64 ++++++------------- 3 files changed, 63 insertions(+), 67 deletions(-) diff --git a/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol b/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol index 2fbb282648..09ea38ce99 100644 --- a/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol @@ -11,6 +11,7 @@ import "../TestUtils.sol"; * This adds support for: * - Unique stake rewards submissions (rewards linear to allocated unique stake) * - Total stake rewards submissions (rewards linear to total stake) + * - Updated MAX_FUTURE_LENGTH to 730 days (63072000 seconds) */ contract DeployRewardsCoordinatorImpl is EOADeployer { using Env for *; @@ -25,6 +26,10 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { vm.startBroadcast(); + // Update the MAX_FUTURE_LENGTH environment variable before deployment + // 63072000s = 730 days = 2 years + zUpdateUint32("REWARDS_COORDINATOR_MAX_FUTURE_LENGTH", 63072000); + // Deploy RewardsCoordinator implementation with the new MAX_FUTURE_LENGTH deployImpl({ name: type(RewardsCoordinator).name, @@ -39,16 +44,13 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { CALCULATION_INTERVAL_SECONDS: Env.CALCULATION_INTERVAL_SECONDS(), MAX_REWARDS_DURATION: Env.MAX_REWARDS_DURATION(), MAX_RETROACTIVE_LENGTH: Env.MAX_RETROACTIVE_LENGTH(), - MAX_FUTURE_LENGTH: 63072000, // 730 days (2 years) + MAX_FUTURE_LENGTH: Env.MAX_FUTURE_LENGTH(), // Using updated env value GENESIS_REWARDS_TIMESTAMP: Env.GENESIS_REWARDS_TIMESTAMP() }) ) ) }); - // Update the MAX_FUTURE_LENGTH environment variable - zUpdateUint32("REWARDS_COORDINATOR_MAX_FUTURE_LENGTH", 63072000); - vm.stopBroadcast(); } @@ -63,6 +65,7 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { _validateNewImplAddress(); _validateProxyAdmin(); _validateImplConstructor(); + _validateZeusEnvUpdated(); _validateImplInitialized(); _validateNewFunctionality(); _validateStorageLayout(); @@ -81,7 +84,8 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { address pa = Env.proxyAdmin(); assertTrue( - TestUtils._getProxyAdmin(address(Env.proxy.rewardsCoordinator())) == pa, "RewardsCoordinator proxyAdmin incorrect" + TestUtils._getProxyAdmin(address(Env.proxy.rewardsCoordinator())) == pa, + "RewardsCoordinator proxyAdmin incorrect" ); } @@ -89,8 +93,6 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { function _validateImplConstructor() internal view { RewardsCoordinator rewardsCoordinatorImpl = Env.impl.rewardsCoordinator(); - // Note: version() function has been removed in this upgrade - // Validate core dependencies assertTrue( address(rewardsCoordinatorImpl.delegationManager()) == address(Env.proxy.delegationManager()), @@ -104,6 +106,14 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { address(rewardsCoordinatorImpl.allocationManager()) == address(Env.proxy.allocationManager()), "RewardsCoordinator allocationManager mismatch" ); + assertTrue( + address(rewardsCoordinatorImpl.pauserRegistry()) == address(Env.impl.pauserRegistry()), + "RewardsCoordinator pauserRegistry mismatch" + ); + assertTrue( + address(rewardsCoordinatorImpl.permissionController()) == address(Env.proxy.permissionController()), + "RewardsCoordinator permissionController mismatch" + ); // Validate reward parameters assertEq( @@ -131,6 +141,25 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { ); } + /// @dev Validate that the zeus environment variable has been updated correctly + function _validateZeusEnvUpdated() internal view { + RewardsCoordinator rewardsCoordinatorImpl = Env.impl.rewardsCoordinator(); + + // Validate that the zeus env MAX_FUTURE_LENGTH matches what was deployed + assertEq( + rewardsCoordinatorImpl.MAX_FUTURE_LENGTH(), + Env.MAX_FUTURE_LENGTH(), + "Deployed MAX_FUTURE_LENGTH should match zeus env value" + ); + + // Also validate it equals the expected value + assertEq( + Env.MAX_FUTURE_LENGTH(), + 63_072_000, + "Zeus env MAX_FUTURE_LENGTH should be updated to 730 days (63072000 seconds)" + ); + } + /// @dev Validate that the new implementation cannot be initialized (should revert) function _validateImplInitialized() internal { bytes memory errInit = "Initializable: contract is already initialized"; @@ -147,7 +176,6 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { ); } - /// @dev Validate new Rewards v2.2 functionality function _validateNewFunctionality() internal view { RewardsCoordinator rewardsCoordinatorImpl = Env.impl.rewardsCoordinator(); @@ -160,10 +188,6 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { // Verify the selectors are non-zero (functions exist) assertTrue(createUniqueStakeSelector != bytes4(0), "createUniqueStakeRewardsSubmission function should exist"); assertTrue(createTotalStakeSelector != bytes4(0), "createTotalStakeRewardsSubmission function should exist"); - - // Check new pause constants are defined - // These are internal constants, so we can't directly access them, but we can verify - // the contract compiles with them and that the pause functionality would work } /// @dev Validate storage layout changes @@ -185,17 +209,18 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { bytes32 testHash = keccak256("test"); // These calls should not revert, validating storage is accessible - bool isRewardsSubmission = rewardsCoordinatorImpl.isAVSRewardsSubmissionHash(testAvs, testHash); - bool isOperatorDirected = rewardsCoordinatorImpl.isOperatorDirectedAVSRewardsSubmissionHash(testAvs, testHash); - bool isOperatorSet = + bool isAVS = rewardsCoordinatorImpl.isAVSRewardsSubmissionHash(testAvs, testHash); + bool isOperatorDirectedAVS = + rewardsCoordinatorImpl.isOperatorDirectedAVSRewardsSubmissionHash(testAvs, testHash); + bool isOperatorDirectedOperatorSet = rewardsCoordinatorImpl.isOperatorDirectedOperatorSetRewardsSubmissionHash(testAvs, testHash); bool isUniqueStake = rewardsCoordinatorImpl.isUniqueStakeRewardsSubmissionHash(testAvs, testHash); bool isTotalStake = rewardsCoordinatorImpl.isTotalStakeRewardsSubmissionHash(testAvs, testHash); // All should be false for a random hash - assertFalse(isRewardsSubmission, "Random hash should not be a rewards submission"); - assertFalse(isOperatorDirected, "Random hash should not be operator directed"); - assertFalse(isOperatorSet, "Random hash should not be operator set"); + assertFalse(isAVS, "Random hash should not be a rewards submission"); + assertFalse(isOperatorDirectedAVS, "Random hash should not be operator directed"); + assertFalse(isOperatorDirectedOperatorSet, "Random hash should not be operator set"); assertFalse(isUniqueStake, "Random hash should not be unique stake"); assertFalse(isTotalStake, "Random hash should not be total stake"); } diff --git a/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol index 53822aeff8..830845bcc1 100644 --- a/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol @@ -16,7 +16,7 @@ import {TimelockController} from "@openzeppelin/contracts/governance/TimelockCon * This queues the upgrade to add Rewards v2.2 support: * - Unique stake rewards (linear to allocated unique stake) * - Total stake rewards (linear to total stake) - * - Updated MAX_FUTURE_LENGTH to 730 days + * - Updated MAX_FUTURE_LENGTH to 730 days (63072000 seconds) */ contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordinatorImpl { using Env for *; @@ -114,9 +114,6 @@ contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordin uint32 currentMaxFutureLength = rewardsCoordinator.MAX_FUTURE_LENGTH(); assertTrue(currentMaxFutureLength != 63_072_000, "Current MAX_FUTURE_LENGTH should not be 730 days yet"); - // Note: Cannot check version() on old implementation as it may not have this function - // The upgrade is needed to add new functions and update MAX_FUTURE_LENGTH - // Validate that we're upgrading from the correct version // We can't directly call them since they don't exist, but we can verify the upgrade is needed // by checking that we're indeed on the right version diff --git a/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol index c907b2a70b..9dde9d8ad3 100644 --- a/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol @@ -76,7 +76,6 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { _validateProxyConstructor(); _validateProxyInitialized(); _validateNewFunctionalityThroughProxy(); - _validateStoragePreservation(); } /// @dev Validate that the RewardsCoordinator proxy now points to the new implementation @@ -91,8 +90,6 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { function _validateProxyConstructor() internal view { RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); - // Note: version() function has been removed in this upgrade - // Validate core dependencies assertTrue( address(rewardsCoordinator.delegationManager()) == address(Env.proxy.delegationManager()), @@ -106,6 +103,14 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { address(rewardsCoordinator.allocationManager()) == address(Env.proxy.allocationManager()), "RewardsCoordinator allocationManager mismatch" ); + assertTrue( + address(rewardsCoordinator.pauserRegistry()) == address(Env.impl.pauserRegistry()), + "RewardsCoordinator pauserRegistry mismatch" + ); + assertTrue( + address(rewardsCoordinator.permissionController()) == address(Env.proxy.permissionController()), + "RewardsCoordinator permissionController mismatch" + ); // Validate reward parameters assertEq( @@ -136,12 +141,17 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { function _validateProxyInitialized() internal { RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); - // Validate that key state variables are still set (proving initialization is preserved) - address owner = rewardsCoordinator.owner(); - assertTrue(owner != address(0), "Owner should still be set"); - - address rewardsUpdater = rewardsCoordinator.rewardsUpdater(); - assertTrue(rewardsUpdater != address(0), "RewardsUpdater should still be set"); + // Validate the existing initializable state variables are still set + assertTrue(rewardsCoordinator.paused() == Env.REWARDS_PAUSE_STATUS(), "Paused status should still be set"); + assertTrue(rewardsCoordinator.owner() == Env.opsMultisig(), "Owner should still be set"); + assertTrue(rewardsCoordinator.rewardsUpdater() == Env.REWARDS_UPDATER(), "RewardsUpdater should still be set"); + assertTrue( + rewardsCoordinator.activationDelay() == Env.ACTIVATION_DELAY(), "Activation delay should still be set" + ); + assertTrue( + rewardsCoordinator.defaultOperatorSplitBips() == Env.DEFAULT_SPLIT_BIPS(), + "Default split bips should still be set" + ); // Attempt to re-initialize should fail bytes memory errInit = "Initializable: contract is already initialized"; @@ -182,40 +192,4 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { assertFalse(isUniqueStake, "Test hash should not be a unique stake submission"); assertFalse(isTotalStake, "Test hash should not be a total stake submission"); } - - /// @dev Validate that existing storage is preserved after upgrade - function _validateStoragePreservation() internal view { - RewardsCoordinator rewardsCoordinator = Env.proxy.rewardsCoordinator(); - - // Check that existing storage mappings are still accessible - address testAvs = address(0xBEEF); - bytes32 testHash = keccak256("existing_storage_test"); - - // These calls should not revert, validating that storage layout is preserved - bool isRewardsSubmission = rewardsCoordinator.isAVSRewardsSubmissionHash(testAvs, testHash); - bool isOperatorDirected = rewardsCoordinator.isOperatorDirectedAVSRewardsSubmissionHash(testAvs, testHash); - bool isOperatorSetRewards = - rewardsCoordinator.isOperatorDirectedOperatorSetRewardsSubmissionHash(testAvs, testHash); - - // All should be false for test values - assertFalse(isRewardsSubmission, "Test hash should not be a rewards submission"); - assertFalse(isOperatorDirected, "Test hash should not be operator directed"); - assertFalse(isOperatorSetRewards, "Test hash should not be operator set rewards"); - - // Check that core state variables are preserved - uint256 currRewardsCalculationEndTimestamp = rewardsCoordinator.currRewardsCalculationEndTimestamp(); - // Note: This may be 0 in test environments, which is acceptable - assertTrue(currRewardsCalculationEndTimestamp >= 0, "currRewardsCalculationEndTimestamp should be accessible"); - - // Check that submission nonce is accessible - uint256 nonce = rewardsCoordinator.submissionNonce(testAvs); - // Nonce should be 0 for a test address, but accessing it validates storage - assertEq(nonce, 0, "Nonce for test AVS should be 0"); - - // Validate distribution roots are still accessible - uint256 distributionRootCount = rewardsCoordinator.getDistributionRootsLength(); - // There should be some distribution roots if this is an existing deployment - // If it's 0, that's also fine for a test environment - assertTrue(distributionRootCount >= 0, "Distribution roots should be accessible"); - } } From 6d210565370ffef835154adc54a7eb29963c7e8f Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Fri, 21 Nov 2025 18:37:03 -0500 Subject: [PATCH 4/6] fix: slashing ux release version check --- .../1-deployProtocolRegistryProxy.s.sol | 7 ++++++- .../2-deployProtocolRegistryImpl.s.sol | 7 ++++++- .../3-upgradeProtocolRegistry.s.sol | 7 ++++++- .../4-deployCoreContracts.s.sol | 7 ++++++- .../v1.9.0-slashing-ux-destination/5-queueUpgrade.s.sol | 7 ++++++- .../v1.9.0-slashing-ux-destination/6-completeUpgrade.s.sol | 7 ++++++- .../v1.9.0-slashing-ux/1-deployProtocolRegistryProxy.s.sol | 7 ++++++- .../v1.9.0-slashing-ux/2-deployProtocolRegistryImpl.s.sol | 7 ++++++- .../v1.9.0-slashing-ux/3-upgradeProtocolRegistry.s.sol | 7 ++++++- .../v1.9.0-slashing-ux/4-deployCoreContracts.s.sol | 7 ++++++- script/releases/v1.9.0-slashing-ux/5-queueUpgrade.s.sol | 7 ++++++- script/releases/v1.9.0-slashing-ux/6-completeUpgrade.s.sol | 7 ++++++- 12 files changed, 72 insertions(+), 12 deletions(-) diff --git a/script/releases/v1.9.0-slashing-ux-destination/1-deployProtocolRegistryProxy.s.sol b/script/releases/v1.9.0-slashing-ux-destination/1-deployProtocolRegistryProxy.s.sol index 4fb0ffb6e8..4fa9743fb7 100644 --- a/script/releases/v1.9.0-slashing-ux-destination/1-deployProtocolRegistryProxy.s.sol +++ b/script/releases/v1.9.0-slashing-ux-destination/1-deployProtocolRegistryProxy.s.sol @@ -15,6 +15,11 @@ contract DeployProtocolRegistryProxy is MultisigBuilder { /// forgefmt: disable-next-item function _runAsMultisig() internal virtual override { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + // We don't use the prank modifier here, since we have to write to the env _startPrank(Env.multichainDeployerMultisig()); @@ -33,7 +38,7 @@ contract DeployProtocolRegistryProxy is MultisigBuilder { } function testScript() public virtual { - if (Env.isCoreProtocolDeployed()) { + if (Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } diff --git a/script/releases/v1.9.0-slashing-ux-destination/2-deployProtocolRegistryImpl.s.sol b/script/releases/v1.9.0-slashing-ux-destination/2-deployProtocolRegistryImpl.s.sol index 1aa43c1d54..e41221c3b3 100644 --- a/script/releases/v1.9.0-slashing-ux-destination/2-deployProtocolRegistryImpl.s.sol +++ b/script/releases/v1.9.0-slashing-ux-destination/2-deployProtocolRegistryImpl.s.sol @@ -14,6 +14,11 @@ contract DeployProtocolRegistryImpl is DeployProtocolRegistryProxy, CoreContract using Env for *; function _runAsEOA() internal virtual override { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + vm.startBroadcast(); // Deploy Protocol Registry implementation @@ -23,7 +28,7 @@ contract DeployProtocolRegistryImpl is DeployProtocolRegistryProxy, CoreContract } function testScript() public virtual override { - if (Env.isCoreProtocolDeployed()) { + if (Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } diff --git a/script/releases/v1.9.0-slashing-ux-destination/3-upgradeProtocolRegistry.s.sol b/script/releases/v1.9.0-slashing-ux-destination/3-upgradeProtocolRegistry.s.sol index fe82c3ddab..c88bb6eed6 100644 --- a/script/releases/v1.9.0-slashing-ux-destination/3-upgradeProtocolRegistry.s.sol +++ b/script/releases/v1.9.0-slashing-ux-destination/3-upgradeProtocolRegistry.s.sol @@ -17,6 +17,11 @@ contract UpgradeProtocolRegistry is DeployProtocolRegistryImpl { /// forgefmt: disable-next-item function _runAsMultisig() internal virtual override prank(Env.multichainDeployerMultisig()) { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + // Upgrade the proxies to point to the actual implementations ITransparentUpgradeableProxy protocolRegistryProxy = ITransparentUpgradeableProxy(payable(address(Env.proxy.protocolRegistry()))); @@ -27,7 +32,7 @@ contract UpgradeProtocolRegistry is DeployProtocolRegistryImpl { } function testScript() public virtual override { - if (Env.isCoreProtocolDeployed()) { + if (Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } // 1. Deploy the Protocol Registry Proxy diff --git a/script/releases/v1.9.0-slashing-ux-destination/4-deployCoreContracts.s.sol b/script/releases/v1.9.0-slashing-ux-destination/4-deployCoreContracts.s.sol index ee280251f7..e5389e7687 100644 --- a/script/releases/v1.9.0-slashing-ux-destination/4-deployCoreContracts.s.sol +++ b/script/releases/v1.9.0-slashing-ux-destination/4-deployCoreContracts.s.sol @@ -28,6 +28,11 @@ contract DeployCoreContracts is UpgradeProtocolRegistry { using Env for *; function _runAsEOA() internal override { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + vm.startBroadcast(); /** @@ -47,7 +52,7 @@ contract DeployCoreContracts is UpgradeProtocolRegistry { } function testScript() public virtual override { - if (Env.isCoreProtocolDeployed()) { + if (Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } diff --git a/script/releases/v1.9.0-slashing-ux-destination/5-queueUpgrade.s.sol b/script/releases/v1.9.0-slashing-ux-destination/5-queueUpgrade.s.sol index 5ec1831200..2ced60438c 100644 --- a/script/releases/v1.9.0-slashing-ux-destination/5-queueUpgrade.s.sol +++ b/script/releases/v1.9.0-slashing-ux-destination/5-queueUpgrade.s.sol @@ -18,6 +18,11 @@ contract QueueUpgrade is DeployCoreContracts { using CoreUpgradeQueueBuilder for MultisigCall[]; function _runAsMultisig() internal virtual override prank(Env.opsMultisig()) { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + bytes memory calldata_to_executor = _getCalldataToExecutor(); TimelockController timelock = Env.timelockController(); @@ -113,7 +118,7 @@ contract QueueUpgrade is DeployCoreContracts { } function testScript() public virtual override { - if (Env.isCoreProtocolDeployed()) { + if (Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } diff --git a/script/releases/v1.9.0-slashing-ux-destination/6-completeUpgrade.s.sol b/script/releases/v1.9.0-slashing-ux-destination/6-completeUpgrade.s.sol index af04bda987..d198e4818d 100644 --- a/script/releases/v1.9.0-slashing-ux-destination/6-completeUpgrade.s.sol +++ b/script/releases/v1.9.0-slashing-ux-destination/6-completeUpgrade.s.sol @@ -12,6 +12,11 @@ contract ExecuteUpgrade is QueueUpgrade { using Env for *; function _runAsMultisig() internal virtual override prank(Env.protocolCouncilMultisig()) { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + bytes memory calldata_to_executor = _getCalldataToExecutor(); TimelockController timelock = Env.timelockController(); @@ -25,7 +30,7 @@ contract ExecuteUpgrade is QueueUpgrade { } function testScript() public virtual override { - if (Env.isCoreProtocolDeployed()) { + if (Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } diff --git a/script/releases/v1.9.0-slashing-ux/1-deployProtocolRegistryProxy.s.sol b/script/releases/v1.9.0-slashing-ux/1-deployProtocolRegistryProxy.s.sol index 5a671f3542..68088534d9 100644 --- a/script/releases/v1.9.0-slashing-ux/1-deployProtocolRegistryProxy.s.sol +++ b/script/releases/v1.9.0-slashing-ux/1-deployProtocolRegistryProxy.s.sol @@ -15,6 +15,11 @@ contract DeployProtocolRegistryProxy is MultisigBuilder { /// forgefmt: disable-next-item function _runAsMultisig() internal virtual override { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + // We don't use the prank modifier here, since we have to write to the env _startPrank(Env.multichainDeployerMultisig()); @@ -33,7 +38,7 @@ contract DeployProtocolRegistryProxy is MultisigBuilder { } function testScript() public virtual { - if (!Env.isCoreProtocolDeployed()) { + if (!Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } execute(); diff --git a/script/releases/v1.9.0-slashing-ux/2-deployProtocolRegistryImpl.s.sol b/script/releases/v1.9.0-slashing-ux/2-deployProtocolRegistryImpl.s.sol index 2c0480ade6..f9ef003402 100644 --- a/script/releases/v1.9.0-slashing-ux/2-deployProtocolRegistryImpl.s.sol +++ b/script/releases/v1.9.0-slashing-ux/2-deployProtocolRegistryImpl.s.sol @@ -14,6 +14,11 @@ contract DeployProtocolRegistryImpl is DeployProtocolRegistryProxy, CoreContract using Env for *; function _runAsEOA() internal virtual override { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + vm.startBroadcast(); // Deploy Protocol Registry implementation @@ -23,7 +28,7 @@ contract DeployProtocolRegistryImpl is DeployProtocolRegistryProxy, CoreContract } function testScript() public virtual override { - if (!Env.isCoreProtocolDeployed()) { + if (!Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } // 1. Deploy Protocol Registry Proxy diff --git a/script/releases/v1.9.0-slashing-ux/3-upgradeProtocolRegistry.s.sol b/script/releases/v1.9.0-slashing-ux/3-upgradeProtocolRegistry.s.sol index 06fa8aa8de..343ac75c2c 100644 --- a/script/releases/v1.9.0-slashing-ux/3-upgradeProtocolRegistry.s.sol +++ b/script/releases/v1.9.0-slashing-ux/3-upgradeProtocolRegistry.s.sol @@ -17,6 +17,11 @@ contract UpgradeProtocolRegistry is DeployProtocolRegistryImpl { /// forgefmt: disable-next-item function _runAsMultisig() internal virtual override prank(Env.multichainDeployerMultisig()) { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + // Upgrade the proxies to point to the actual implementations ITransparentUpgradeableProxy protocolRegistryProxy = ITransparentUpgradeableProxy(payable(address(Env.proxy.protocolRegistry()))); @@ -27,7 +32,7 @@ contract UpgradeProtocolRegistry is DeployProtocolRegistryImpl { } function testScript() public virtual override { - if (!Env.isCoreProtocolDeployed()) { + if (!Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } // 1. Deploy the Protocol Registry Proxy diff --git a/script/releases/v1.9.0-slashing-ux/4-deployCoreContracts.s.sol b/script/releases/v1.9.0-slashing-ux/4-deployCoreContracts.s.sol index 853e7f9d1a..2e8191dc35 100644 --- a/script/releases/v1.9.0-slashing-ux/4-deployCoreContracts.s.sol +++ b/script/releases/v1.9.0-slashing-ux/4-deployCoreContracts.s.sol @@ -46,6 +46,11 @@ contract DeployCoreContracts is UpgradeProtocolRegistry { using Env for *; function _runAsEOA() internal override { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + vm.startBroadcast(); /** @@ -97,7 +102,7 @@ contract DeployCoreContracts is UpgradeProtocolRegistry { } function testScript() public virtual override { - if (!Env.isCoreProtocolDeployed()) { + if (!Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } // Deploy protocol registry and initialize it diff --git a/script/releases/v1.9.0-slashing-ux/5-queueUpgrade.s.sol b/script/releases/v1.9.0-slashing-ux/5-queueUpgrade.s.sol index 9b105db45f..278b49441e 100644 --- a/script/releases/v1.9.0-slashing-ux/5-queueUpgrade.s.sol +++ b/script/releases/v1.9.0-slashing-ux/5-queueUpgrade.s.sol @@ -18,6 +18,11 @@ contract QueueUpgrade is DeployCoreContracts { using CoreUpgradeQueueBuilder for MultisigCall[]; function _runAsMultisig() internal virtual override prank(Env.opsMultisig()) { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + bytes memory calldata_to_executor = _getCalldataToExecutor(); TimelockController timelock = Env.timelockController(); @@ -234,7 +239,7 @@ contract QueueUpgrade is DeployCoreContracts { } function testScript() public virtual override { - if (!Env.isCoreProtocolDeployed()) { + if (!Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } // Complete previous steps diff --git a/script/releases/v1.9.0-slashing-ux/6-completeUpgrade.s.sol b/script/releases/v1.9.0-slashing-ux/6-completeUpgrade.s.sol index 1cd3d9abde..9304d30ade 100644 --- a/script/releases/v1.9.0-slashing-ux/6-completeUpgrade.s.sol +++ b/script/releases/v1.9.0-slashing-ux/6-completeUpgrade.s.sol @@ -12,6 +12,11 @@ contract ExecuteUpgrade is QueueUpgrade { using Env for *; function _runAsMultisig() internal virtual override prank(Env.protocolCouncilMultisig()) { + // Only execute on version 1.8.1 + if (!Env._strEq(Env.envVersion(), "1.8.1")) { + return; + } + bytes memory calldata_to_executor = _getCalldataToExecutor(); TimelockController timelock = Env.timelockController(); @@ -25,7 +30,7 @@ contract ExecuteUpgrade is QueueUpgrade { } function testScript() public virtual override { - if (!Env.isCoreProtocolDeployed()) { + if (!Env.isCoreProtocolDeployed() || !Env._strEq(Env.envVersion(), "1.8.1")) { return; } // Complete previous steps From 174ced248ac8ee4a211a4345a2e78d329e200c3e Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Fri, 21 Nov 2025 20:15:35 -0500 Subject: [PATCH 5/6] fix: use MAX_REWARDS_DURATION --- .../1-deployRewardsCoordinatorImpl.s.sol | 34 +++++++++---------- .../2-queueRewardsCoordinatorUpgrade.s.sol | 27 +++++++-------- .../3-executeRewardsCoordinatorUpgrade.s.sol | 27 ++++++--------- 3 files changed, 38 insertions(+), 50 deletions(-) diff --git a/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol b/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol index 09ea38ce99..92172cd1f2 100644 --- a/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/1-deployRewardsCoordinatorImpl.s.sol @@ -11,7 +11,7 @@ import "../TestUtils.sol"; * This adds support for: * - Unique stake rewards submissions (rewards linear to allocated unique stake) * - Total stake rewards submissions (rewards linear to total stake) - * - Updated MAX_FUTURE_LENGTH to 730 days (63072000 seconds) + * - Updated MAX_REWARDS_DURATION to 730 days (63072000 seconds) */ contract DeployRewardsCoordinatorImpl is EOADeployer { using Env for *; @@ -26,11 +26,11 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { vm.startBroadcast(); - // Update the MAX_FUTURE_LENGTH environment variable before deployment + // Update the MAX_REWARDS_DURATION environment variable before deployment // 63072000s = 730 days = 2 years - zUpdateUint32("REWARDS_COORDINATOR_MAX_FUTURE_LENGTH", 63072000); + zUpdateUint32("REWARDS_COORDINATOR_MAX_REWARDS_DURATION", 63072000); - // Deploy RewardsCoordinator implementation with the new MAX_FUTURE_LENGTH + // Deploy RewardsCoordinator implementation with the updated MAX_REWARDS_DURATION deployImpl({ name: type(RewardsCoordinator).name, deployedTo: address( @@ -42,9 +42,9 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { pauserRegistry: Env.impl.pauserRegistry(), permissionController: Env.proxy.permissionController(), CALCULATION_INTERVAL_SECONDS: Env.CALCULATION_INTERVAL_SECONDS(), - MAX_REWARDS_DURATION: Env.MAX_REWARDS_DURATION(), + MAX_REWARDS_DURATION: Env.MAX_REWARDS_DURATION(), // Using updated env value MAX_RETROACTIVE_LENGTH: Env.MAX_RETROACTIVE_LENGTH(), - MAX_FUTURE_LENGTH: Env.MAX_FUTURE_LENGTH(), // Using updated env value + MAX_FUTURE_LENGTH: Env.MAX_FUTURE_LENGTH(), GENESIS_REWARDS_TIMESTAMP: Env.GENESIS_REWARDS_TIMESTAMP() }) ) @@ -122,18 +122,16 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { "CALCULATION_INTERVAL_SECONDS mismatch" ); assertEq( - rewardsCoordinatorImpl.MAX_REWARDS_DURATION(), Env.MAX_REWARDS_DURATION(), "MAX_REWARDS_DURATION mismatch" + rewardsCoordinatorImpl.MAX_REWARDS_DURATION(), + 63_072_000, + "MAX_REWARDS_DURATION should be updated to 730 days (63072000 seconds)" ); assertEq( rewardsCoordinatorImpl.MAX_RETROACTIVE_LENGTH(), Env.MAX_RETROACTIVE_LENGTH(), "MAX_RETROACTIVE_LENGTH mismatch" ); - assertEq( - rewardsCoordinatorImpl.MAX_FUTURE_LENGTH(), - 63_072_000, - "MAX_FUTURE_LENGTH should be 730 days (63072000 seconds)" - ); + assertEq(rewardsCoordinatorImpl.MAX_FUTURE_LENGTH(), Env.MAX_FUTURE_LENGTH(), "MAX_FUTURE_LENGTH mismatch"); assertEq( rewardsCoordinatorImpl.GENESIS_REWARDS_TIMESTAMP(), Env.GENESIS_REWARDS_TIMESTAMP(), @@ -145,18 +143,18 @@ contract DeployRewardsCoordinatorImpl is EOADeployer { function _validateZeusEnvUpdated() internal view { RewardsCoordinator rewardsCoordinatorImpl = Env.impl.rewardsCoordinator(); - // Validate that the zeus env MAX_FUTURE_LENGTH matches what was deployed + // Validate that the zeus env MAX_REWARDS_DURATION matches what was deployed assertEq( - rewardsCoordinatorImpl.MAX_FUTURE_LENGTH(), - Env.MAX_FUTURE_LENGTH(), - "Deployed MAX_FUTURE_LENGTH should match zeus env value" + rewardsCoordinatorImpl.MAX_REWARDS_DURATION(), + Env.MAX_REWARDS_DURATION(), + "Deployed MAX_REWARDS_DURATION should match zeus env value" ); // Also validate it equals the expected value assertEq( - Env.MAX_FUTURE_LENGTH(), + Env.MAX_REWARDS_DURATION(), 63_072_000, - "Zeus env MAX_FUTURE_LENGTH should be updated to 730 days (63072000 seconds)" + "Zeus env MAX_REWARDS_DURATION should be updated to 730 days (63072000 seconds)" ); } diff --git a/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol index 830845bcc1..d948dc4608 100644 --- a/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol @@ -16,7 +16,7 @@ import {TimelockController} from "@openzeppelin/contracts/governance/TimelockCon * This queues the upgrade to add Rewards v2.2 support: * - Unique stake rewards (linear to allocated unique stake) * - Total stake rewards (linear to total stake) - * - Updated MAX_FUTURE_LENGTH to 730 days (63072000 seconds) + * - Updated MAX_REWARDS_DURATION to 730 days (63072000 seconds) */ contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordinatorImpl { using Env for *; @@ -52,12 +52,13 @@ contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordin }) }); - return Encode.gnosisSafe.execTransaction({ - from: address(Env.timelockController()), - to: Env.multiSendCallOnly(), - op: Encode.Operation.DelegateCall, - data: Encode.multiSend(executorCalls) - }); + return Encode.gnosisSafe + .execTransaction({ + from: address(Env.timelockController()), + to: Env.multiSendCallOnly(), + op: Encode.Operation.DelegateCall, + data: Encode.multiSend(executorCalls) + }); } function testScript() public virtual override { @@ -71,11 +72,7 @@ contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordin TimelockController timelock = Env.timelockController(); bytes memory calldata_to_executor = _getCalldataToExecutor(); bytes32 txHash = timelock.hashOperation({ - target: Env.executorMultisig(), - value: 0, - data: calldata_to_executor, - predecessor: 0, - salt: 0 + target: Env.executorMultisig(), value: 0, data: calldata_to_executor, predecessor: 0, salt: 0 }); // Ensure transaction is not already queued @@ -109,10 +106,10 @@ contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordin address newImpl = address(Env.impl.rewardsCoordinator()); assertTrue(currentImpl != newImpl, "Current and new implementations should be different"); - // Validate current MAX_FUTURE_LENGTH is different from new value + // Validate current MAX_REWARDS_DURATION is different from new value // Note: We access this through the proxy, which still points to the old implementation - uint32 currentMaxFutureLength = rewardsCoordinator.MAX_FUTURE_LENGTH(); - assertTrue(currentMaxFutureLength != 63_072_000, "Current MAX_FUTURE_LENGTH should not be 730 days yet"); + uint32 currentMaxRewardsDuration = rewardsCoordinator.MAX_REWARDS_DURATION(); + assertTrue(currentMaxRewardsDuration != 63_072_000, "Current MAX_REWARDS_DURATION should not be 730 days yet"); // Validate that we're upgrading from the correct version // We can't directly call them since they don't exist, but we can verify the upgrade is needed diff --git a/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol index 9dde9d8ad3..f3425702dd 100644 --- a/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol @@ -12,7 +12,7 @@ import {Encode} from "zeus-templates/utils/Encode.sol"; * This completes the upgrade to add Rewards v2.2 support: * - Unique stake rewards (linear to allocated unique stake) * - Total stake rewards (linear to total stake) - * - Updated MAX_FUTURE_LENGTH to 730 days (63072000 seconds) + * - Updated MAX_REWARDS_DURATION to 730 days (63072000 seconds) */ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { using Env for *; @@ -28,11 +28,7 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { TimelockController timelock = Env.timelockController(); timelock.execute({ - target: Env.executorMultisig(), - value: 0, - payload: calldata_to_executor, - predecessor: 0, - salt: 0 + target: Env.executorMultisig(), value: 0, payload: calldata_to_executor, predecessor: 0, salt: 0 }); } @@ -47,11 +43,7 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { TimelockController timelock = Env.timelockController(); bytes memory calldata_to_executor = _getCalldataToExecutor(); bytes32 txHash = timelock.hashOperation({ - target: Env.executorMultisig(), - value: 0, - data: calldata_to_executor, - predecessor: 0, - salt: 0 + target: Env.executorMultisig(), value: 0, data: calldata_to_executor, predecessor: 0, salt: 0 }); // 2 - Queue. Check that the operation IS ready @@ -118,17 +110,18 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { Env.CALCULATION_INTERVAL_SECONDS(), "CALCULATION_INTERVAL_SECONDS mismatch" ); - assertEq(rewardsCoordinator.MAX_REWARDS_DURATION(), Env.MAX_REWARDS_DURATION(), "MAX_REWARDS_DURATION mismatch"); + + // Validate the updated MAX_REWARDS_DURATION assertEq( - rewardsCoordinator.MAX_RETROACTIVE_LENGTH(), Env.MAX_RETROACTIVE_LENGTH(), "MAX_RETROACTIVE_LENGTH mismatch" + rewardsCoordinator.MAX_REWARDS_DURATION(), + 63_072_000, + "MAX_REWARDS_DURATION should be updated to 730 days (63072000 seconds)" ); - // Validate the updated MAX_FUTURE_LENGTH assertEq( - rewardsCoordinator.MAX_FUTURE_LENGTH(), - 63_072_000, - "MAX_FUTURE_LENGTH should be 730 days (63072000 seconds)" + rewardsCoordinator.MAX_RETROACTIVE_LENGTH(), Env.MAX_RETROACTIVE_LENGTH(), "MAX_RETROACTIVE_LENGTH mismatch" ); + assertEq(rewardsCoordinator.MAX_FUTURE_LENGTH(), Env.MAX_FUTURE_LENGTH(), "MAX_FUTURE_LENGTH mismatch"); assertEq( rewardsCoordinator.GENESIS_REWARDS_TIMESTAMP(), From b4b78b19108a237523561a13c4c86b7d32754ef2 Mon Sep 17 00:00:00 2001 From: 0xrajath Date: Fri, 21 Nov 2025 20:24:55 -0500 Subject: [PATCH 6/6] chore: forge fmt --- .../2-queueRewardsCoordinatorUpgrade.s.sol | 19 +++++++++++-------- .../3-executeRewardsCoordinatorUpgrade.s.sol | 12 ++++++++++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol index d948dc4608..74ebf363ac 100644 --- a/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/2-queueRewardsCoordinatorUpgrade.s.sol @@ -52,13 +52,12 @@ contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordin }) }); - return Encode.gnosisSafe - .execTransaction({ - from: address(Env.timelockController()), - to: Env.multiSendCallOnly(), - op: Encode.Operation.DelegateCall, - data: Encode.multiSend(executorCalls) - }); + return Encode.gnosisSafe.execTransaction({ + from: address(Env.timelockController()), + to: Env.multiSendCallOnly(), + op: Encode.Operation.DelegateCall, + data: Encode.multiSend(executorCalls) + }); } function testScript() public virtual override { @@ -72,7 +71,11 @@ contract QueueRewardsCoordinatorUpgrade is MultisigBuilder, DeployRewardsCoordin TimelockController timelock = Env.timelockController(); bytes memory calldata_to_executor = _getCalldataToExecutor(); bytes32 txHash = timelock.hashOperation({ - target: Env.executorMultisig(), value: 0, data: calldata_to_executor, predecessor: 0, salt: 0 + target: Env.executorMultisig(), + value: 0, + data: calldata_to_executor, + predecessor: 0, + salt: 0 }); // Ensure transaction is not already queued diff --git a/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol index f3425702dd..1a5724600d 100644 --- a/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol +++ b/script/releases/v1.10.0-rewards-v2.2/3-executeRewardsCoordinatorUpgrade.s.sol @@ -28,7 +28,11 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { TimelockController timelock = Env.timelockController(); timelock.execute({ - target: Env.executorMultisig(), value: 0, payload: calldata_to_executor, predecessor: 0, salt: 0 + target: Env.executorMultisig(), + value: 0, + payload: calldata_to_executor, + predecessor: 0, + salt: 0 }); } @@ -43,7 +47,11 @@ contract ExecuteRewardsCoordinatorUpgrade is QueueRewardsCoordinatorUpgrade { TimelockController timelock = Env.timelockController(); bytes memory calldata_to_executor = _getCalldataToExecutor(); bytes32 txHash = timelock.hashOperation({ - target: Env.executorMultisig(), value: 0, data: calldata_to_executor, predecessor: 0, salt: 0 + target: Env.executorMultisig(), + value: 0, + data: calldata_to_executor, + predecessor: 0, + salt: 0 }); // 2 - Queue. Check that the operation IS ready