Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/validate-deployment-scripts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
test:
runs-on: protocol-x64-16core
strategy:
fail-fast: true
fail-fast: false
matrix:
env: [mainnet, testnet-sepolia, testnet-hoodi, testnet-base-sepolia, base, preprod-hoodi]

Expand Down
2 changes: 2 additions & 0 deletions script/releases/CoreContractsDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ abstract contract CoreContractsDeployer is EOADeployer {
delegationManager: Env.proxy.delegationManager(),
strategyManager: Env.proxy.strategyManager(),
allocationManager: Env.proxy.allocationManager(),
// NOTE: EmissionsController was added in v1.12.0. For backward compatibility with
// older releases (v1.9.0, etc.), this will be address(Env.executorMultisig()) if not deployed.
emissionsController: Env.proxy.emissionsController(),
pauserRegistry: Env.impl.pauserRegistry(),
permissionController: Env.proxy.permissionController(),
Expand Down
8 changes: 8 additions & 0 deletions script/releases/Env.sol
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,14 @@ library Env {
return ZEnvHelpers.state().deployedProxy(name);
}

function _deployedProxyOr(
string memory name,
address defaultValue
) private view returns (address) {
string memory envvar = string.concat("ZEUS_DEPLOYED_", name, "_Proxy");
return vm.envOr(envvar, defaultValue);
}

function _deployedBeacon(
string memory name
) private view returns (address) {
Expand Down
26 changes: 24 additions & 2 deletions script/releases/TestUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -941,13 +941,15 @@ library TestUtils {
function validateAllocationManagerInitialized(
AllocationManager allocationManager
) internal {
vm.label(address(allocationManager), type(AllocationManager).name);
vm.expectRevert(errInit);
allocationManager.initialize(0);
}

function validateAVSDirectoryInitialized(
AVSDirectory avsDirectory
) internal {
vm.label(address(avsDirectory), type(AVSDirectory).name);
vm.expectRevert(errInit);
avsDirectory.initialize(address(0), 0);
}
Expand All @@ -962,6 +964,7 @@ library TestUtils {
function validateProtocolRegistryInitialized(
ProtocolRegistry protocolRegistry
) internal {
vm.label(address(protocolRegistry), type(ProtocolRegistry).name);
vm.expectRevert(errInit);
protocolRegistry.initialize(address(0), address(0));
}
Expand All @@ -971,13 +974,15 @@ library TestUtils {
function validateRewardsCoordinatorInitialized(
RewardsCoordinator rewardsCoordinator
) internal {
vm.label(address(rewardsCoordinator), type(RewardsCoordinator).name);
vm.expectRevert(errInit);
rewardsCoordinator.initialize(address(0), 0, address(0), 0, 0, address(0));
}

function validateStrategyManagerInitialized(
StrategyManager strategyManager
) internal {
vm.label(address(strategyManager), type(StrategyManager).name);
vm.expectRevert(errInit);
strategyManager.initialize(address(0), address(0), 0);
}
Expand All @@ -988,6 +993,7 @@ library TestUtils {
function validateEigenPodManagerInitialized(
EigenPodManager eigenPodManager
) internal {
vm.label(address(eigenPodManager), type(EigenPodManager).name);
vm.expectRevert(errInit);
eigenPodManager.initialize(address(0), 0);
}
Expand All @@ -996,6 +1002,7 @@ library TestUtils {
function validateEigenStrategyInitialized(
EigenStrategy eigenStrategy
) internal {
vm.label(address(eigenStrategy), type(EigenStrategy).name);
vm.expectRevert(errInit);
eigenStrategy.initialize(IEigen(address(0)), IBackingEigen(address(0)));
}
Expand All @@ -1005,28 +1012,41 @@ library TestUtils {
function validateStrategyBaseTVLLimitsInitialized(
StrategyBaseTVLLimits strategyBaseTVLLimits
) internal {
vm.label(address(strategyBaseTVLLimits), type(StrategyBaseTVLLimits).name);
vm.expectRevert(errInit);
strategyBaseTVLLimits.initialize(0, 0, IERC20(address(0)));
}

function validateStrategyFactoryInitialized(
StrategyFactory strategyFactory
) internal {
vm.expectRevert(errInit);
strategyFactory.initialize(address(0), 0, UpgradeableBeacon(address(0)));
vm.label(address(strategyFactory), type(StrategyFactory).name);

// First test if it reverts at all (catches any revert type)
(bool success,) = address(strategyFactory)
.call(
abi.encodeWithSelector(
StrategyFactory.initialize.selector, address(0), uint256(0), UpgradeableBeacon(address(0))
)
);

// Should always revert since it's already initialized
assertTrue(!success, "StrategyFactory should not be initializable");
}

/// multichain/
function validateCrossChainRegistryInitialized(
CrossChainRegistry crossChainRegistry
) internal {
vm.label(address(crossChainRegistry), type(CrossChainRegistry).name);
vm.expectRevert(errInit);
crossChainRegistry.initialize(address(0), 0, 0);
}

function validateOperatorTableUpdaterInitialized(
OperatorTableUpdater operatorTableUpdater
) internal {
vm.label(address(operatorTableUpdater), type(OperatorTableUpdater).name);
OperatorSet memory dummyOperatorSet = OperatorSet({avs: address(0), id: 0});
IOperatorTableCalculatorTypes.BN254OperatorSetInfo memory dummyBN254Info;
vm.expectRevert(errInit);
Expand All @@ -1039,6 +1059,7 @@ library TestUtils {
function validateTaskMailboxInitialized(
TaskMailbox taskMailbox
) internal {
vm.label(address(taskMailbox), type(TaskMailbox).name);
vm.expectRevert(errInit);
taskMailbox.initialize(address(0), 0, address(0));
}
Expand All @@ -1047,6 +1068,7 @@ library TestUtils {
function validateEmissionsControllerInitialized(
EmissionsController emissionsController
) internal {
vm.label(address(emissionsController), type(EmissionsController).name);
vm.expectRevert(errInit);
emissionsController.initialize(address(0), address(0), 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ contract DeployImplementations is CoreContractsDeployer {
function _runAsEOA() internal virtual override {
vm.startBroadcast();

deployRewardsCoordinator();
// Preprod needs to be upgraded, not redeployed.
if (!(Env._strEq(Env.envVersion(), "1.12.0"))) {
deployEmissionsControllerProxy();
}

deployEmissionsController();
deployEmissionsControllerProxy();
deployRewardsCoordinator();

vm.stopBroadcast();
}
Expand Down
92 changes: 63 additions & 29 deletions script/releases/v1.12.0-incentive-council/2-queueUpgrade.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {IBackingEigen} from "src/contracts/interfaces/IBackingEigen.sol";

/// Steps:
/// 1. Queue EmissionsController upgrade and initialization.
/// 2. Queue RewardsCoordinator upgrade and reinitialization.
/// 2. Queue RewardsCoordinator upgrade (with conditional reinitialization based on current state).
/// 3. Queue add EmissionsController to protocol registry.
/// 4. Queue remove minting rights from old hopper.
/// 5. Queue grant minting rights to EmissionsController.
Expand All @@ -48,33 +48,60 @@ contract QueueUpgrade is DeployImplementations, MultisigBuilder {
MultisigCall[] storage executorCalls = Encode.newMultisigCalls();

// 1. Upgrade EmissionsController proxy to the new implementation and initialize
executorCalls.append({
to: Env.proxyAdmin(),
data: abi.encodeCall(
IProxyAdmin.upgradeAndCall,
(
ITransparentProxy(payable(address(Env.proxy.emissionsController()))),
address(Env.impl.emissionsController()),
abi.encodeCall(
EmissionsController.initialize,
(
Env.opsMultisig(), // initialOwner
Env.incentiveCouncilMultisig(), // initialIncentiveCouncil
0 // initialPausedStatus
// Preprod needs to be upgraded, not redeployed.
if (Env._strEq(Env.envVersion(), "1.12.0")) {
executorCalls.append({
to: Env.proxyAdmin(),
data: abi.encodeCall(
IProxyAdmin.upgrade,
(
ITransparentProxy(payable(address(Env.proxy.emissionsController()))),
address(Env.impl.emissionsController())
)
)
});
} else {
executorCalls.append({
to: Env.proxyAdmin(),
data: abi.encodeCall(
IProxyAdmin.upgradeAndCall,
(
ITransparentProxy(payable(address(Env.proxy.emissionsController()))),
address(Env.impl.emissionsController()),
abi.encodeCall(
EmissionsController.initialize,
(
Env.opsMultisig(), // initialOwner
Env.incentiveCouncilMultisig(), // initialIncentiveCouncil
0 // initialPausedStatus
)
)
)
)
)
});
// 2. Upgrade RewardsCoordinator to the new implementation and reinitialize.
executorCalls.upgradeAndReinitializeRewardsCoordinator({
initialOwner: Env.opsMultisig(),
initialPausedStatus: 0,
rewardsUpdater: Env.REWARDS_UPDATER(),
activationDelay: Env.ACTIVATION_DELAY(),
defaultSplitBips: Env.DEFAULT_SPLIT_BIPS(),
feeRecipient: Env.incentiveCouncilMultisig()
});
});
}
// 2. Upgrade RewardsCoordinator to the new implementation.
// Check if RewardsCoordinator has already been reinitialized by reading _initialized from storage.
// Slot 0 contains: _initialized (uint8 at offset 0) and _initializing (bool at offset 1)
// If _initialized >= 2, reinitializer(2) has already been called.
RewardsCoordinator rc = Env.proxy.rewardsCoordinator();
bytes32 slot0 = vm.load(address(rc), bytes32(uint256(0)));
uint8 initializedVersion = uint8(uint256(slot0) & 0xFF); // Mask to get only the first byte

if (initializedVersion < 2) {
// Not yet reinitialized - perform upgrade with reinitialization
executorCalls.upgradeAndReinitializeRewardsCoordinator({
initialOwner: Env.opsMultisig(),
initialPausedStatus: 0,
rewardsUpdater: Env.REWARDS_UPDATER(),
activationDelay: Env.ACTIVATION_DELAY(),
defaultSplitBips: Env.DEFAULT_SPLIT_BIPS(),
feeRecipient: Env.incentiveCouncilMultisig()
});
} else {
// Already reinitialized - just upgrade without calling initialize
executorCalls.upgradeRewardsCoordinator();
}
// 3. Add EmissionsController to the protocol registry.
address[] memory addresses = new address[](1);
addresses[0] = address(Env.proxy.emissionsController());
Expand Down Expand Up @@ -111,6 +138,10 @@ contract QueueUpgrade is DeployImplementations, MultisigBuilder {
}

function testScript() public virtual override {
if (!Env.isCoreProtocolDeployed()) {
return;
}

runAsEOA();

TimelockController timelock = Env.timelockController();
Expand Down Expand Up @@ -151,10 +182,13 @@ contract QueueUpgrade is DeployImplementations, MultisigBuilder {
require(beigen.isMinter(Env.legacyTokenHopper()), "Old hopper should have minting rights before upgrade");
}
// Ensure EmissionsController does NOT have minting rights yet
require(
!beigen.isMinter(address(Env.proxy.emissionsController())),
"EmissionsController should NOT have minting rights before upgrade"
);
// Skip check if we are on preprod, as the EmissionsController is already deployed.
if (!Env._strEq(Env.envVersion(), "1.12.0")) {
require(
!beigen.isMinter(address(Env.proxy.emissionsController())),
"EmissionsController should NOT have minting rights before upgrade"
);
}
}
}

2 changes: 1 addition & 1 deletion script/releases/v1.12.0-incentive-council/upgrade.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "incentives-emissions-controller",
"from": ">=1.9.0",
"from": ">=1.11.0",
"to": "1.12.0",
"phases": [
{
Expand Down

This file was deleted.

Loading