diff --git a/docs/public-docs/chain-operators/tutorials/upgrade-chain-to-super-roots.mdx b/docs/public-docs/chain-operators/tutorials/upgrade-chain-to-super-roots.mdx index d3f9b3a9ab2..22aea05866b 100644 --- a/docs/public-docs/chain-operators/tutorials/upgrade-chain-to-super-roots.mdx +++ b/docs/public-docs/chain-operators/tutorials/upgrade-chain-to-super-roots.mdx @@ -84,7 +84,7 @@ Read the values you need from `chain.json`: Before you change any configuration: -* **Confirm the template injects `overrides.cfg.startingAnchorRoot`.** Open `superchain-ops/src/template/OPCMUpgradeV800.sol` and check `_buildExtraInstructions`. As of writing it only injects `overrides.cfg.startingRespectedGameType` and `PermittedProxyDeployment`. Without an `overrides.cfg.startingAnchorRoot` override, OPCM falls back to the existing on-chain `startingAnchorRoot`, which on a pre-upgrade chain is an output-root-shaped value with a block-number `l2SequenceNumber` — not a valid super-root anchor. The template must be extended to read a starting super-root anchor from TOML and add it as a third extra instruction. Fix the template before continuing. +* **Confirm the template's extra instructions.** Open `superchain-ops/src/template/OPCMUpgradeV800.sol` and check `_buildExtraInstructions`. As of writing it injects `overrides.cfg.startingRespectedGameType` and `PermittedProxyDeployment`. Both need attention before continuing. `PermittedProxyDeployment` must be dropped: OPCM `8.0.0` permits no proxy deployments during an upgrade, because the unified `DelayedWETH` shipped with the 7.x OPCM, so the instruction now reverts with `OPContractsManagerV2_InvalidUpgradeInstruction`. An `overrides.cfg.startingAnchorRoot` override must be added: without it, OPCM falls back to the existing on-chain `startingAnchorRoot`, which on a pre-upgrade chain is an output-root-shaped value with a block-number `l2SequenceNumber` — not a valid super-root anchor. The template must be extended to read a starting super-root anchor from TOML and add it as an extra instruction. Fix the template before continuing. * **Confirm the RPC endpoint returns a single-chain super root.** Either the chain's op-node RPC endpoint or an op-supernode `//` endpoint can be used. Do not use a multi-chain op-supernode root endpoint; it computes roots across its full dependency set. * **Verify the single-chain RPC endpoint is healthy.** For an op-node or namespaced op-supernode endpoint, confirm it reports a recent finalized L2 head and can produce the corresponding super root: diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index 835169fa428..ea0cdd824c4 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -1078,12 +1078,7 @@ func runEndToEndBootstrapAndApplyUpgradeTest(t *testing.T, afactsFS foundry.Stat GameType: embedded.GameTypeZKDisputeGame, }, }, - ExtraInstructions: []embedded.ExtraInstruction{ - { - Key: "PermittedProxyDeployment", - Data: []byte("DelayedWETH"), - }, - }, + ExtraInstructions: []embedded.ExtraInstruction{}, }, } diff --git a/op-deployer/pkg/deployer/integration_test/cli/manage_add_game_type_v2_test.go b/op-deployer/pkg/deployer/integration_test/cli/manage_add_game_type_v2_test.go index af44c8c5d49..1a4ad9f1fa3 100644 --- a/op-deployer/pkg/deployer/integration_test/cli/manage_add_game_type_v2_test.go +++ b/op-deployer/pkg/deployer/integration_test/cli/manage_add_game_type_v2_test.go @@ -168,7 +168,6 @@ func TestManageAddGameTypeV2_Integration(t *testing.T) { ExtraInstructions: []embedded.ExtraInstruction{ {Key: "overrides.cfg.startingAnchorRoot", Data: startingAnchorRoot}, {Key: "overrides.cfg.startingRespectedGameType", Data: startingRespectedGameType}, - {Key: "PermittedProxyDeployment", Data: []byte("DelayedWETH")}, }, }, } diff --git a/op-devstack/sysgo/add_game_type.go b/op-devstack/sysgo/add_game_type.go index c2dea631ba7..365d4ba3f77 100644 --- a/op-devstack/sysgo/add_game_type.go +++ b/op-devstack/sysgo/add_game_type.go @@ -144,7 +144,6 @@ func addGameTypesForRuntime( Key: "overrides.cfg.startingRespectedGameType", Data: encodeStartingRespectedGameType(t, superPermissionedGameType), }, - {Key: "PermittedProxyDeployment", Data: []byte("DelayedWETH")}, } // Download the contracts artifacts once; reused for the mock verifier deploy and the upgrade. diff --git a/op-devstack/sysgo/superroot_via_upgrade.go b/op-devstack/sysgo/superroot_via_upgrade.go index af108e12637..31de5fa9e1d 100644 --- a/op-devstack/sysgo/superroot_via_upgrade.go +++ b/op-devstack/sysgo/superroot_via_upgrade.go @@ -67,7 +67,6 @@ func upgradeToSuperRoots( ExtraInstructions: []embedded.ExtraInstruction{ {Key: "overrides.cfg.startingAnchorRoot", Data: anchorRootData}, {Key: "overrides.cfg.startingRespectedGameType", Data: respectedGameTypeData}, - {Key: "PermittedProxyDeployment", Data: []byte("DelayedWETH")}, }, }, }) diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUtils.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUtils.json index a05a5009bc7..edbe40d081f 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUtils.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUtils.json @@ -576,6 +576,30 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract ISystemConfig", + "name": "_default", + "type": "address" + }, + { + "internalType": "address", + "name": "_target", + "type": "address" + } + ], + "name": "systemConfigFor", + "outputs": [ + { + "internalType": "contract ISystemConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index 22aa825f14d..c931f8972a7 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -36,8 +36,8 @@ "sourceCodeHash": "0xceeedf69dcb6c05b88fd1569c53606dec02195b4d393a6491876b6d2f0c2ff1f" }, "src/L1/opcm/OPContractsManagerV2.sol:OPContractsManagerV2": { - "initCodeHash": "0x5cf001b0bc8758c996db25ebdfe181516bfeb0697d066bbde2e907e76aaefd03", - "sourceCodeHash": "0xa2b3f54c8350ce4408760a45f631acad4458e466ab7c0bb1a2b7ff4dadf63511" + "initCodeHash": "0x4554a189b4481e32892cc2c276f41e407ba015442568f6779389e649f6d7a4e0", + "sourceCodeHash": "0x7c10505fe79bddcd92e6ff5ee2df648a68b743d608fbb34c2fb5ceef5b271dda" }, "src/L2/BaseFeeVault.sol:BaseFeeVault": { "initCodeHash": "0x18650c65fa6f23fefc6f0c5fff605f12be99fce0bfbcbc0644403138e4c8bb12", diff --git a/packages/contracts-bedrock/src/L1/opcm/OPContractsManagerV2.sol b/packages/contracts-bedrock/src/L1/opcm/OPContractsManagerV2.sol index ef43a37560c..eb56af8a68e 100644 --- a/packages/contracts-bedrock/src/L1/opcm/OPContractsManagerV2.sol +++ b/packages/contracts-bedrock/src/L1/opcm/OPContractsManagerV2.sol @@ -158,9 +158,9 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller { /// - Major bump: New required sequential upgrade /// - Minor bump: Replacement OPCM for same upgrade /// - Patch bump: Development changes (expected for normal dev work) - /// @custom:semver 7.2.5 + /// @custom:semver 8.0.0 function version() public pure returns (string memory) { - return "7.2.5"; + return "8.0.0"; } /// @param _standardValidator The standard validator for this OPCM release. @@ -359,13 +359,7 @@ contract OPContractsManagerV2 is ISemver, OPContractsManagerUtilsCaller { // developers start working on the next release this will automatically become false so // even if the code is somehow forgotten it will not actually apply to the deployment. Make // sure to REMOVE the allowance once the upgrade is complete. - if (SemverComp.lt(_version(), "8.0.0")) { - // Unified DelayedWETH is being deployed for the first time. - // TODO:(#18382): Remove this allowance after unified DelayedWETH is deployed. - if (_isMatchingInstruction(_instruction, Constants.PERMITTED_PROXY_DEPLOYMENT_KEY, "DelayedWETH")) { - return true; - } - + if (SemverComp.lt(_version(), "9.0.0")) { // Super root games migration requires overriding anchor root. if (isDevFeatureEnabled(DevFeatures.SUPER_ROOT_GAMES_MIGRATION)) { if (_isMatchingInstructionByKey(_instruction, "overrides.cfg.startingAnchorRoot")) return true; diff --git a/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol b/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol index 130801d1a16..b585f68190a 100644 --- a/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol +++ b/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol @@ -330,14 +330,6 @@ contract OPContractsManagerV2_Upgrade_TestInit is OPContractsManagerV2_TestInit ) }) ); - - _pushPermittedProxyDeploymentInstruction(); - } - - function _pushPermittedProxyDeploymentInstruction() internal { - v2UpgradeInput.extraInstructions.push( - IOPContractsManagerUtils.ExtraInstruction({ key: "PermittedProxyDeployment", data: bytes("DelayedWETH") }) - ); } /// @notice Helper function that runs an OPCM V2 upgrade, asserts that the upgrade was successful, @@ -929,8 +921,9 @@ contract OPContractsManagerV2_Upgrade_Test is OPContractsManagerV2_Upgrade_TestI ); } - /// @notice Tests that duplicate PermittedProxyDeployment instruction keys are allowed. - function test_upgrade_duplicatePermittedProxyDeploymentKeys_succeeds() public { + /// @notice Tests that duplicate PermittedProxyDeployment instruction keys are exempt from the + /// duplicate instruction check, so validation carries on to the permission check. + function test_upgrade_duplicatePermittedProxyDeploymentKeys_reverts() public { delete v2UpgradeInput.extraInstructions; v2UpgradeInput.extraInstructions.push( IOPContractsManagerUtils.ExtraInstruction({ @@ -944,7 +937,18 @@ contract OPContractsManagerV2_Upgrade_Test is OPContractsManagerV2_Upgrade_TestI data: bytes("DelayedWETH") }) ); - runCurrentUpgradeV2(chainPAO); + + // This upgrade permits no proxy deployments, so the instructions are rejected by the + // permission check. Without the duplicate exemption the revert would instead be + // OPContractsManagerV2_DuplicateUpgradeInstruction. + // nosemgrep: sol-style-use-abi-encodecall + runCurrentUpgradeV2( + chainPAO, + abi.encodeWithSelector( + IOPContractsManagerV2.OPContractsManagerV2_InvalidUpgradeInstruction.selector, + Constants.PERMITTED_PROXY_DEPLOYMENT_KEY + ) + ); } /// @notice INVARIANT: Upgrades must always work when the system is paused. diff --git a/packages/contracts-bedrock/test/setup/ForkL1Live.s.sol b/packages/contracts-bedrock/test/setup/ForkL1Live.s.sol index d3cff3e52e7..7611a900fcf 100644 --- a/packages/contracts-bedrock/test/setup/ForkL1Live.s.sol +++ b/packages/contracts-bedrock/test/setup/ForkL1Live.s.sol @@ -346,19 +346,15 @@ contract ForkL1Live is Deployer, StdAssertions, FeatureFlags { gameArgs: hex"" }); - // Migration needs 3 extra instructions: DelayedWETH proxy + anchor root + game type overrides. - extraInstructions = new IOPContractsManagerUtils.ExtraInstruction[](3); + // Migration needs 2 extra instructions: anchor root + game type overrides. + extraInstructions = new IOPContractsManagerUtils.ExtraInstruction[](2); extraInstructions[0] = IOPContractsManagerUtils.ExtraInstruction({ - key: "PermittedProxyDeployment", - data: bytes("DelayedWETH") - }); - extraInstructions[1] = IOPContractsManagerUtils.ExtraInstruction({ key: "overrides.cfg.startingAnchorRoot", data: abi.encode( Proposal({ root: Hash.wrap(keccak256("migrationAnchorRoot")), l2SequenceNumber: currentAnchorSeqNum + 1 }) ) }); - extraInstructions[2] = IOPContractsManagerUtils.ExtraInstruction({ + extraInstructions[1] = IOPContractsManagerUtils.ExtraInstruction({ key: "overrides.cfg.startingRespectedGameType", data: abi.encode(targetGameType) }); @@ -419,14 +415,8 @@ contract ForkL1Live is Deployer, StdAssertions, FeatureFlags { gameArgs: hex"" }); - // Permit the upgrade to (re)deploy the DelayedWETH proxy if it is missing on the forked - // chain. The standard path deploys no other proxies (unlike the super-root migration path - // above), so this is the only PermittedProxyDeployment instruction it needs. - extraInstructions = new IOPContractsManagerUtils.ExtraInstruction[](1); - extraInstructions[0] = IOPContractsManagerUtils.ExtraInstruction({ - key: "PermittedProxyDeployment", - data: bytes("DelayedWETH") - }); + // The standard upgrade path deploys no proxies, so it needs no extra instructions. + extraInstructions = new IOPContractsManagerUtils.ExtraInstruction[](0); } vm.prank(_delegateCaller, true);