From 8534b61b135714ad4a1f4b2a897e328c4c4cd265 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 01:24:54 +0100 Subject: [PATCH 01/35] remove proxyAdmin inputs from opcm and sv, derive it from the sysCfg, fix tests --- .../interfaces/L1/IOPContractsManager.sol | 12 +- .../IOPContractsManagerStandardValidator.sol | 25 ++++- .../scripts/deploy/AddGameType.s.sol | 1 - .../deploy/GenerateOPCMMigrateCalldata.sol | 5 - .../snapshots/abi/OPContractsManager.json | 25 ----- .../abi/OPContractsManagerGameTypeAdder.json | 5 - .../OPContractsManagerInteropMigrator.json | 5 - .../OPContractsManagerStandardValidator.json | 10 -- .../abi/OPContractsManagerUpgrader.json | 5 - .../snapshots/semver-lock.json | 8 +- .../src/L1/OPContractsManager.sol | 104 +++++++++--------- .../OPContractsManagerStandardValidator.sol | 28 ++--- .../test/L1/OPContractsManager.t.sol | 74 ++++++++----- .../OPContractsManagerStandardValidator.t.sol | 13 +-- .../test/opcm/InteropMigration.t.sol | 16 +-- .../test/opcm/UpgradeOPChain.t.sol | 17 +-- .../test/setup/ForkLive.s.sol | 32 ++++-- 17 files changed, 182 insertions(+), 203 deletions(-) diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol index aaffb5972a3e9..a128272cc3b41 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol @@ -221,7 +221,6 @@ interface IOPContractsManager { /// @notice The input required to identify a chain for upgrading. struct OpChainConfig { ISystemConfig systemConfigProxy; - IProxyAdmin proxyAdmin; Claim absolutePrestate; } @@ -235,7 +234,6 @@ interface IOPContractsManager { struct AddGameInput { string saltMixer; ISystemConfig systemConfig; - IProxyAdmin proxyAdmin; IDelayedWETH delayedWETH; GameType disputeGameType; Claim disputeAbsolutePrestate; @@ -390,3 +388,13 @@ interface IOPContractsManager { /// @notice Returns the implementation contract addresses. function implementations() external view returns (Implementations memory); } + +interface IOldOPContractsManager { + struct OpChainConfig { + ISystemConfig systemConfigProxy; + IProxyAdmin proxyAdmin; + Claim absolutePrestate; + } + + function upgrade(OpChainConfig[] memory _opChainConfigs) external; +} diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol index 15cb768e44d41..95a3448cbdaae 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol @@ -23,7 +23,6 @@ interface IOPContractsManagerStandardValidator { } struct ValidationInput { - IProxyAdmin proxyAdmin; ISystemConfig sysCfg; bytes32 absolutePrestate; uint256 l2ChainID; @@ -75,3 +74,27 @@ interface IOPContractsManagerStandardValidator { ) external; } + +interface IOldOPContractsManagerStandardValidator { + struct ValidationInput { + IProxyAdmin proxyAdmin; + ISystemConfig sysCfg; + bytes32 absolutePrestate; + uint256 l2ChainID; + } + + struct ValidationOverrides { + address l1PAOMultisig; + address challenger; + } + + function validateWithOverrides( + ValidationInput memory _input, + bool _allowFailure, + ValidationOverrides memory _overrides + ) + external + view + returns (string memory); + function validate(ValidationInput memory _input, bool _allowFailure) external view returns (string memory); +} diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index 5d65d1111cdcc..e69dfd019c3c2 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -62,7 +62,6 @@ contract AddGameType is Script { gameConfigs[0] = OPContractsManager.AddGameInput({ saltMixer: _agi.saltMixer, systemConfig: _agi.systemConfigProxy, - proxyAdmin: _agi.opChainProxyAdmin, delayedWETH: _agi.delayedWETHProxy, disputeGameType: _agi.disputeGameType, disputeAbsolutePrestate: _agi.disputeAbsolutePrestate, diff --git a/packages/contracts-bedrock/scripts/deploy/GenerateOPCMMigrateCalldata.sol b/packages/contracts-bedrock/scripts/deploy/GenerateOPCMMigrateCalldata.sol index 50ad81865add4..9e7ee6e78dbe8 100644 --- a/packages/contracts-bedrock/scripts/deploy/GenerateOPCMMigrateCalldata.sol +++ b/packages/contracts-bedrock/scripts/deploy/GenerateOPCMMigrateCalldata.sol @@ -121,17 +121,12 @@ contract GenerateOPCMMigrateCalldata is Script { for (uint256 i = 0; i < j.length; i++) { opChainConfigs[i] = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(j[i].systemConfigProxy), - proxyAdmin: IProxyAdmin(j[i].proxyAdmin), absolutePrestate: Claim.wrap(absolutePrestate) }); require( opChainConfigs[i].systemConfigProxy != ISystemConfig(address(0)), "GenerateOPCMMigrateCalldata: systemConfigProxy cannot be 0" ); - require( - opChainConfigs[i].proxyAdmin != IProxyAdmin(address(0)), - "GenerateOPCMMigrateCalldata: proxyAdmin cannot be 0" - ); } return IOPContractsManagerInteropMigrator.MigrateInput({ diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json index b9e54537a4d33..030f553b3972b 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json @@ -59,11 +59,6 @@ "name": "systemConfig", "type": "address" }, - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "contract IDelayedWETH", "name": "delayedWETH", @@ -629,11 +624,6 @@ "name": "systemConfigProxy", "type": "address" }, - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "Claim", "name": "absolutePrestate", @@ -798,11 +788,6 @@ "name": "systemConfigProxy", "type": "address" }, - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "Claim", "name": "absolutePrestate", @@ -841,11 +826,6 @@ "inputs": [ { "components": [ - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "contract ISystemConfig", "name": "sysCfg", @@ -887,11 +867,6 @@ "inputs": [ { "components": [ - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "contract ISystemConfig", "name": "sysCfg", diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerGameTypeAdder.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerGameTypeAdder.json index 6bf4393418702..f5e56936bdf34 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerGameTypeAdder.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerGameTypeAdder.json @@ -24,11 +24,6 @@ "name": "systemConfig", "type": "address" }, - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "contract IDelayedWETH", "name": "delayedWETH", diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInteropMigrator.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInteropMigrator.json index b06cd541bb38d..69a4652a4dc97 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInteropMigrator.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInteropMigrator.json @@ -327,11 +327,6 @@ "name": "systemConfigProxy", "type": "address" }, - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "Claim", "name": "absolutePrestate", diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerStandardValidator.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerStandardValidator.json index 7ec9ab0bc717f..3816126313ef2 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerStandardValidator.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerStandardValidator.json @@ -335,11 +335,6 @@ "inputs": [ { "components": [ - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "contract ISystemConfig", "name": "sysCfg", @@ -381,11 +376,6 @@ "inputs": [ { "components": [ - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "contract ISystemConfig", "name": "sysCfg", diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUpgrader.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUpgrader.json index 512a83ae75cff..967ac19b0a6e1 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUpgrader.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUpgrader.json @@ -261,11 +261,6 @@ "name": "systemConfigProxy", "type": "address" }, - { - "internalType": "contract IProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, { "internalType": "Claim", "name": "absolutePrestate", diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index 366cbca9da7c8..b3087d622d169 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -20,12 +20,12 @@ "sourceCodeHash": "0xfca613b5d055ffc4c3cbccb0773ddb9030abedc1aa6508c9e2e7727cc0cd617b" }, "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0x9f9a3738b05cae6597ea9a5c5747f7dbd3a5328b05a319955054fbd8b1aaa791", - "sourceCodeHash": "0x154c764083f353e2a56337c0dd5cbcd6f2e12c21966cd0580c7a0f96c4e147dd" + "initCodeHash": "0x68fdd3da390465694255695e141f8b337b0502790044c7d2d94899616fcfd496", + "sourceCodeHash": "0x219fefb1e4fa08af3216b7808a18606aba925ee2b39b68ccbd590f976527aff5" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { - "initCodeHash": "0x57d6a6729d887ead009d518e8f17fa0d26bfc97b8efe1494ab4ef8dbb000d109", - "sourceCodeHash": "0x1d58891954cf782d2fe4f112b0c7fd25be991c2b8873f10d8545c653b517cac9" + "initCodeHash": "0xafe49b4d5d481ba0e874f5c81227b610c9c4e365691426354a8dcefdcabba9a3", + "sourceCodeHash": "0xa4efe31937aca12452a4cd1a4bfd660de84eab2ee11e95df38362dad1d6a8d60" }, "src/L1/OptimismPortal2.sol:OptimismPortal2": { "initCodeHash": "0x5bf576ea7f566e402a997204988471fc9b971410aa9dff8fe810b10baf6b7456", diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index 142fa67ea358f..05bcccde5c283 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -429,7 +429,7 @@ contract OPContractsManagerGameTypeAdder is OPContractsManagerBase { payable( deployProxy( l2ChainId, - gameConfig.proxyAdmin, + gameConfig.systemConfig.proxyAdmin(), gameConfig.saltMixer, string.concat("DelayedWETH-", Strings.toString(uint256(gameTypeInt))) ) @@ -438,7 +438,7 @@ contract OPContractsManagerGameTypeAdder is OPContractsManagerBase { // Initialize the proxy. upgradeToAndCall( - gameConfig.proxyAdmin, + gameConfig.systemConfig.proxyAdmin(), address(outputs[i].delayedWETH), getImplementations().delayedWETHImpl, abi.encodeCall(IDelayedWETH.initialize, (gameConfig.systemConfig)) @@ -639,7 +639,6 @@ contract OPContractsManagerGameTypeAdder is OPContractsManagerBase { disputeAbsolutePrestate: prestate, saltMixer: reusableSaltMixer(_prestateUpdateInputs[i].systemConfigProxy), systemConfig: _prestateUpdateInputs[i].systemConfigProxy, - proxyAdmin: _prestateUpdateInputs[i].systemConfigProxy.proxyAdmin(), delayedWETH: IDelayedWETH(payable(address(gameParams.weth))), disputeGameType: gameParams.gameType, disputeMaxGameDepth: gameParams.maxGameDepth, @@ -723,8 +722,11 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase { ) internal { + // Get the proxyAdmin from the systemConfig. + IProxyAdmin proxyAdmin = _opChainConfig.systemConfigProxy.proxyAdmin(); + // Upgrade the SystemConfig first. - upgradeTo(_opChainConfig.proxyAdmin, address(_opChainConfig.systemConfigProxy), _impls.systemConfigImpl); + upgradeTo(proxyAdmin, address(_opChainConfig.systemConfigProxy), _impls.systemConfigImpl); // Grab the OptimismPortal contract. IOptimismPortal optimismPortal = IOptimismPortal(payable(_opChainConfig.systemConfigProxy.optimismPortal())); @@ -733,7 +735,7 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase { if (isDevFeatureEnabled(DevFeatures.OPTIMISM_PORTAL_INTEROP)) { // This does NOT run in production. // Upgrade the OptimismPortal contract implementation. - upgradeTo(_opChainConfig.proxyAdmin, address(optimismPortal), _impls.optimismPortalInteropImpl); + upgradeTo(proxyAdmin, address(optimismPortal), _impls.optimismPortalInteropImpl); // If we don't already have an ETHLockbox, deploy and initialize it. IETHLockbox ethLockbox = optimismPortal.ethLockbox(); @@ -742,7 +744,7 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase { ethLockbox = IETHLockbox( deployProxy({ _l2ChainId: _l2ChainId, - _proxyAdmin: _opChainConfig.proxyAdmin, + _proxyAdmin: proxyAdmin, _saltMixer: reusableSaltMixer(_opChainConfig.systemConfigProxy), _contractName: "ETHLockbox-U16a" }) @@ -752,7 +754,7 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase { IOptimismPortal[] memory portals = new IOptimismPortal[](1); portals[0] = optimismPortal; upgradeToAndCall( - _opChainConfig.proxyAdmin, + proxyAdmin, address(ethLockbox), _impls.ethLockboxImpl, abi.encodeCall(IETHLockbox.initialize, (_opChainConfig.systemConfigProxy, portals)) @@ -770,12 +772,12 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase { IOptimismPortalInterop(payable(optimismPortal)).upgrade(anchorStateRegistry, ethLockbox); } else { // This runs in production. - upgradeTo(_opChainConfig.proxyAdmin, address(optimismPortal), _impls.optimismPortalImpl); + upgradeTo(proxyAdmin, address(optimismPortal), _impls.optimismPortalImpl); } // Upgrade the OptimismMintableERC20Factory contract. upgradeTo( - _opChainConfig.proxyAdmin, + proxyAdmin, _opChainConfig.systemConfigProxy.optimismMintableERC20Factory(), _impls.optimismMintableERC20FactoryImpl ); @@ -784,7 +786,7 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase { IDisputeGameFactory dgf = IDisputeGameFactory(_opChainConfig.systemConfigProxy.disputeGameFactory()); // Need to upgrade the DisputeGameFactory implementation, no internal upgrade call. - upgradeTo(_opChainConfig.proxyAdmin, address(dgf), _impls.disputeGameFactoryImpl); + upgradeTo(proxyAdmin, address(dgf), _impls.disputeGameFactoryImpl); // Separate context to avoid stack too deep. { @@ -794,24 +796,20 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase { // Upgrade the L1CrossDomainMessenger contract. upgradeTo( - _opChainConfig.proxyAdmin, + proxyAdmin, address(IL1CrossDomainMessenger(opChainAddrs.l1CrossDomainMessenger)), _impls.l1CrossDomainMessengerImpl ); // Upgrade the L1StandardBridge contract. upgradeTo( - _opChainConfig.proxyAdmin, + proxyAdmin, address(IL1StandardBridge(payable(opChainAddrs.l1StandardBridge))), _impls.l1StandardBridgeImpl ); // Upgrade the L1ERC721Bridge contract. - upgradeTo( - _opChainConfig.proxyAdmin, - address(IL1ERC721Bridge(opChainAddrs.l1ERC721Bridge)), - _impls.l1ERC721BridgeImpl - ); + upgradeTo(proxyAdmin, address(IL1ERC721Bridge(opChainAddrs.l1ERC721Bridge)), _impls.l1ERC721BridgeImpl); } // All chains have the PermissionedDisputeGame, grab that. @@ -880,7 +878,6 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase { /// @notice Verifies that all OpChainConfig inputs are valid and reverts if any are invalid. function assertValidOpChainConfig(OPContractsManager.OpChainConfig memory _config) internal view { assertValidContractAddress(address(_config.systemConfigProxy)); - assertValidContractAddress(address(_config.proxyAdmin)); } /// @notice Deploys and sets a new dispute game implementation @@ -1452,11 +1449,14 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { /// you know what you're doing and that you are prepared to fully execute this migration. /// @param _input The input parameters for the migration. function migrate(MigrateInput calldata _input) public virtual { + // Get the proxyAdmin from the first system config. + IProxyAdmin proxyAdmin = _input.opChainConfigs[0].systemConfigProxy.proxyAdmin(); + // Check that all of the configs have the same proxy admin owner and prestate. for (uint256 i = 0; i < _input.opChainConfigs.length; i++) { // Different chains might actually have different ProxyAdmin contracts, but it's fine // as long as the owner of all of those contracts is the same. - if (_input.opChainConfigs[i].proxyAdmin.owner() != _input.opChainConfigs[0].proxyAdmin.owner()) { + if (_input.opChainConfigs[i].systemConfigProxy.proxyAdmin().owner() != proxyAdmin.owner()) { revert OPContractsManagerInteropMigrator_ProxyAdminOwnerMismatch(); } if (_input.opChainConfigs[i].absolutePrestate.raw() != _input.opChainConfigs[0].absolutePrestate.raw()) { @@ -1481,7 +1481,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { // ProxyAdmin contract as the ProxyAdmin for all of the newly shared contracts. This is // safe because we already checked that all of the provided chains have the same ProxyAdmin // owner and therefore have the same access models. - address proxyAdminOwner = _input.opChainConfigs[0].proxyAdmin.owner(); + address proxyAdminOwner = proxyAdmin.owner(); // Deploy the new ETHLockbox. // NOTE that here and in the rest of this function we use block.timestamp as a fake chain @@ -1492,7 +1492,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { IETHLockbox newEthLockbox = IETHLockbox( deployProxy({ _l2ChainId: block.timestamp, - _proxyAdmin: _input.opChainConfigs[0].proxyAdmin, + _proxyAdmin: proxyAdmin, _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), _contractName: "ETHLockbox-Interop" }) @@ -1509,7 +1509,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { // Initialize the new ETHLockbox. // Note that this authorizes the portals to use the ETHLockbox. upgradeToAndCall( - _input.opChainConfigs[0].proxyAdmin, + proxyAdmin, address(newEthLockbox), getImplementations().ethLockboxImpl, abi.encodeCall(IETHLockbox.initialize, (portals[0].systemConfig(), castedPortals)) @@ -1520,7 +1520,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { IDisputeGameFactory newDisputeGameFactory = IDisputeGameFactory( deployProxy({ _l2ChainId: block.timestamp, - _proxyAdmin: _input.opChainConfigs[0].proxyAdmin, + _proxyAdmin: proxyAdmin, _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), _contractName: "DisputeGameFactory-Interop" }) @@ -1528,7 +1528,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { // Initialize the new DisputeGameFactory. upgradeToAndCall( - _input.opChainConfigs[0].proxyAdmin, + proxyAdmin, address(newDisputeGameFactory), getImplementations().disputeGameFactoryImpl, abi.encodeCall(IDisputeGameFactory.initialize, (proxyAdminOwner)) @@ -1538,7 +1538,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { IAnchorStateRegistry newAnchorStateRegistry = IAnchorStateRegistry( deployProxy({ _l2ChainId: block.timestamp, - _proxyAdmin: _input.opChainConfigs[0].proxyAdmin, + _proxyAdmin: proxyAdmin, _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), _contractName: "AnchorStateRegistry-Interop" }) @@ -1555,7 +1555,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { // We can use portals[0].systemConfig() as they are members of the same superchain cluster (shared lockbox) // Initialize the new AnchorStateRegistry. upgradeToAndCall( - _input.opChainConfigs[0].proxyAdmin, + proxyAdmin, address(newAnchorStateRegistry), getImplementations().anchorStateRegistryImpl, abi.encodeCall( @@ -1597,7 +1597,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { payable( deployProxy({ _l2ChainId: block.timestamp, - _proxyAdmin: _input.opChainConfigs[0].proxyAdmin, + _proxyAdmin: proxyAdmin, _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), _contractName: "DelayedWETH-Interop-Permissioned" }) @@ -1606,12 +1606,15 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { // Initialize the new DelayedWETH proxy. upgradeToAndCall( - _input.opChainConfigs[0].proxyAdmin, + proxyAdmin, address(newPermissionedDelayedWETHProxy), getImplementations().delayedWETHImpl, abi.encodeCall(IDelayedWETH.initialize, (portals[0].systemConfig())) ); + // Fix stack too deep + MigrateInput memory input = _input; + // Deploy the new SuperPermissionedDisputeGame. // NOTE that we use a chain id of 0 here (instead of the block timestamp) because the // use of the chain id is different and actually passed into the constructor of the @@ -1623,24 +1626,24 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { blueprints().superPermissionedDisputeGame2, computeSalt( block.timestamp, - reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), + reusableSaltMixer(input.opChainConfigs[0].systemConfigProxy), "SuperPermissionedDisputeGame" ), encodePermissionedSuperFDGConstructor( ISuperFaultDisputeGame.GameConstructorParams({ gameType: GameTypes.SUPER_PERMISSIONED_CANNON, - absolutePrestate: _input.opChainConfigs[0].absolutePrestate, - maxGameDepth: _input.gameParameters.maxGameDepth, - splitDepth: _input.gameParameters.splitDepth, - clockExtension: _input.gameParameters.clockExtension, - maxClockDuration: _input.gameParameters.maxClockDuration, + absolutePrestate: input.opChainConfigs[0].absolutePrestate, + maxGameDepth: input.gameParameters.maxGameDepth, + splitDepth: input.gameParameters.splitDepth, + clockExtension: input.gameParameters.clockExtension, + maxClockDuration: input.gameParameters.maxClockDuration, vm: IBigStepper(getImplementations().mipsImpl), weth: newPermissionedDelayedWETHProxy, anchorStateRegistry: newAnchorStateRegistry, l2ChainId: 0 }), - _input.gameParameters.proposer, - _input.gameParameters.challenger + input.gameParameters.proposer, + input.gameParameters.challenger ) ) ); @@ -1649,7 +1652,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { newDisputeGameFactory.setImplementation( GameTypes.SUPER_PERMISSIONED_CANNON, IDisputeGame(address(newSuperPDG)) ); - newDisputeGameFactory.setInitBond(GameTypes.SUPER_PERMISSIONED_CANNON, _input.gameParameters.initBond); + newDisputeGameFactory.setInitBond(GameTypes.SUPER_PERMISSIONED_CANNON, input.gameParameters.initBond); } // If the permissionless game is being used, set that up too. @@ -1659,7 +1662,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { payable( deployProxy({ _l2ChainId: block.timestamp, - _proxyAdmin: _input.opChainConfigs[0].proxyAdmin, + _proxyAdmin: proxyAdmin, _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), _contractName: "DelayedWETH-Interop-Permissionless" }) @@ -1668,12 +1671,15 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { // Initialize the new DelayedWETH proxy. upgradeToAndCall( - _input.opChainConfigs[0].proxyAdmin, + proxyAdmin, address(newPermissionlessDelayedWETHProxy), getImplementations().delayedWETHImpl, abi.encodeCall(IDelayedWETH.initialize, (portals[0].systemConfig())) ); + // Fix stack too deep + MigrateInput memory input = _input; + // Deploy the new SuperFaultDisputeGame. ISuperFaultDisputeGame newSuperFDG = ISuperFaultDisputeGame( Blueprint.deployFrom( @@ -1681,17 +1687,17 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { blueprints().superPermissionlessDisputeGame2, computeSalt( block.timestamp, - reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), + reusableSaltMixer(input.opChainConfigs[0].systemConfigProxy), "SuperFaultDisputeGame" ), encodePermissionlessSuperFDGConstructor( ISuperFaultDisputeGame.GameConstructorParams({ gameType: GameTypes.SUPER_CANNON, - absolutePrestate: _input.opChainConfigs[0].absolutePrestate, - maxGameDepth: _input.gameParameters.maxGameDepth, - splitDepth: _input.gameParameters.splitDepth, - clockExtension: _input.gameParameters.clockExtension, - maxClockDuration: _input.gameParameters.maxClockDuration, + absolutePrestate: input.opChainConfigs[0].absolutePrestate, + maxGameDepth: input.gameParameters.maxGameDepth, + splitDepth: input.gameParameters.splitDepth, + clockExtension: input.gameParameters.clockExtension, + maxClockDuration: input.gameParameters.maxClockDuration, vm: IBigStepper(getImplementations().mipsImpl), weth: newPermissionlessDelayedWETHProxy, anchorStateRegistry: newAnchorStateRegistry, @@ -1703,7 +1709,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { // Register the new SuperFaultDisputeGame. newDisputeGameFactory.setImplementation(GameTypes.SUPER_CANNON, IDisputeGame(address(newSuperFDG))); - newDisputeGameFactory.setInitBond(GameTypes.SUPER_CANNON, _input.gameParameters.initBond); + newDisputeGameFactory.setInitBond(GameTypes.SUPER_CANNON, input.gameParameters.initBond); } } } @@ -1803,7 +1809,6 @@ contract OPContractsManager is ISemver { /// @notice The input required to identify a chain for upgrading, along with new prestate hashes struct OpChainConfig { ISystemConfig systemConfigProxy; - IProxyAdmin proxyAdmin; Claim absolutePrestate; } @@ -1817,7 +1822,6 @@ contract OPContractsManager is ISemver { struct AddGameInput { string saltMixer; ISystemConfig systemConfig; - IProxyAdmin proxyAdmin; IDelayedWETH delayedWETH; GameType disputeGameType; Claim disputeAbsolutePrestate; @@ -1837,9 +1841,9 @@ contract OPContractsManager is ISemver { // -------- Constants and Variables -------- - /// @custom:semver 4.0.0 + /// @custom:semver 4.1.0 function version() public pure virtual returns (string memory) { - return "4.0.0"; + return "4.1.0"; } OPContractsManagerGameTypeAdder public immutable opcmGameTypeAdder; diff --git a/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol b/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol index f82b21b248c57..5928b32356333 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol @@ -112,7 +112,6 @@ contract OPContractsManagerStandardValidator is ISemver { /// @notice Struct containing the input parameters for the validation process. struct ValidationInput { - IProxyAdmin proxyAdmin; ISystemConfig sysCfg; bytes32 absolutePrestate; uint256 l2ChainID; @@ -260,8 +259,7 @@ contract OPContractsManagerStandardValidator is ISemver { _errors = internalRequire(outputConfig.maximumBaseFee == type(uint128).max, "SYSCON-100", _errors); _errors = internalRequire(_sysCfg.operatorFeeScalar() == 0, "SYSCON-110", _errors); _errors = internalRequire(_sysCfg.operatorFeeConstant() == 0, "SYSCON-120", _errors); - _errors = internalRequire(getProxyAdmin(address(_sysCfg)) == _admin, "SYSCON-130", _errors); - _errors = internalRequire(_sysCfg.superchainConfig() == superchainConfig, "SYSCON-140", _errors); + _errors = internalRequire(_sysCfg.superchainConfig() == superchainConfig, "SYSCON-130", _errors); return _errors; } @@ -760,22 +758,24 @@ contract OPContractsManagerStandardValidator is ISemver { { string memory _errors = ""; + IProxyAdmin _proxyAdmin = _input.sysCfg.proxyAdmin(); + _errors = assertValidSuperchainConfig(_errors); - _errors = assertValidProxyAdmin(_errors, _input.proxyAdmin, _overrides); - _errors = assertValidSystemConfig(_errors, _input.sysCfg, _input.proxyAdmin); - _errors = assertValidL1CrossDomainMessenger(_errors, _input.sysCfg, _input.proxyAdmin); - _errors = assertValidL1StandardBridge(_errors, _input.sysCfg, _input.proxyAdmin); - _errors = assertValidOptimismMintableERC20Factory(_errors, _input.sysCfg, _input.proxyAdmin); - _errors = assertValidL1ERC721Bridge(_errors, _input.sysCfg, _input.proxyAdmin); - _errors = assertValidOptimismPortal(_errors, _input.sysCfg, _input.proxyAdmin); - _errors = assertValidDisputeGameFactory(_errors, _input.sysCfg, _input.proxyAdmin, _overrides); + _errors = assertValidProxyAdmin(_errors, _proxyAdmin, _overrides); + _errors = assertValidSystemConfig(_errors, _input.sysCfg, _proxyAdmin); + _errors = assertValidL1CrossDomainMessenger(_errors, _input.sysCfg, _proxyAdmin); + _errors = assertValidL1StandardBridge(_errors, _input.sysCfg, _proxyAdmin); + _errors = assertValidOptimismMintableERC20Factory(_errors, _input.sysCfg, _proxyAdmin); + _errors = assertValidL1ERC721Bridge(_errors, _input.sysCfg, _proxyAdmin); + _errors = assertValidOptimismPortal(_errors, _input.sysCfg, _proxyAdmin); + _errors = assertValidDisputeGameFactory(_errors, _input.sysCfg, _proxyAdmin, _overrides); _errors = assertValidPermissionedDisputeGame( - _errors, _input.sysCfg, _input.absolutePrestate, _input.l2ChainID, _input.proxyAdmin, _overrides + _errors, _input.sysCfg, _input.absolutePrestate, _input.l2ChainID, _proxyAdmin, _overrides ); _errors = assertValidPermissionlessDisputeGame( - _errors, _input.sysCfg, _input.absolutePrestate, _input.l2ChainID, _input.proxyAdmin, _overrides + _errors, _input.sysCfg, _input.absolutePrestate, _input.l2ChainID, _proxyAdmin, _overrides ); - _errors = assertValidETHLockbox(_errors, _input.sysCfg, _input.proxyAdmin); + _errors = assertValidETHLockbox(_errors, _input.sysCfg, _proxyAdmin); string memory overridesString = getOverridesString(_overrides); string memory finalErrors = _errors; diff --git a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol index 4d2056137fc5e..239f589a12783 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol @@ -38,9 +38,13 @@ import { IOPContractsManager, IOPContractsManagerGameTypeAdder, IOPContractsManagerInteropMigrator, - IOPContractsManagerUpgrader + IOPContractsManagerUpgrader, + IOldOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; -import { IOPContractsManagerStandardValidator } from "interfaces/L1/IOPContractsManagerStandardValidator.sol"; +import { + IOPContractsManagerStandardValidator, + IOldOPContractsManagerStandardValidator +} from "interfaces/L1/IOPContractsManagerStandardValidator.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; import { ISuperFaultDisputeGame } from "interfaces/dispute/ISuperFaultDisputeGame.sol"; @@ -136,11 +140,7 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { vm.etch(upgrader, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller")); opChainConfigs.push( - IOPContractsManager.OpChainConfig({ - systemConfigProxy: systemConfig, - proxyAdmin: proxyAdmin, - absolutePrestate: absolutePrestate - }) + IOPContractsManager.OpChainConfig({ systemConfigProxy: systemConfig, absolutePrestate: absolutePrestate }) ); // Retrieve the l2ChainId, which was read from the superchain-registry, and saved in @@ -217,9 +217,21 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { } // Execute the chain upgrade. - DelegateCaller(_delegateCaller).dcForward( - address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs)) - ); + if (address(_opcm) == 0x8123739C1368C2DEDc8C564255bc417FEEeBFF9D) { + IOldOPContractsManager.OpChainConfig[] memory opChains = new IOldOPContractsManager.OpChainConfig[](1); + opChains[0] = IOldOPContractsManager.OpChainConfig({ + systemConfigProxy: systemConfig, + proxyAdmin: proxyAdmin, + absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) + }); + DelegateCaller(_delegateCaller).dcForward( + address(_opcm), abi.encodeCall(IOldOPContractsManager.upgrade, (opChains)) + ); + } else { + DelegateCaller(_delegateCaller).dcForward( + address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs)) + ); + } // Return early if a revert was expected. Otherwise we'll get errors below. if (_revertBytes.length > 0) { @@ -261,15 +273,26 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { } // Run the StandardValidator checks. - validator.validate( - IOPContractsManagerStandardValidator.ValidationInput({ - proxyAdmin: opChainConfigs[0].proxyAdmin, - sysCfg: opChainConfigs[0].systemConfigProxy, - absolutePrestate: opChainConfigs[0].absolutePrestate.raw(), - l2ChainID: l2ChainId - }), - false - ); + if (address(validator) == 0x845FEF377Fa9C678B3eBe33B024678538f1215dD) { + IOldOPContractsManagerStandardValidator(address(validator)).validate( + IOldOPContractsManagerStandardValidator.ValidationInput({ + proxyAdmin: opChainConfigs[0].systemConfigProxy.proxyAdmin(), + sysCfg: opChainConfigs[0].systemConfigProxy, + absolutePrestate: opChainConfigs[0].absolutePrestate.raw(), + l2ChainID: l2ChainId + }), + false + ); + } else { + validator.validate( + IOPContractsManagerStandardValidator.ValidationInput({ + sysCfg: opChainConfigs[0].systemConfigProxy, + absolutePrestate: opChainConfigs[0].absolutePrestate.raw(), + l2ChainID: l2ChainId + }), + false + ); + } } /// @notice Executes all past upgrades that have not yet been executed on mainnet as of the @@ -398,7 +421,6 @@ contract OPContractsManager_TestInit is CommonTest { return IOPContractsManager.AddGameInput({ saltMixer: "hello", systemConfig: chainDeployOutput1.systemConfigProxy, - proxyAdmin: chainDeployOutput1.opChainProxyAdmin, delayedWETH: IDelayedWETH(payable(address(0))), disputeGameType: _gameType, disputeAbsolutePrestate: Claim.wrap(bytes32(hex"deadbeef1234")), @@ -1483,12 +1505,8 @@ contract OPContractsManager_Migrate_Test is OPContractsManager_TestInit { }); IOPContractsManager.OpChainConfig[] memory opChainConfigs = new IOPContractsManager.OpChainConfig[](2); - opChainConfigs[0] = IOPContractsManager.OpChainConfig( - chainDeployOutput1.systemConfigProxy, chainDeployOutput1.opChainProxyAdmin, absolutePrestate1 - ); - opChainConfigs[1] = IOPContractsManager.OpChainConfig( - chainDeployOutput2.systemConfigProxy, chainDeployOutput2.opChainProxyAdmin, absolutePrestate1 - ); + opChainConfigs[0] = IOPContractsManager.OpChainConfig(chainDeployOutput1.systemConfigProxy, absolutePrestate1); + opChainConfigs[1] = IOPContractsManager.OpChainConfig(chainDeployOutput2.systemConfigProxy, absolutePrestate1); return IOPContractsManagerInteropMigrator.MigrateInput({ usePermissionlessGame: true, @@ -1781,12 +1799,12 @@ contract OPContractsManager_Migrate_Test is OPContractsManager_TestInit { // Mock out the owners of the ProxyAdmins to be different. vm.mockCall( - address(input.opChainConfigs[0].proxyAdmin), + address(input.opChainConfigs[0].systemConfigProxy.proxyAdmin()), abi.encodeCall(IProxyAdmin.owner, ()), abi.encode(address(1234)) ); vm.mockCall( - address(input.opChainConfigs[1].proxyAdmin), + address(input.opChainConfigs[1].systemConfigProxy.proxyAdmin()), abi.encodeCall(IProxyAdmin.owner, ()), abi.encode(address(5678)) ); diff --git a/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol index 8bbbd9e8c2cd7..09f93eb57fbce 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol @@ -198,7 +198,6 @@ contract OPContractsManagerStandardValidator_TestInit is CommonTest { function _validate(bool _allowFailure) internal view returns (string memory) { return opcm.validate( IOPContractsManagerStandardValidator.ValidationInput({ - proxyAdmin: proxyAdmin, sysCfg: systemConfig, absolutePrestate: absolutePrestate.raw(), l2ChainID: l2ChainId @@ -220,7 +219,6 @@ contract OPContractsManagerStandardValidator_TestInit is CommonTest { { return opcm.validateWithOverrides( IOPContractsManagerStandardValidator.ValidationInput({ - proxyAdmin: proxyAdmin, sysCfg: systemConfig, absolutePrestate: absolutePrestate.raw(), l2ChainID: l2ChainId @@ -472,22 +470,13 @@ contract OPContractsManagerStandardValidator_SystemConfig_Test is OPContractsMan assertEq("SYSCON-120", _validate(true)); } - /// @notice Tests that the validate function successfully returns the right error when the - /// SystemConfig proxyAdmin is invalid. - function test_validate_systemConfigInvalidProxyAdmin_succeeds() public { - vm.mockCall( - address(systemConfig), abi.encodeCall(IProxyAdminOwnedBase.proxyAdmin, ()), abi.encode(address(0xbad)) - ); - assertEq("SYSCON-130", _validate(true)); - } - /// @notice Tests that the validate function successfully returns the right error when the /// SystemConfig superchainConfig is invalid. function test_validate_systemConfigInvalidSuperchainConfig_succeeds() public { vm.mockCall( address(systemConfig), abi.encodeCall(ISystemConfig.superchainConfig, ()), abi.encode(address(0xbad)) ); - assertEq("SYSCON-140", _validate(true)); + assertEq("SYSCON-130", _validate(true)); } } diff --git a/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol b/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol index d4c7cc4dca6c4..c17b081f4bfa6 100644 --- a/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol +++ b/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol @@ -81,7 +81,6 @@ contract InteropMigrationInput_Test is Test { configs[0] = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(systemConfig1), - proxyAdmin: IProxyAdmin(proxyAdmin1), absolutePrestate: Claim.wrap(bytes32(uint256(1))) }); @@ -93,7 +92,6 @@ contract InteropMigrationInput_Test is Test { configs[1] = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(systemConfig2), - proxyAdmin: IProxyAdmin(proxyAdmin2), absolutePrestate: Claim.wrap(bytes32(uint256(2))) }); @@ -143,7 +141,6 @@ contract InteropMigrationInput_Test is Test { configs[0] = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(mockSystemConfig), - proxyAdmin: IProxyAdmin(mockProxyAdmin), absolutePrestate: Claim.wrap(bytes32(uint256(1))) }); @@ -153,13 +150,11 @@ contract InteropMigrationInput_Test is Test { } contract MockOPCM { - event MigrateCalled(address indexed sysCfgProxy, address indexed proxyAdmin, bytes32 indexed absolutePrestate); + event MigrateCalled(address indexed sysCfgProxy, bytes32 indexed absolutePrestate); function migrate(IOPContractsManagerInteropMigrator.MigrateInput memory _input) public { emit MigrateCalled( - address(_input.opChainConfigs[0].systemConfigProxy), - address(_input.opChainConfigs[0].proxyAdmin), - Claim.unwrap(_input.opChainConfigs[0].absolutePrestate) + address(_input.opChainConfigs[0].systemConfigProxy), Claim.unwrap(_input.opChainConfigs[0].absolutePrestate) ); } } @@ -171,7 +166,7 @@ contract InteropMigration_Test is Test { InteropMigration migration; address prank; - event MigrateCalled(address indexed sysCfgProxy, address indexed proxyAdmin, bytes32 indexed absolutePrestate); + event MigrateCalled(address indexed sysCfgProxy, bytes32 indexed absolutePrestate); function setUp() public { mockOPCM = new MockOPCM(); @@ -179,7 +174,6 @@ contract InteropMigration_Test is Test { input.set(input.opcm.selector, address(mockOPCM)); config = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(makeAddr("systemConfigProxy")), - proxyAdmin: IProxyAdmin(makeAddr("proxyAdmin")), absolutePrestate: Claim.wrap(keccak256("absolutePrestate")) }); IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](1); @@ -205,9 +199,7 @@ contract InteropMigration_Test is Test { function test_migrate_succeeds() public { // MigrateCalled should be emitted by the prank since it's a delegatecall. vm.expectEmit(address(prank)); - emit MigrateCalled( - address(config.systemConfigProxy), address(config.proxyAdmin), Claim.unwrap(config.absolutePrestate) - ); + emit MigrateCalled(address(config.systemConfigProxy), Claim.unwrap(config.absolutePrestate)); // mocks for post-migration checks address portal = makeAddr("optimismPortal"); diff --git a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol index 06e20c078c122..264aecb0058a3 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol @@ -5,7 +5,6 @@ import { Test } from "forge-std/Test.sol"; import { Claim } from "src/dispute/lib/Types.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { UpgradeOPChain, UpgradeOPChainInput } from "scripts/deploy/UpgradeOPChain.s.sol"; @@ -54,7 +53,6 @@ contract UpgradeOPChainInput_Test is Test { configs[0] = OPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(systemConfig1), - proxyAdmin: IProxyAdmin(proxyAdmin1), absolutePrestate: Claim.wrap(bytes32(uint256(1))) }); @@ -66,7 +64,6 @@ contract UpgradeOPChainInput_Test is Test { configs[1] = OPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(systemConfig2), - proxyAdmin: IProxyAdmin(proxyAdmin2), absolutePrestate: Claim.wrap(bytes32(uint256(2))) }); @@ -110,7 +107,6 @@ contract UpgradeOPChainInput_Test is Test { configs[0] = OPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(mockSystemConfig), - proxyAdmin: IProxyAdmin(mockProxyAdmin), absolutePrestate: Claim.wrap(bytes32(uint256(1))) }); @@ -120,13 +116,11 @@ contract UpgradeOPChainInput_Test is Test { } contract MockOPCM { - event UpgradeCalled(address indexed sysCfgProxy, address indexed proxyAdmin, bytes32 indexed absolutePrestate); + event UpgradeCalled(address indexed sysCfgProxy, bytes32 indexed absolutePrestate); function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs) public { emit UpgradeCalled( - address(_opChainConfigs[0].systemConfigProxy), - address(_opChainConfigs[0].proxyAdmin), - Claim.unwrap(_opChainConfigs[0].absolutePrestate) + address(_opChainConfigs[0].systemConfigProxy), Claim.unwrap(_opChainConfigs[0].absolutePrestate) ); } } @@ -138,7 +132,7 @@ contract UpgradeOPChain_Test is Test { UpgradeOPChain upgradeOPChain; address prank; - event UpgradeCalled(address indexed sysCfgProxy, address indexed proxyAdmin, bytes32 indexed absolutePrestate); + event UpgradeCalled(address indexed sysCfgProxy, bytes32 indexed absolutePrestate); function setUp() public virtual { mockOPCM = new MockOPCM(); @@ -146,7 +140,6 @@ contract UpgradeOPChain_Test is Test { uoci.set(uoci.opcm.selector, address(mockOPCM)); config = OPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(makeAddr("systemConfigProxy")), - proxyAdmin: IProxyAdmin(makeAddr("proxyAdmin")), absolutePrestate: Claim.wrap(keccak256("absolutePrestate")) }); OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](1); @@ -160,9 +153,7 @@ contract UpgradeOPChain_Test is Test { function test_upgrade_succeeds() public { // UpgradeCalled should be emitted by the prank since it's a delegate call. vm.expectEmit(address(prank)); - emit UpgradeCalled( - address(config.systemConfigProxy), address(config.proxyAdmin), Claim.unwrap(config.absolutePrestate) - ); + emit UpgradeCalled(address(config.systemConfigProxy), Claim.unwrap(config.absolutePrestate)); upgradeOPChain.run(uoci); } } diff --git a/packages/contracts-bedrock/test/setup/ForkLive.s.sol b/packages/contracts-bedrock/test/setup/ForkLive.s.sol index cb80df50bd08e..9ac9ba9f699dd 100644 --- a/packages/contracts-bedrock/test/setup/ForkLive.s.sol +++ b/packages/contracts-bedrock/test/setup/ForkLive.s.sol @@ -27,7 +27,7 @@ import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; import { IAddressManager } from "interfaces/legacy/IAddressManager.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManager, IOldOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; @@ -200,13 +200,6 @@ contract ForkLive is Deployer, StdAssertions { ISystemConfig systemConfig = ISystemConfig(artifacts.mustGetAddress("SystemConfigProxy")); IProxyAdmin proxyAdmin = IProxyAdmin(EIP1967Helper.getAdmin(address(systemConfig))); - IOPContractsManager.OpChainConfig[] memory opChains = new IOPContractsManager.OpChainConfig[](1); - opChains[0] = IOPContractsManager.OpChainConfig({ - systemConfigProxy: systemConfig, - proxyAdmin: proxyAdmin, - absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) - }); - // Turn the SuperchainPAO into a DelegateCaller so we can try to upgrade the // SuperchainConfig contract. ISuperchainConfig superchainConfig = ISuperchainConfig(artifacts.mustGetAddress("SuperchainConfigProxy")); @@ -240,9 +233,26 @@ contract ForkLive is Deployer, StdAssertions { vm.etch(_delegateCaller, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller")); // Upgrade the chain. - DelegateCaller(_delegateCaller).dcForward( - address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChains)) - ); + if (address(_opcm) == 0x8123739C1368C2DEDc8C564255bc417FEEeBFF9D) { + IOldOPContractsManager.OpChainConfig[] memory opChains = new IOldOPContractsManager.OpChainConfig[](1); + opChains[0] = IOldOPContractsManager.OpChainConfig({ + systemConfigProxy: systemConfig, + proxyAdmin: proxyAdmin, + absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) + }); + DelegateCaller(_delegateCaller).dcForward( + address(_opcm), abi.encodeCall(IOldOPContractsManager.upgrade, (opChains)) + ); + } else { + IOPContractsManager.OpChainConfig[] memory opChains = new IOPContractsManager.OpChainConfig[](1); + opChains[0] = IOPContractsManager.OpChainConfig({ + systemConfigProxy: systemConfig, + absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) + }); + DelegateCaller(_delegateCaller).dcForward( + address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChains)) + ); + } // Reset the upgrader to the original code. vm.etch(_delegateCaller, upgraderCode); From bf34604dee531daacfe2af42abcea64c4ef1d1f8 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 01:27:38 +0100 Subject: [PATCH 02/35] run semver lock for sv --- packages/contracts-bedrock/snapshots/semver-lock.json | 4 ++-- .../src/L1/OPContractsManagerStandardValidator.sol | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index b3087d622d169..43249017dc8f0 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -24,8 +24,8 @@ "sourceCodeHash": "0x219fefb1e4fa08af3216b7808a18606aba925ee2b39b68ccbd590f976527aff5" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { - "initCodeHash": "0xafe49b4d5d481ba0e874f5c81227b610c9c4e365691426354a8dcefdcabba9a3", - "sourceCodeHash": "0xa4efe31937aca12452a4cd1a4bfd660de84eab2ee11e95df38362dad1d6a8d60" + "initCodeHash": "0x23c1f832faf49fe7843330c15c55541c53858cda975fd91e645b7602528a0c56", + "sourceCodeHash": "0xdcdcc5eccba0743f56c46ab93013efc5e223ac03bacaa1d32e6cc19e71107f89" }, "src/L1/OptimismPortal2.sol:OptimismPortal2": { "initCodeHash": "0x5bf576ea7f566e402a997204988471fc9b971410aa9dff8fe810b10baf6b7456", diff --git a/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol b/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol index 5928b32356333..ef05bf29f58e0 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol @@ -38,8 +38,8 @@ import { IProxyAdminOwnedBase } from "interfaces/L1/IProxyAdminOwnedBase.sol"; /// before and after an upgrade. contract OPContractsManagerStandardValidator is ISemver { /// @notice The semantic version of the OPContractsManagerStandardValidator contract. - /// @custom:semver 1.18.0 - string public constant version = "1.18.0"; + /// @custom:semver 1.19.0 + string public constant version = "1.19.0"; /// @notice The SuperchainConfig contract. ISuperchainConfig public superchainConfig; From 9ea47307896395ac96fffab2c6e68d16bd9149d1 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 01:33:43 +0100 Subject: [PATCH 03/35] remove unused imports --- .../scripts/deploy/GenerateOPCMMigrateCalldata.sol | 1 - packages/contracts-bedrock/test/opcm/InteropMigration.t.sol | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/GenerateOPCMMigrateCalldata.sol b/packages/contracts-bedrock/scripts/deploy/GenerateOPCMMigrateCalldata.sol index 9e7ee6e78dbe8..fa1d356ee9f0a 100644 --- a/packages/contracts-bedrock/scripts/deploy/GenerateOPCMMigrateCalldata.sol +++ b/packages/contracts-bedrock/scripts/deploy/GenerateOPCMMigrateCalldata.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; -import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { IOPContractsManagerInteropMigrator, IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { Claim, Duration, Proposal, Hash } from "src/dispute/lib/Types.sol"; diff --git a/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol b/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol index c17b081f4bfa6..64426e41e538e 100644 --- a/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol +++ b/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol @@ -7,7 +7,6 @@ import { InteropMigrationInput, InteropMigration, InteropMigrationOutput } from import { IOPContractsManagerInteropMigrator, IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPortal2.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { Claim } from "src/dispute/lib/Types.sol"; contract InteropMigrationInput_Test is Test { From ba99ad05154c6c80c33c8987e1dd6bc92e886461 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 02:59:02 +0100 Subject: [PATCH 04/35] adapt go code, fix go tests --- op-chain-ops/interopgen/deploy.go | 1 - op-deployer/pkg/deployer/manage/migrate.go | 4 +- .../pkg/deployer/manage/migrate_test.go | 1 - .../scripts/deploy/UpgradeOPChain.s.sol | 38 ++++++++++++++++--- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index 8b52b2f40944c..bfbaeaec61178 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -277,7 +277,6 @@ func MigrateInterop( l2Deployment := l2Deployments[l2ChainID] chainConfigs[i] = manage.OPChainConfig{ SystemConfigProxy: l2Deployment.SystemConfigProxy, - ProxyAdmin: superDeployment.ProxyAdmin, AbsolutePrestate: l2Cfgs[l2ChainID].DisputeAbsolutePrestate, } } diff --git a/op-deployer/pkg/deployer/manage/migrate.go b/op-deployer/pkg/deployer/manage/migrate.go index af6c074478775..3c8b3899c9c70 100644 --- a/op-deployer/pkg/deployer/manage/migrate.go +++ b/op-deployer/pkg/deployer/manage/migrate.go @@ -54,7 +54,6 @@ func (u *InteropMigrationInput) OpChainConfigs() ([]byte, error) { type OPChainConfig struct { SystemConfigProxy common.Address `json:"systemConfigProxy"` - ProxyAdmin common.Address `json:"proxyAdmin"` AbsolutePrestate common.Hash `json:"absolutePrestate"` } @@ -66,7 +65,7 @@ func (output *InteropMigrationOutput) CheckOutput(input common.Address) error { return nil } -var opChainConfigEncoder = w3.MustNewFunc("dummy((address systemConfigProxy,address proxyAdmin,bytes32 absolutePrestate)[])", "") +var opChainConfigEncoder = w3.MustNewFunc("dummy((address systemConfigProxy,bytes32 absolutePrestate)[])", "") type InteropMigration struct { Run func(input common.Address) @@ -112,7 +111,6 @@ func MigrateCLI(cliCtx *cli.Context) error { EncodedChainConfigs: []OPChainConfig{ { SystemConfigProxy: common.HexToAddress(cliCtx.String(SystemConfigProxyFlag.Name)), - ProxyAdmin: common.HexToAddress(cliCtx.String(OPChainProxyAdminFlag.Name)), AbsolutePrestate: common.HexToHash(cliCtx.String(DisputeAbsolutePrestateFlag.Name)), }, }, diff --git a/op-deployer/pkg/deployer/manage/migrate_test.go b/op-deployer/pkg/deployer/manage/migrate_test.go index 9366572bf8d06..f735e3ea34aaf 100644 --- a/op-deployer/pkg/deployer/manage/migrate_test.go +++ b/op-deployer/pkg/deployer/manage/migrate_test.go @@ -64,7 +64,6 @@ func TestInteropMigration(t *testing.T) { EncodedChainConfigs: []OPChainConfig{ { SystemConfigProxy: common.HexToAddress("0x034edD2A225f7f429A63E0f1D2084B9E0A93b538"), - ProxyAdmin: common.HexToAddress("0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc"), AbsolutePrestate: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000abc"), }, }, diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index d238b55edc23c..443ed3dde66ff 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; import { OPContractsManager } from "src/L1/OPContractsManager.sol"; +import { IOldOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; contract UpgradeOPChainInput is BaseDeployIO { @@ -45,23 +46,35 @@ contract UpgradeOPChainInput is BaseDeployIO { contract UpgradeOPChain is Script { function run(UpgradeOPChainInput _uoci) external { OPContractsManager opcm = _uoci.opcm(); - OPContractsManager.OpChainConfig[] memory opChainConfigs = - abi.decode(_uoci.opChainConfigs(), (OPContractsManager.OpChainConfig[])); // Etch DummyCaller contract. This contract is used to mimic the contract that is used // as the source of the delegatecall to the OPCM. In practice this will be the governance // 2/2 or similar. address prank = _uoci.prank(); - bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCaller"); - vm.etch(prank, code); + if (address(opcm) == 0xaf334F4537E87F5155d135392Ff6D52f1866465E) { + bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:OldDummyCaller"); + vm.etch(prank, code); + } else { + bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCaller"); + vm.etch(prank, code); + } vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); vm.label(prank, "DummyCaller"); // Call into the DummyCaller. This will perform the delegatecall under the hood and // return the result. vm.broadcast(msg.sender); - (bool success,) = DummyCaller(prank).upgrade(opChainConfigs); - require(success, "UpgradeChain: upgrade failed"); + if (address(opcm) == 0xaf334F4537E87F5155d135392Ff6D52f1866465E) { + IOldOPContractsManager.OpChainConfig[] memory opChainConfigs = + abi.decode(_uoci.opChainConfigs(), (IOldOPContractsManager.OpChainConfig[])); + (bool success,) = OldDummyCaller(prank).upgrade(opChainConfigs); + require(success, "UpgradeOPChain: upgrade failed"); + } else { + OPContractsManager.OpChainConfig[] memory opChainConfigs = + abi.decode(_uoci.opChainConfigs(), (OPContractsManager.OpChainConfig[])); + (bool success,) = DummyCaller(prank).upgrade(opChainConfigs); + require(success, "UpgradeOPChain: upgrade failed"); + } } } @@ -74,3 +87,16 @@ contract DummyCaller { return (success, result); } } + +contract OldDummyCaller { + address internal _opcmAddr; + + function upgrade(IOldOPContractsManager.OpChainConfig[] memory _opChainConfigs) + external + returns (bool, bytes memory) + { + bytes memory data = abi.encodeCall(OldDummyCaller.upgrade, _opChainConfigs); + (bool success, bytes memory result) = _opcmAddr.delegatecall(data); + return (success, result); + } +} From 9dddb73a5754f8019ec051983153609ef713cfab Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 03:09:17 +0100 Subject: [PATCH 05/35] fix UpgradeOPChain test --- .../contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index 443ed3dde66ff..3d135eb002ff1 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -63,15 +63,18 @@ contract UpgradeOPChain is Script { // Call into the DummyCaller. This will perform the delegatecall under the hood and // return the result. - vm.broadcast(msg.sender); if (address(opcm) == 0xaf334F4537E87F5155d135392Ff6D52f1866465E) { IOldOPContractsManager.OpChainConfig[] memory opChainConfigs = abi.decode(_uoci.opChainConfigs(), (IOldOPContractsManager.OpChainConfig[])); + + vm.broadcast(msg.sender); (bool success,) = OldDummyCaller(prank).upgrade(opChainConfigs); require(success, "UpgradeOPChain: upgrade failed"); } else { OPContractsManager.OpChainConfig[] memory opChainConfigs = abi.decode(_uoci.opChainConfigs(), (OPContractsManager.OpChainConfig[])); + + vm.broadcast(msg.sender); (bool success,) = DummyCaller(prank).upgrade(opChainConfigs); require(success, "UpgradeOPChain: upgrade failed"); } From c2c571168cc8ca3fe96550002bbed0db54d0c603 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 05:29:25 +0100 Subject: [PATCH 06/35] fix addGameType go test --- .../interfaces/L1/IOPContractsManager.sol | 23 +++++ .../scripts/deploy/AddGameType.s.sol | 87 ++++++++++++++----- 2 files changed, 89 insertions(+), 21 deletions(-) diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol index a128272cc3b41..3ce5e7be5626a 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol @@ -390,11 +390,34 @@ interface IOPContractsManager { } interface IOldOPContractsManager { + struct AddGameInput { + string saltMixer; + ISystemConfig systemConfig; + IProxyAdmin proxyAdmin; + IDelayedWETH delayedWETH; + GameType disputeGameType; + Claim disputeAbsolutePrestate; + uint256 disputeMaxGameDepth; + uint256 disputeSplitDepth; + Duration disputeClockExtension; + Duration disputeMaxClockDuration; + uint256 initialBond; + IBigStepper vm; + bool permissioned; + } + + struct AddGameOutput { + IDelayedWETH delayedWETH; + IFaultDisputeGame faultDisputeGame; + } + struct OpChainConfig { ISystemConfig systemConfigProxy; IProxyAdmin proxyAdmin; Claim absolutePrestate; } + function addGameType(AddGameInput[] memory _gameConfigs) external returns (AddGameOutput[] memory); + function upgrade(OpChainConfig[] memory _opChainConfigs) external; } diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index e69dfd019c3c2..94c5cc50b580f 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -9,6 +9,7 @@ import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; // Interfaces import { OPContractsManager } from "src/L1/OPContractsManager.sol"; +import { IOldOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; @@ -57,34 +58,65 @@ contract AddGameType is Script { } function run(Input memory _agi) public returns (Output memory) { - // Create the game input - OPContractsManager.AddGameInput[] memory gameConfigs = new OPContractsManager.AddGameInput[](1); - gameConfigs[0] = OPContractsManager.AddGameInput({ - saltMixer: _agi.saltMixer, - systemConfig: _agi.systemConfigProxy, - delayedWETH: _agi.delayedWETHProxy, - disputeGameType: _agi.disputeGameType, - disputeAbsolutePrestate: _agi.disputeAbsolutePrestate, - disputeMaxGameDepth: _agi.disputeMaxGameDepth, - disputeSplitDepth: _agi.disputeSplitDepth, - disputeClockExtension: _agi.disputeClockExtension, - disputeMaxClockDuration: _agi.disputeMaxClockDuration, - initialBond: _agi.initialBond, - vm: _agi.vm, - permissioned: _agi.permissioned - }); - // Etch DummyCaller contract address prank = _agi.prank; - bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCaller"); - vm.etch(prank, code); + + if (address(_agi.opcmImpl) == 0x1B25F566336F47BC5E0036D66E142237DcF4640b) { + bytes memory code = vm.getDeployedCode("AddGameType.s.sol:OldDummyCaller"); + vm.etch(prank, code); + } else { + bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCaller"); + vm.etch(prank, code); + } vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcmImpl))))); vm.label(prank, "DummyCaller"); // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); - (bool success, bytes memory result) = DummyCaller(prank).addGameType(gameConfigs); - require(success, "AddGameType: addGameType failed"); + bytes memory result; + bool success; + if (address(_agi.opcmImpl) == 0x1B25F566336F47BC5E0036D66E142237DcF4640b) { + // Create the game input + IOldOPContractsManager.AddGameInput[] memory gameConfigs = new IOldOPContractsManager.AddGameInput[](1); + gameConfigs[0] = IOldOPContractsManager.AddGameInput({ + saltMixer: _agi.saltMixer, + systemConfig: _agi.systemConfigProxy, + proxyAdmin: _agi.opChainProxyAdmin, + delayedWETH: _agi.delayedWETHProxy, + disputeGameType: _agi.disputeGameType, + disputeAbsolutePrestate: _agi.disputeAbsolutePrestate, + disputeMaxGameDepth: _agi.disputeMaxGameDepth, + disputeSplitDepth: _agi.disputeSplitDepth, + disputeClockExtension: _agi.disputeClockExtension, + disputeMaxClockDuration: _agi.disputeMaxClockDuration, + initialBond: _agi.initialBond, + vm: _agi.vm, + permissioned: _agi.permissioned + }); + + (success, result) = OldDummyCaller(prank).addGameType(gameConfigs); + require(success, "AddGameType: addGameType failed"); + } else { + // Create the game input + OPContractsManager.AddGameInput[] memory gameConfigs = new OPContractsManager.AddGameInput[](1); + gameConfigs[0] = OPContractsManager.AddGameInput({ + saltMixer: _agi.saltMixer, + systemConfig: _agi.systemConfigProxy, + delayedWETH: _agi.delayedWETHProxy, + disputeGameType: _agi.disputeGameType, + disputeAbsolutePrestate: _agi.disputeAbsolutePrestate, + disputeMaxGameDepth: _agi.disputeMaxGameDepth, + disputeSplitDepth: _agi.disputeSplitDepth, + disputeClockExtension: _agi.disputeClockExtension, + disputeMaxClockDuration: _agi.disputeMaxClockDuration, + initialBond: _agi.initialBond, + vm: _agi.vm, + permissioned: _agi.permissioned + }); + + (success, result) = DummyCaller(prank).addGameType(gameConfigs); + require(success, "AddGameType: addGameType failed"); + } // Decode the result and set it in the output OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); @@ -99,6 +131,19 @@ contract AddGameType is Script { } /// @title DummyCaller +contract OldDummyCaller { + address internal _opcmAddr; + + function addGameType(IOldOPContractsManager.AddGameInput[] memory _gameConfigs) + external + returns (bool, bytes memory) + { + bytes memory data = abi.encodeCall(OldDummyCaller.addGameType, _gameConfigs); + (bool success, bytes memory result) = _opcmAddr.delegatecall(data); + return (success, result); + } +} + contract DummyCaller { address internal _opcmAddr; From 7a4e2675674b89e111af09c972898232306dc523 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 05:53:33 +0100 Subject: [PATCH 07/35] use semverComp to make interface usage checks flexible --- .../scripts/deploy/AddGameType.s.sol | 50 +++++++++++-------- .../scripts/deploy/UpgradeOPChain.s.sol | 25 ++++++---- .../test/L1/OPContractsManager.t.sol | 5 +- .../test/setup/ForkLive.s.sol | 3 +- 4 files changed, 51 insertions(+), 32 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index 94c5cc50b580f..d433df65b9daa 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -6,6 +6,7 @@ import { Script } from "forge-std/Script.sol"; // Scripts import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; +import { SemverComp } from "src/libraries/SemverComp.sol"; // Interfaces import { OPContractsManager } from "src/L1/OPContractsManager.sol"; @@ -61,21 +62,12 @@ contract AddGameType is Script { // Etch DummyCaller contract address prank = _agi.prank; - if (address(_agi.opcmImpl) == 0x1B25F566336F47BC5E0036D66E142237DcF4640b) { + if (SemverComp.lt(_agi.opcmImpl.version(), "4.1.0")) { bytes memory code = vm.getDeployedCode("AddGameType.s.sol:OldDummyCaller"); vm.etch(prank, code); - } else { - bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCaller"); - vm.etch(prank, code); - } - vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcmImpl))))); - vm.label(prank, "DummyCaller"); - - // Call into the DummyCaller to perform the delegatecall - vm.broadcast(msg.sender); - bytes memory result; - bool success; - if (address(_agi.opcmImpl) == 0x1B25F566336F47BC5E0036D66E142237DcF4640b) { + vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcmImpl))))); + vm.label(prank, "DummyCaller"); + // Create the game input IOldOPContractsManager.AddGameInput[] memory gameConfigs = new IOldOPContractsManager.AddGameInput[](1); gameConfigs[0] = IOldOPContractsManager.AddGameInput({ @@ -94,9 +86,23 @@ contract AddGameType is Script { permissioned: _agi.permissioned }); - (success, result) = OldDummyCaller(prank).addGameType(gameConfigs); + // Call into the DummyCaller to perform the delegatecall + vm.broadcast(msg.sender); + + (bool success, bytes memory result) = OldDummyCaller(prank).addGameType(gameConfigs); require(success, "AddGameType: addGameType failed"); + + // Decode the result and set it in the output + OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); + require(outputs.length == 1, "AddGameType: unexpected number of outputs"); + return + Output({ delayedWETHProxy: outputs[0].delayedWETH, faultDisputeGameProxy: outputs[0].faultDisputeGame }); } else { + bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCaller"); + vm.etch(prank, code); + vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcmImpl))))); + vm.label(prank, "DummyCaller"); + // Create the game input OPContractsManager.AddGameInput[] memory gameConfigs = new OPContractsManager.AddGameInput[](1); gameConfigs[0] = OPContractsManager.AddGameInput({ @@ -114,14 +120,18 @@ contract AddGameType is Script { permissioned: _agi.permissioned }); - (success, result) = DummyCaller(prank).addGameType(gameConfigs); + // Call into the DummyCaller to perform the delegatecall + vm.broadcast(msg.sender); + + (bool success, bytes memory result) = DummyCaller(prank).addGameType(gameConfigs); require(success, "AddGameType: addGameType failed"); - } - // Decode the result and set it in the output - OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); - require(outputs.length == 1, "AddGameType: unexpected number of outputs"); - return Output({ delayedWETHProxy: outputs[0].delayedWETH, faultDisputeGameProxy: outputs[0].faultDisputeGame }); + // Decode the result and set it in the output + OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); + require(outputs.length == 1, "AddGameType: unexpected number of outputs"); + return + Output({ delayedWETHProxy: outputs[0].delayedWETH, faultDisputeGameProxy: outputs[0].faultDisputeGame }); + } } function checkOutput(Output memory _ago) internal view { diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index 3d135eb002ff1..92200faa9b6b2 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -5,6 +5,7 @@ import { Script } from "forge-std/Script.sol"; import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { IOldOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; +import { SemverComp } from "src/libraries/SemverComp.sol"; contract UpgradeOPChainInput is BaseDeployIO { address internal _prank; @@ -51,30 +52,34 @@ contract UpgradeOPChain is Script { // as the source of the delegatecall to the OPCM. In practice this will be the governance // 2/2 or similar. address prank = _uoci.prank(); - if (address(opcm) == 0xaf334F4537E87F5155d135392Ff6D52f1866465E) { + if (SemverComp.lt(opcm.version(), "4.1.0")) { bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:OldDummyCaller"); vm.etch(prank, code); - } else { - bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCaller"); - vm.etch(prank, code); - } - vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); - vm.label(prank, "DummyCaller"); - // Call into the DummyCaller. This will perform the delegatecall under the hood and - // return the result. - if (address(opcm) == 0xaf334F4537E87F5155d135392Ff6D52f1866465E) { + vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); + vm.label(prank, "DummyCaller"); + IOldOPContractsManager.OpChainConfig[] memory opChainConfigs = abi.decode(_uoci.opChainConfigs(), (IOldOPContractsManager.OpChainConfig[])); + // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); + (bool success,) = OldDummyCaller(prank).upgrade(opChainConfigs); require(success, "UpgradeOPChain: upgrade failed"); } else { + bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCaller"); + vm.etch(prank, code); + + vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); + vm.label(prank, "DummyCaller"); + OPContractsManager.OpChainConfig[] memory opChainConfigs = abi.decode(_uoci.opChainConfigs(), (OPContractsManager.OpChainConfig[])); + // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); + (bool success,) = DummyCaller(prank).upgrade(opChainConfigs); require(success, "UpgradeOPChain: upgrade failed"); } diff --git a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol index 239f589a12783..745a0ac25b76a 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol @@ -21,6 +21,7 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { GameType, Duration, Hash, Claim } from "src/dispute/lib/LibUDT.sol"; import { Proposal, GameTypes } from "src/dispute/lib/Types.sol"; import { DevFeatures } from "src/libraries/DevFeatures.sol"; +import { SemverComp } from "src/libraries/SemverComp.sol"; // Interfaces import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; @@ -211,13 +212,15 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { bytes memory delegateCallerCode = address(_delegateCaller).code; vm.etch(_delegateCaller, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller")); + string memory OPCM_VERSION = _opcm.version(); + // Expect the revert if one is specified. if (_revertBytes.length > 0) { vm.expectRevert(_revertBytes); } // Execute the chain upgrade. - if (address(_opcm) == 0x8123739C1368C2DEDc8C564255bc417FEEeBFF9D) { + if (SemverComp.lt(OPCM_VERSION, "4.1.0")) { IOldOPContractsManager.OpChainConfig[] memory opChains = new IOldOPContractsManager.OpChainConfig[](1); opChains[0] = IOldOPContractsManager.OpChainConfig({ systemConfigProxy: systemConfig, diff --git a/packages/contracts-bedrock/test/setup/ForkLive.s.sol b/packages/contracts-bedrock/test/setup/ForkLive.s.sol index 9ac9ba9f699dd..f606aa54eb67a 100644 --- a/packages/contracts-bedrock/test/setup/ForkLive.s.sol +++ b/packages/contracts-bedrock/test/setup/ForkLive.s.sol @@ -17,6 +17,7 @@ import { Config } from "scripts/libraries/Config.sol"; import { GameTypes, Claim } from "src/dispute/lib/Types.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { LibString } from "@solady/utils/LibString.sol"; +import { SemverComp } from "src/libraries/SemverComp.sol"; // Interfaces import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; @@ -233,7 +234,7 @@ contract ForkLive is Deployer, StdAssertions { vm.etch(_delegateCaller, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller")); // Upgrade the chain. - if (address(_opcm) == 0x8123739C1368C2DEDc8C564255bc417FEEeBFF9D) { + if (SemverComp.lt(_opcm.version(), "4.1.0")) { IOldOPContractsManager.OpChainConfig[] memory opChains = new IOldOPContractsManager.OpChainConfig[](1); opChains[0] = IOldOPContractsManager.OpChainConfig({ systemConfigProxy: systemConfig, From 3141f4dc95e1641cadcc491259c44226c8a031ab Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 06:02:25 +0100 Subject: [PATCH 08/35] fix failing ci --- packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol index 264aecb0058a3..dce5d4446ef5e 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol @@ -123,6 +123,10 @@ contract MockOPCM { address(_opChainConfigs[0].systemConfigProxy), Claim.unwrap(_opChainConfigs[0].absolutePrestate) ); } + + function version() public pure returns (string memory) { + return "4.1.0"; + } } contract UpgradeOPChain_Test is Test { From 658a2aa0059c5a9b3731e12e75bdaf0cad272a77 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 14:14:22 +0100 Subject: [PATCH 09/35] use better naming for old opcm interfaces and related contracts --- .../interfaces/L1/IOPContractsManager.sol | 2 +- .../IOPContractsManagerStandardValidator.sol | 2 +- .../scripts/deploy/AddGameType.s.sol | 24 ++++++++++++------- .../scripts/deploy/UpgradeOPChain.s.sol | 23 ++++++++++++------ .../test/L1/OPContractsManager.t.sol | 23 +++++++++++------- .../test/setup/ForkLive.s.sol | 11 +++++---- 6 files changed, 56 insertions(+), 29 deletions(-) diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol index 3ce5e7be5626a..607602a0574d3 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol @@ -389,7 +389,7 @@ interface IOPContractsManager { function implementations() external view returns (Implementations memory); } -interface IOldOPContractsManager { +interface IOPContractsManagerPre4_1_0 { struct AddGameInput { string saltMixer; ISystemConfig systemConfig; diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol index 95a3448cbdaae..e4ea81632c38e 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol @@ -75,7 +75,7 @@ interface IOPContractsManagerStandardValidator { external; } -interface IOldOPContractsManagerStandardValidator { +interface IOPContractsManagerStandardValidatorPreOPCM4_1_0 { struct ValidationInput { IProxyAdmin proxyAdmin; ISystemConfig sysCfg; diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index d433df65b9daa..0c8c6ee3e9d1d 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -10,7 +10,7 @@ import { SemverComp } from "src/libraries/SemverComp.sol"; // Interfaces import { OPContractsManager } from "src/L1/OPContractsManager.sol"; -import { IOldOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; @@ -62,6 +62,8 @@ contract AddGameType is Script { // Etch DummyCaller contract address prank = _agi.prank; + // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for + // both interface variants. if (SemverComp.lt(_agi.opcmImpl.version(), "4.1.0")) { bytes memory code = vm.getDeployedCode("AddGameType.s.sol:OldDummyCaller"); vm.etch(prank, code); @@ -69,8 +71,9 @@ contract AddGameType is Script { vm.label(prank, "DummyCaller"); // Create the game input - IOldOPContractsManager.AddGameInput[] memory gameConfigs = new IOldOPContractsManager.AddGameInput[](1); - gameConfigs[0] = IOldOPContractsManager.AddGameInput({ + IOPContractsManagerPre4_1_0.AddGameInput[] memory gameConfigs = + new IOPContractsManagerPre4_1_0.AddGameInput[](1); + gameConfigs[0] = IOPContractsManagerPre4_1_0.AddGameInput({ saltMixer: _agi.saltMixer, systemConfig: _agi.systemConfigProxy, proxyAdmin: _agi.opChainProxyAdmin, @@ -89,7 +92,7 @@ contract AddGameType is Script { // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); - (bool success, bytes memory result) = OldDummyCaller(prank).addGameType(gameConfigs); + (bool success, bytes memory result) = DummyCallerPreOPCM4_1_0(prank).addGameType(gameConfigs); require(success, "AddGameType: addGameType failed"); // Decode the result and set it in the output @@ -140,20 +143,25 @@ contract AddGameType is Script { } } -/// @title DummyCaller -contract OldDummyCaller { +/// @title DummyCallerPreOPCM4_1_0 +/// @notice This contract is used to mimic the contract that is used as the source of the delegatecall to the OPCM. +/// @dev This contract is used for OPCM versions 4.1.0 and below. +contract DummyCallerPreOPCM4_1_0 { address internal _opcmAddr; - function addGameType(IOldOPContractsManager.AddGameInput[] memory _gameConfigs) + function addGameType(IOPContractsManagerPre4_1_0.AddGameInput[] memory _gameConfigs) external returns (bool, bytes memory) { - bytes memory data = abi.encodeCall(OldDummyCaller.addGameType, _gameConfigs); + bytes memory data = abi.encodeCall(DummyCallerPreOPCM4_1_0.addGameType, _gameConfigs); (bool success, bytes memory result) = _opcmAddr.delegatecall(data); return (success, result); } } +/// @title DummyCaller +/// @notice This contract is used to mimic the contract that is used as the source of the delegatecall to the OPCM. +/// @dev This contract is used for OPCM versions 4.1.0 and above. contract DummyCaller { address internal _opcmAddr; diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index 92200faa9b6b2..e503f00d20e3e 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; import { OPContractsManager } from "src/L1/OPContractsManager.sol"; -import { IOldOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; import { SemverComp } from "src/libraries/SemverComp.sol"; @@ -52,6 +52,9 @@ contract UpgradeOPChain is Script { // as the source of the delegatecall to the OPCM. In practice this will be the governance // 2/2 or similar. address prank = _uoci.prank(); + + // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for + // both interface variants. if (SemverComp.lt(opcm.version(), "4.1.0")) { bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:OldDummyCaller"); vm.etch(prank, code); @@ -59,13 +62,13 @@ contract UpgradeOPChain is Script { vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); vm.label(prank, "DummyCaller"); - IOldOPContractsManager.OpChainConfig[] memory opChainConfigs = - abi.decode(_uoci.opChainConfigs(), (IOldOPContractsManager.OpChainConfig[])); + IOPContractsManagerPre4_1_0.OpChainConfig[] memory opChainConfigs = + abi.decode(_uoci.opChainConfigs(), (IOPContractsManagerPre4_1_0.OpChainConfig[])); // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); - (bool success,) = OldDummyCaller(prank).upgrade(opChainConfigs); + (bool success,) = DummyCallerPreOPCM4_1_0(prank).upgrade(opChainConfigs); require(success, "UpgradeOPChain: upgrade failed"); } else { bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCaller"); @@ -86,6 +89,9 @@ contract UpgradeOPChain is Script { } } +/// @title DummyCaller +/// @notice This contract is used to mimic the contract that is used as the source of the delegatecall to the OPCM. +/// @dev This contract is used for OPCM versions 4.1.0 and above. contract DummyCaller { address internal _opcmAddr; @@ -96,14 +102,17 @@ contract DummyCaller { } } -contract OldDummyCaller { +/// @title DummyCallerPreOPCM4_1_0 +/// @notice This contract is used to mimic the contract that is used as the source of the delegatecall to the OPCM. +/// @dev This contract is used for OPCM versions 4.1.0 and below. +contract DummyCallerPreOPCM4_1_0 { address internal _opcmAddr; - function upgrade(IOldOPContractsManager.OpChainConfig[] memory _opChainConfigs) + function upgrade(IOPContractsManagerPre4_1_0.OpChainConfig[] memory _opChainConfigs) external returns (bool, bytes memory) { - bytes memory data = abi.encodeCall(OldDummyCaller.upgrade, _opChainConfigs); + bytes memory data = abi.encodeCall(DummyCallerPreOPCM4_1_0.upgrade, _opChainConfigs); (bool success, bytes memory result) = _opcmAddr.delegatecall(data); return (success, result); } diff --git a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol index 745a0ac25b76a..7e1f06fe5c68c 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol @@ -40,11 +40,11 @@ import { IOPContractsManagerGameTypeAdder, IOPContractsManagerInteropMigrator, IOPContractsManagerUpgrader, - IOldOPContractsManager + IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerStandardValidator, - IOldOPContractsManagerStandardValidator + IOPContractsManagerStandardValidatorPreOPCM4_1_0 } from "interfaces/L1/IOPContractsManagerStandardValidator.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; @@ -220,15 +220,18 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { } // Execute the chain upgrade. + // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for + // both interface variants. if (SemverComp.lt(OPCM_VERSION, "4.1.0")) { - IOldOPContractsManager.OpChainConfig[] memory opChains = new IOldOPContractsManager.OpChainConfig[](1); - opChains[0] = IOldOPContractsManager.OpChainConfig({ + IOPContractsManagerPre4_1_0.OpChainConfig[] memory opChains = + new IOPContractsManagerPre4_1_0.OpChainConfig[](1); + opChains[0] = IOPContractsManagerPre4_1_0.OpChainConfig({ systemConfigProxy: systemConfig, proxyAdmin: proxyAdmin, absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) }); DelegateCaller(_delegateCaller).dcForward( - address(_opcm), abi.encodeCall(IOldOPContractsManager.upgrade, (opChains)) + address(_opcm), abi.encodeCall(IOPContractsManagerPre4_1_0.upgrade, (opChains)) ); } else { DelegateCaller(_delegateCaller).dcForward( @@ -266,6 +269,8 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { // try to apply to this function call instead. IOPContractsManagerStandardValidator validator = _opcm.opcmStandardValidator(); + string memory SV_VERSION = validator.version(); + // If the absolute prestate is zero, we will always get a PDDG-40,PLDG-40 error here in the // standard validator. This happens because an absolute prestate of zero means that the // user is requesting to use the existing prestate. We could avoid the error by grabbing @@ -276,9 +281,11 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { } // Run the StandardValidator checks. - if (address(validator) == 0x845FEF377Fa9C678B3eBe33B024678538f1215dD) { - IOldOPContractsManagerStandardValidator(address(validator)).validate( - IOldOPContractsManagerStandardValidator.ValidationInput({ + // From StandardValidator version 1.19.0, the proxyAdmin was removed from the ValidationInput struct so we do + // create support for both variants. + if (SemverComp.lt(SV_VERSION, "1.19.0")) { + IOPContractsManagerStandardValidatorPreOPCM4_1_0(address(validator)).validate( + IOPContractsManagerStandardValidatorPreOPCM4_1_0.ValidationInput({ proxyAdmin: opChainConfigs[0].systemConfigProxy.proxyAdmin(), sysCfg: opChainConfigs[0].systemConfigProxy, absolutePrestate: opChainConfigs[0].absolutePrestate.raw(), diff --git a/packages/contracts-bedrock/test/setup/ForkLive.s.sol b/packages/contracts-bedrock/test/setup/ForkLive.s.sol index f606aa54eb67a..3378322212f16 100644 --- a/packages/contracts-bedrock/test/setup/ForkLive.s.sol +++ b/packages/contracts-bedrock/test/setup/ForkLive.s.sol @@ -28,7 +28,7 @@ import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; import { IAddressManager } from "interfaces/legacy/IAddressManager.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { IOPContractsManager, IOldOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManager, IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; @@ -234,15 +234,18 @@ contract ForkLive is Deployer, StdAssertions { vm.etch(_delegateCaller, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller")); // Upgrade the chain. + // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for + // both interface variants. if (SemverComp.lt(_opcm.version(), "4.1.0")) { - IOldOPContractsManager.OpChainConfig[] memory opChains = new IOldOPContractsManager.OpChainConfig[](1); - opChains[0] = IOldOPContractsManager.OpChainConfig({ + IOPContractsManagerPre4_1_0.OpChainConfig[] memory opChains = + new IOPContractsManagerPre4_1_0.OpChainConfig[](1); + opChains[0] = IOPContractsManagerPre4_1_0.OpChainConfig({ systemConfigProxy: systemConfig, proxyAdmin: proxyAdmin, absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) }); DelegateCaller(_delegateCaller).dcForward( - address(_opcm), abi.encodeCall(IOldOPContractsManager.upgrade, (opChains)) + address(_opcm), abi.encodeCall(IOPContractsManagerPre4_1_0.upgrade, (opChains)) ); } else { IOPContractsManager.OpChainConfig[] memory opChains = new IOPContractsManager.OpChainConfig[](1); From 2e49eb6d09562a9ced3faf43ea1b7a043f9423a6 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 14:23:53 +0100 Subject: [PATCH 10/35] fix go tests --- packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol | 2 +- packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index 0c8c6ee3e9d1d..c658efab6a726 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -65,7 +65,7 @@ contract AddGameType is Script { // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for // both interface variants. if (SemverComp.lt(_agi.opcmImpl.version(), "4.1.0")) { - bytes memory code = vm.getDeployedCode("AddGameType.s.sol:OldDummyCaller"); + bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCallerPreOPCM4_1_0"); vm.etch(prank, code); vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcmImpl))))); vm.label(prank, "DummyCaller"); diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index e503f00d20e3e..42e52c7382c24 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -56,7 +56,7 @@ contract UpgradeOPChain is Script { // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for // both interface variants. if (SemverComp.lt(opcm.version(), "4.1.0")) { - bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:OldDummyCaller"); + bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCallerPreOPCM4_1_0"); vm.etch(prank, code); vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); From 2754bd0d3b27dd8f95ab3b6fa1d787a557f19f00 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 18:25:33 +0100 Subject: [PATCH 11/35] try fix op-acceptance tests --- op-devstack/sysgo/superroot.go | 1 - op-e2e/bindings/opcontractsmanager.go | 117 ++++++++++++++++---------- 2 files changed, 71 insertions(+), 47 deletions(-) diff --git a/op-devstack/sysgo/superroot.go b/op-devstack/sysgo/superroot.go index f487acf9321b4..d5c989cc52859 100644 --- a/op-devstack/sysgo/superroot.go +++ b/op-devstack/sysgo/superroot.go @@ -69,7 +69,6 @@ func WithSuperRoots(l1ChainID eth.ChainID, l1ELID stack.L1ELNodeID, l2CLID stack l2ChainIDs = append(l2ChainIDs, l2ChainID) opChainConfigs = append(opChainConfigs, bindings.OPContractsManagerOpChainConfig{ SystemConfigProxy: l2Deployment.SystemConfigProxyAddr(), - ProxyAdmin: superchainProxyAdmin, AbsolutePrestate: absolutePrestate, }) } diff --git a/op-e2e/bindings/opcontractsmanager.go b/op-e2e/bindings/opcontractsmanager.go index 26dea347ff642..c65d6dd091c3c 100644 --- a/op-e2e/bindings/opcontractsmanager.go +++ b/op-e2e/bindings/opcontractsmanager.go @@ -33,7 +33,6 @@ var ( type OPContractsManagerAddGameInput struct { SaltMixer string SystemConfig common.Address - ProxyAdmin common.Address DelayedWETH common.Address DisputeGameType uint32 DisputeAbsolutePrestate [32]byte @@ -145,7 +144,6 @@ type OPContractsManagerInteropMigratorMigrateInput struct { // OPContractsManagerOpChainConfig is an auto generated low-level Go binding around an user-defined struct. type OPContractsManagerOpChainConfig struct { SystemConfigProxy common.Address - ProxyAdmin common.Address AbsolutePrestate [32]byte } @@ -161,7 +159,6 @@ type OPContractsManagerRoles struct { // OPContractsManagerStandardValidatorValidationInput is an auto generated low-level Go binding around an user-defined struct. type OPContractsManagerStandardValidatorValidationInput struct { - ProxyAdmin common.Address SysCfg common.Address AbsolutePrestate [32]byte L2ChainID *big.Int @@ -173,6 +170,13 @@ type OPContractsManagerStandardValidatorValidationOverrides struct { Challenger common.Address } +// OPContractsManagerUpdatePrestateInput is an auto generated low-level Go binding around an user-defined struct. +type OPContractsManagerUpdatePrestateInput struct { + SystemConfigProxy common.Address + CannonPrestate [32]byte + CannonKonaPrestate [32]byte +} + // Proposal is an auto generated low-level Go binding around an user-defined struct. type Proposal struct { Root [32]byte @@ -181,8 +185,8 @@ type Proposal struct { // OPContractsManagerMetaData contains all meta data concerning the OPContractsManager contract. var OPContractsManagerMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_opcmGameTypeAdder\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerGameTypeAdder\"},{\"name\":\"_opcmDeployer\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerDeployer\"},{\"name\":\"_opcmUpgrader\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerUpgrader\"},{\"name\":\"_opcmInteropMigrator\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerInteropMigrator\"},{\"name\":\"_opcmStandardValidator\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerStandardValidator\"},{\"name\":\"_superchainConfig\",\"type\":\"address\",\"internalType\":\"contractISuperchainConfig\"},{\"name\":\"_protocolVersions\",\"type\":\"address\",\"internalType\":\"contractIProtocolVersions\"},{\"name\":\"_superchainProxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addGameType\",\"inputs\":[{\"name\":\"_gameConfigs\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.AddGameInput[]\",\"components\":[{\"name\":\"saltMixer\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"systemConfig\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"proxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"},{\"name\":\"delayedWETH\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"},{\"name\":\"disputeGameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"disputeAbsolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"disputeMaxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"disputeSplitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"disputeClockExtension\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"disputeMaxClockDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"initialBond\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"vm\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"},{\"name\":\"permissioned\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.AddGameOutput[]\",\"components\":[{\"name\":\"delayedWETH\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"},{\"name\":\"faultDisputeGame\",\"type\":\"address\",\"internalType\":\"contractIFaultDisputeGame\"}]}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"blueprints\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.Blueprints\",\"components\":[{\"name\":\"addressManager\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"proxy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"proxyAdmin\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1ChugSplashProxy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"resolvedDelegateProxy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"permissionedDisputeGame1\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"permissionedDisputeGame2\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"permissionlessDisputeGame1\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"permissionlessDisputeGame2\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superPermissionedDisputeGame1\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superPermissionedDisputeGame2\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superPermissionlessDisputeGame1\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superPermissionlessDisputeGame2\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"chainIdToBatchInboxAddress\",\"inputs\":[{\"name\":\"_l2ChainId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deploy\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.DeployInput\",\"components\":[{\"name\":\"roles\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.Roles\",\"components\":[{\"name\":\"opChainProxyAdminOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"systemConfigOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"batcher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"unsafeBlockSigner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"challenger\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"basefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"blobBasefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"l2ChainId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startingAnchorRoot\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"saltMixer\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"disputeGameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"disputeAbsolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"disputeMaxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"disputeSplitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"disputeClockExtension\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"disputeMaxClockDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.DeployOutput\",\"components\":[{\"name\":\"opChainProxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"},{\"name\":\"addressManager\",\"type\":\"address\",\"internalType\":\"contractIAddressManager\"},{\"name\":\"l1ERC721BridgeProxy\",\"type\":\"address\",\"internalType\":\"contractIL1ERC721Bridge\"},{\"name\":\"systemConfigProxy\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"optimismMintableERC20FactoryProxy\",\"type\":\"address\",\"internalType\":\"contractIOptimismMintableERC20Factory\"},{\"name\":\"l1StandardBridgeProxy\",\"type\":\"address\",\"internalType\":\"contractIL1StandardBridge\"},{\"name\":\"l1CrossDomainMessengerProxy\",\"type\":\"address\",\"internalType\":\"contractIL1CrossDomainMessenger\"},{\"name\":\"ethLockboxProxy\",\"type\":\"address\",\"internalType\":\"contractIETHLockbox\"},{\"name\":\"optimismPortalProxy\",\"type\":\"address\",\"internalType\":\"contractIOptimismPortal2\"},{\"name\":\"disputeGameFactoryProxy\",\"type\":\"address\",\"internalType\":\"contractIDisputeGameFactory\"},{\"name\":\"anchorStateRegistryProxy\",\"type\":\"address\",\"internalType\":\"contractIAnchorStateRegistry\"},{\"name\":\"faultDisputeGame\",\"type\":\"address\",\"internalType\":\"contractIFaultDisputeGame\"},{\"name\":\"permissionedDisputeGame\",\"type\":\"address\",\"internalType\":\"contractIPermissionedDisputeGame\"},{\"name\":\"delayedWETHPermissionedGameProxy\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"},{\"name\":\"delayedWETHPermissionlessGameProxy\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"}]}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"devFeatureBitmap\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"implementations\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.Implementations\",\"components\":[{\"name\":\"superchainConfigImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"protocolVersionsImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1ERC721BridgeImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismPortalImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismPortalInteropImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"ethLockboxImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"systemConfigImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismMintableERC20FactoryImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1CrossDomainMessengerImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1StandardBridgeImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"disputeGameFactoryImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"anchorStateRegistryImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delayedWETHImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"mipsImpl\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isDevFeatureEnabled\",\"inputs\":[{\"name\":\"_feature\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrate\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerInteropMigrator.MigrateInput\",\"components\":[{\"name\":\"usePermissionlessGame\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"startingAnchorRoot\",\"type\":\"tuple\",\"internalType\":\"structProposal\",\"components\":[{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"Hash\"},{\"name\":\"l2SequenceNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"gameParameters\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerInteropMigrator.GameParameters\",\"components\":[{\"name\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"challenger\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"maxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"splitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"initBond\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"clockExtension\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"maxClockDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"}]},{\"name\":\"opChainConfigs\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.OpChainConfig[]\",\"components\":[{\"name\":\"systemConfigProxy\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"proxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"},{\"name\":\"absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"opcmDeployer\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerDeployer\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"opcmGameTypeAdder\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerGameTypeAdder\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"opcmInteropMigrator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerInteropMigrator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"opcmStandardValidator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerStandardValidator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"opcmUpgrader\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerUpgrader\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"protocolVersions\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIProtocolVersions\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"superchainConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISuperchainConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"superchainProxyAdmin\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updatePrestate\",\"inputs\":[{\"name\":\"_prestateUpdateInputs\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.OpChainConfig[]\",\"components\":[{\"name\":\"systemConfigProxy\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"proxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"},{\"name\":\"absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgrade\",\"inputs\":[{\"name\":\"_opChainConfigs\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.OpChainConfig[]\",\"components\":[{\"name\":\"systemConfigProxy\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"proxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"},{\"name\":\"absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"validate\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerStandardValidator.ValidationInput\",\"components\":[{\"name\":\"proxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"},{\"name\":\"sysCfg\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"l2ChainID\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"_allowFailure\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validateWithOverrides\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerStandardValidator.ValidationInput\",\"components\":[{\"name\":\"proxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"},{\"name\":\"sysCfg\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"l2ChainID\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"_allowFailure\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_overrides\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerStandardValidator.ValidationOverrides\",\"components\":[{\"name\":\"l1PAOMultisig\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"challenger\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"pure\"},{\"type\":\"error\",\"name\":\"AddressHasNoCode\",\"inputs\":[{\"name\":\"who\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AddressNotFound\",\"inputs\":[{\"name\":\"who\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AlreadyReleased\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidChainId\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidGameConfigs\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidRoleAddress\",\"inputs\":[{\"name\":\"role\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"InvalidStartingAnchorRoot\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"LatestReleaseNotSet\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyDelegatecall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PrestateNotSet\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PrestateRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SuperchainConfigMismatch\",\"inputs\":[{\"name\":\"systemConfig\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"}]},{\"type\":\"error\",\"name\":\"SuperchainProxyAdminMismatch\",\"inputs\":[]}]", - Bin: "0x6101a06040523480156200001257600080fd5b5060405162002cd838038062002cd883398101604081905262000035916200030c565b60405163b6a4cd2160e01b81526001600160a01b03848116600483015288169063b6a4cd219060240160006040518083038186803b1580156200007757600080fd5b505afa1580156200008c573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0385811660048301528a16925063b6a4cd21915060240160006040518083038186803b158015620000d257600080fd5b505afa158015620000e7573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b038b811660048301528a16925063b6a4cd21915060240160006040518083038186803b1580156200012d57600080fd5b505afa15801562000142573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b038a1660048201819052925063b6a4cd21915060240160006040518083038186803b1580156200018757600080fd5b505afa1580156200019c573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0389811660048301528a16925063b6a4cd21915060240160006040518083038186803b158015620001e257600080fd5b505afa158015620001f7573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0388811660048301528a16925063b6a4cd21915060240160006040518083038186803b1580156200023d57600080fd5b505afa15801562000252573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0387811660048301528a16925063b6a4cd21915060240160006040518083038186803b1580156200029857600080fd5b505afa158015620002ad573d6000803e3d6000fd5b5050506001600160a01b039889166080525095871660a05293861660c05291851660e05284166101005283166101205282166101405216610160523061018052620003cd565b6001600160a01b03811681146200030957600080fd5b50565b600080600080600080600080610100898b0312156200032a57600080fd5b88516200033781620002f3565b60208a01519098506200034a81620002f3565b60408a01519097506200035d81620002f3565b60608a01519096506200037081620002f3565b60808a01519095506200038381620002f3565b60a08a01519094506200039681620002f3565b60c08a0151909350620003a981620002f3565b60e08a0151909250620003bc81620002f3565b809150509295985092959890939650565b60805160a05160c05160e051610100516101205161014051610160516101805161281c620004bc600039600081816104580152818161084f01528181610be501528181610cf10152610ed60152600061022d0152600061035801526000818161029c0152610a170152600081816103f0015281816106230152610ab80152600081816101d0015261091901526000818161018c01528181610cbc0152610fa00152600081816103310152818161056b01528181610719015281816107cc015281816109e001528181610b680152610e4b015260008181610417015281816105240152610dbb015261281c6000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063613e827b116100d8578063b0b807eb1161008c578063ba7903db11610066578063ba7903db146103eb578063becbdf4a14610412578063ff2dd5a11461043957600080fd5b8063b0b807eb146103b0578063b23cc044146103c3578063b51f9c2b146103d657600080fd5b80636624856a116100bd5780636624856a1461035357806367cda69c1461037a57806378ecabce1461038d57600080fd5b8063613e827b1461030c578063622d56f11461032c57600080fd5b806330d148881161013a57806335e80ab31161011457806335e80ab3146102975780633fe13f3f146102be57806354fd4d50146102d357600080fd5b806330d148881461024f57806330e9012c1461026f578063318b1b801461028457600080fd5b80631661a2e91161016b5780631661a2e9146101f25780631d8a4e92146102125780632b96b8391461022857600080fd5b806303dbe68c146101875780631481a724146101cb575b600080fd5b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b610205610200366004611260565b61044c565b6040516101c29190611408565b61021a610567565b6040519081526020016101c2565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b61026261025d3660046114dc565b6105f0565b6040516101c2919061156c565b6102776106a6565b6040516101c2919061157f565b6101ae6102923660046116b3565b61079a565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6102d16102cc3660046116cc565b610845565b005b60408051808201909152600581527f342e302e300000000000000000000000000000000000000000000000000000006020820152610262565b61031f61031a366004611708565b610943565b6040516101c29190611744565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b610262610388366004611881565b610a85565b6103a061039b3660046116b3565b610b36565b60405190151581526020016101c2565b6102d16103be36600461191b565b610bdb565b6102d16103d1366004611949565b610ce7565b6103de610de0565b6040516101c29190611a10565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6102d1610447366004611b33565b610ecc565b60606001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036104b0576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826040516024016104c39190611bf7565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1661a2e900000000000000000000000000000000000000000000000000000000179052905060006105497f000000000000000000000000000000000000000000000000000000000000000083610fc1565b90508080602001905181019061055f9190611d44565b949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631d8a4e926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105eb9190611e0d565b905090565b6040517f30d148880000000000000000000000000000000000000000000000000000000081526060906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906330d148889061065a9086908690600401611e26565b600060405180830381865afa158015610677573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261069f9190810190611e71565b9392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166330e9012c6040518163ffffffff1660e01b81526004016101c060405180830381865afa158015610776573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105eb9190611ee8565b6040517f318b1b80000000000000000000000000000000000000000000000000000000008152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063318b1b8090602401602060405180830381865afa15801561081b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083f9190611ff8565b92915050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036108a7576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816040516024016108ba91906120ed565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f3fe13f3f00000000000000000000000000000000000000000000000000000000179052905061093e7f000000000000000000000000000000000000000000000000000000000000000082610fc1565b505050565b604080516101e081018252600080825260208201819052818301819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082015290517fb2e48a3f0000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b2e48a3f90610a419085907f0000000000000000000000000000000000000000000000000000000000000000903390600401612300565b6101e0604051808303816000875af1158015610a61573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083f91906124b5565b6040517f67cda69c0000000000000000000000000000000000000000000000000000000081526060906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906367cda69c90610af1908790879087906004016125cc565b600060405180830381865afa158015610b0e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261055f9190810190611e71565b6040517f78ecabce000000000000000000000000000000000000000000000000000000008152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906378ecabce90602401602060405180830381865afa158015610bb7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083f9190612636565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610c3d576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b0380841660248301528216604482015260009060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb0b807eb000000000000000000000000000000000000000000000000000000001790529050610ce17f000000000000000000000000000000000000000000000000000000000000000082610fc1565b50505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610d49576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081604051602401610d5c9190612653565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb23cc04400000000000000000000000000000000000000000000000000000000179052905061093e7f000000000000000000000000000000000000000000000000000000000000000082610fc1565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b51f9c2b6040518163ffffffff1660e01b81526004016101a060405180830381865afa158015610ea8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105eb91906126a8565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610f2e576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081604051602401610f41919061279b565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fff2dd5a100000000000000000000000000000000000000000000000000000000179052905061093e7f0000000000000000000000000000000000000000000000000000000000000000825b6060600080846001600160a01b031684604051610fde91906127f3565b600060405180830381855af49150503d8060008114611019576040519150601f19603f3d011682016040523d82523d6000602084013e61101e565b606091505b50915091508161055f57805160208201fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101a0810167ffffffffffffffff8111828210171561108357611083611030565b60405290565b6040805190810167ffffffffffffffff8111828210171561108357611083611030565b6040516060810167ffffffffffffffff8111828210171561108357611083611030565b6040516101c0810167ffffffffffffffff8111828210171561108357611083611030565b6040516101e0810167ffffffffffffffff8111828210171561108357611083611030565b604051601f8201601f1916810167ffffffffffffffff8111828210171561114057611140611030565b604052919050565b600067ffffffffffffffff82111561116257611162611030565b5060051b60200190565b600067ffffffffffffffff82111561118657611186611030565b50601f01601f191660200190565b600082601f8301126111a557600080fd5b81356111b86111b38261116c565b611117565b8181528460208386010111156111cd57600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b03811681146111ff57600080fd5b50565b803561120d816111ea565b919050565b803563ffffffff8116811461120d57600080fd5b67ffffffffffffffff811681146111ff57600080fd5b803561120d81611226565b80151581146111ff57600080fd5b803561120d81611247565b6000602080838503121561127357600080fd5b823567ffffffffffffffff8082111561128b57600080fd5b818501915085601f83011261129f57600080fd5b81356112ad6111b382611148565b81815260059190911b830184019084810190888311156112cc57600080fd5b8585015b838110156113fb578035858111156112e85760008081fd5b86016101a0818c03601f19018113156113015760008081fd5b61130961105f565b898301358881111561131b5760008081fd5b6113298e8c83870101611194565b8252506040611339818501611202565b8b830152606061134a818601611202565b828401526080915061135d828601611202565b9083015260a061136e858201611212565b8284015260c0915081850135818401525060e0808501358284015261010091508185013581840152506101206113a581860161123c565b8284015261014091506113b982860161123c565b8184015250610160808501358284015261018091506113d9828601611202565b908301526113e8848401611255565b90820152855250509186019186016112d0565b5098975050505050505050565b602080825282518282018190526000919060409081850190868401855b8281101561145757815180516001600160a01b0390811686529087015116868501529284019290850190600101611425565b5091979650505050505050565b60006080828403121561147657600080fd5b6040516080810181811067ffffffffffffffff8211171561149957611499611030565b60405290508082356114aa816111ea565b815260208301356114ba816111ea565b8060208301525060408301356040820152606083013560608201525092915050565b60008060a083850312156114ef57600080fd5b6114f98484611464565b9150608083013561150981611247565b809150509250929050565b60005b8381101561152f578181015183820152602001611517565b83811115610ce15750506000910152565b60008151808452611558816020860160208601611514565b601f01601f19169290920160200192915050565b60208152600061069f6020830184611540565b81516001600160a01b031681526101c0810160208301516115ab60208401826001600160a01b03169052565b5060408301516115c660408401826001600160a01b03169052565b5060608301516115e160608401826001600160a01b03169052565b5060808301516115fc60808401826001600160a01b03169052565b5060a083015161161760a08401826001600160a01b03169052565b5060c083015161163260c08401826001600160a01b03169052565b5060e083015161164d60e08401826001600160a01b03169052565b50610100838101516001600160a01b0390811691840191909152610120808501518216908401526101408085015182169084015261016080850151821690840152610180808501518216908401526101a08085015191821681850152905b505092915050565b6000602082840312156116c557600080fd5b5035919050565b6000602082840312156116de57600080fd5b813567ffffffffffffffff8111156116f557600080fd5b8201610160818503121561069f57600080fd5b60006020828403121561171a57600080fd5b813567ffffffffffffffff81111561173157600080fd5b8201610240818503121561069f57600080fd5b81516001600160a01b031681526101e08101602083015161177060208401826001600160a01b03169052565b50604083015161178b60408401826001600160a01b03169052565b5060608301516117a660608401826001600160a01b03169052565b5060808301516117c160808401826001600160a01b03169052565b5060a08301516117dc60a08401826001600160a01b03169052565b5060c08301516117f760c08401826001600160a01b03169052565b5060e083015161181260e08401826001600160a01b03169052565b50610100838101516001600160a01b0390811691840191909152610120808501518216908401526101408085015182169084015261016080850151821690840152610180808501518216908401526101a0808501518216908401526101c08085015191821681850152906116ab565b600080600083850360e081121561189757600080fd5b6118a18686611464565b935060808501356118b181611247565b925060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60820112156118e357600080fd5b506118ec611089565b60a08501356118fa816111ea565b815260c085013561190a816111ea565b602082015292959194509192509050565b6000806040838503121561192e57600080fd5b8235611939816111ea565b91506020830135611509816111ea565b6000602080838503121561195c57600080fd5b823567ffffffffffffffff81111561197357600080fd5b8301601f8101851361198457600080fd5b80356119926111b382611148565b818152606091820283018401918482019190888411156119b157600080fd5b938501935b83851015611a045780858a0312156119ce5760008081fd5b6119d66110ac565b85356119e1816111ea565b8152858701358782015260408087013590820152835293840193918501916119b6565b50979650505050505050565b81516001600160a01b031681526101a081016020830151611a3c60208401826001600160a01b03169052565b506040830151611a5760408401826001600160a01b03169052565b506060830151611a7260608401826001600160a01b03169052565b506080830151611a8d60808401826001600160a01b03169052565b5060a0830151611aa860a08401826001600160a01b03169052565b5060c0830151611ac360c08401826001600160a01b03169052565b5060e0830151611ade60e08401826001600160a01b03169052565b50610100838101516001600160a01b03908116918401919091526101208085015182169084015261014080850151821690840152610160808501518216908401526101808085015191821681850152906116ab565b60006020808385031215611b4657600080fd5b823567ffffffffffffffff811115611b5d57600080fd5b8301601f81018513611b6e57600080fd5b8035611b7c6111b382611148565b81815260609182028301840191848201919088841115611b9b57600080fd5b938501935b83851015611a045780858a031215611bb85760008081fd5b611bc06110ac565b8535611bcb816111ea565b815285870135611bda816111ea565b818801526040868101359082015283529384019391850191611ba0565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611d2b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281516101a08151818652611c6382870182611540565b91505088820151611c7e8a8701826001600160a01b03169052565b50878201516001600160a01b03908116868a015260608084015182169087015260808084015163ffffffff169087015260a0808401519087015260c0808401519087015260e080840151908701526101008084015167ffffffffffffffff9081169188019190915261012080850151909116908701526101408084015190870152610160808401519091169086015261018091820151151591909401529386019390860190600101611c1e565b509098975050505050505050565b805161120d816111ea565b60006020808385031215611d5757600080fd5b825167ffffffffffffffff811115611d6e57600080fd5b8301601f81018513611d7f57600080fd5b8051611d8d6111b382611148565b81815260069190911b82018301908381019087831115611dac57600080fd5b928401925b82841015611e025760408489031215611dca5760008081fd5b611dd2611089565b8451611ddd816111ea565b815284860151611dec816111ea565b8187015282526040939093019290840190611db1565b979650505050505050565b600060208284031215611e1f57600080fd5b5051919050565b60a08101611e6282856001600160a01b038082511683528060208301511660208401525060408101516040830152606081015160608301525050565b82151560808301529392505050565b600060208284031215611e8357600080fd5b815167ffffffffffffffff811115611e9a57600080fd5b8201601f81018413611eab57600080fd5b8051611eb96111b38261116c565b818152856020838501011115611ece57600080fd5b611edf826020830160208601611514565b95945050505050565b60006101c08284031215611efb57600080fd5b611f036110cf565b611f0c83611d39565b8152611f1a60208401611d39565b6020820152611f2b60408401611d39565b6040820152611f3c60608401611d39565b6060820152611f4d60808401611d39565b6080820152611f5e60a08401611d39565b60a0820152611f6f60c08401611d39565b60c0820152611f8060e08401611d39565b60e0820152610100611f93818501611d39565b90820152610120611fa5848201611d39565b90820152610140611fb7848201611d39565b90820152610160611fc9848201611d39565b90820152610180611fdb848201611d39565b908201526101a0611fed848201611d39565b908201529392505050565b60006020828403121561200a57600080fd5b815161069f816111ea565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261204a57600080fd5b830160208101925035905067ffffffffffffffff81111561206a57600080fd5b60608102360382131561207c57600080fd5b9250929050565b8183526000602080850194508260005b858110156120e25781356120a6816111ea565b6001600160a01b03908116885282840135906120c1826111ea565b16878401526040828101359088015260609687019690910190600101612093565b509495945050505050565b60208152600082356120fe81611247565b80151560208401525060208301356040830152604083013560608301526060830135612129816111ea565b6001600160a01b03808216608085015260808501359150612149826111ea565b80821660a0850152505060a083013560c083015260c083013560e083015261010060e08401358184015280840135905061218281611226565b61012067ffffffffffffffff82168185015261219f81860161123c565b9150506101406121ba8185018367ffffffffffffffff169052565b6121c681860186612015565b6101608681015292509050611edf61018085018383612083565b80356121eb816111ea565b6001600160a01b039081168352602082013590612207826111ea565b908116602084015260408201359061221e826111ea565b9081166040840152606082013590612235826111ea565b908116606084015260808201359061224c826111ea565b908116608084015260a082013590612263826111ea565b80821660a085015250505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a657600080fd5b830160208101925035905067ffffffffffffffff8111156122c657600080fd5b80360382131561207c57600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6060815261231160608201856121e0565b600061231f60c08601611212565b6101206123338185018363ffffffff169052565b61233f60e08801611212565b91506101406123558186018463ffffffff169052565b61016092506101008801358386015261237082890189612271565b9250610240610180818189015261238c6102a0890186856122d5565b945061239a848c018c612271565b945092506101a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa089870301818a01526123d58686866122d5565b95506123e2878d0161123c565b96506101c094506123fe858a018867ffffffffffffffff169052565b612409828d01611212565b96506101e09350612421848a018863ffffffff169052565b6102009650808c0135878a01525050610220838b013581890152828b01358289015261244e868c0161123c565b67ffffffffffffffff81166102608a0152955061246c818c0161123c565b95505050505061248961028085018367ffffffffffffffff169052565b6001600160a01b038616602085015291506124a19050565b6001600160a01b038316604083015261055f565b60006101e082840312156124c857600080fd5b6124d06110f3565b6124d983611d39565b81526124e760208401611d39565b60208201526124f860408401611d39565b604082015261250960608401611d39565b606082015261251a60808401611d39565b608082015261252b60a08401611d39565b60a082015261253c60c08401611d39565b60c082015261254d60e08401611d39565b60e0820152610100612560818501611d39565b90820152610120612572848201611d39565b90820152610140612584848201611d39565b90820152610160612596848201611d39565b908201526101806125a8848201611d39565b908201526101a06125ba848201611d39565b908201526101c0611fed848201611d39565b60e0810161260882866001600160a01b038082511683528060208301511660208401525060408101516040830152606081015160608301525050565b83151560808301526001600160a01b038084511660a08401528060208501511660c084015250949350505050565b60006020828403121561264857600080fd5b815161069f81611247565b602080825282518282018190526000919060409081850190868401855b8281101561145757815180516001600160a01b0316855286810151878601528501518585015260609093019290850190600101612670565b60006101a082840312156126bb57600080fd5b6126c361105f565b6126cc83611d39565b81526126da60208401611d39565b60208201526126eb60408401611d39565b60408201526126fc60608401611d39565b606082015261270d60808401611d39565b608082015261271e60a08401611d39565b60a082015261272f60c08401611d39565b60c082015261274060e08401611d39565b60e0820152610100612753818501611d39565b90820152610120612765848201611d39565b90820152610140612777848201611d39565b90820152610160612789848201611d39565b90820152610180611fed848201611d39565b602080825282518282018190526000919060409081850190868401855b8281101561145757815180516001600160a01b03908116865287820151168786015285015185850152606090930192908501906001016127b8565b60008251612805818460208701611514565b919091019291505056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_opcmGameTypeAdder\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerGameTypeAdder\"},{\"name\":\"_opcmDeployer\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerDeployer\"},{\"name\":\"_opcmUpgrader\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerUpgrader\"},{\"name\":\"_opcmInteropMigrator\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerInteropMigrator\"},{\"name\":\"_opcmStandardValidator\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerStandardValidator\"},{\"name\":\"_superchainConfig\",\"type\":\"address\",\"internalType\":\"contractISuperchainConfig\"},{\"name\":\"_protocolVersions\",\"type\":\"address\",\"internalType\":\"contractIProtocolVersions\"},{\"name\":\"_superchainProxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addGameType\",\"inputs\":[{\"name\":\"_gameConfigs\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.AddGameInput[]\",\"components\":[{\"name\":\"saltMixer\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"systemConfig\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"delayedWETH\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"},{\"name\":\"disputeGameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"disputeAbsolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"disputeMaxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"disputeSplitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"disputeClockExtension\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"disputeMaxClockDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"initialBond\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"vm\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"},{\"name\":\"permissioned\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.AddGameOutput[]\",\"components\":[{\"name\":\"delayedWETH\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"},{\"name\":\"faultDisputeGame\",\"type\":\"address\",\"internalType\":\"contractIFaultDisputeGame\"}]}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"blueprints\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.Blueprints\",\"components\":[{\"name\":\"addressManager\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"proxy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"proxyAdmin\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1ChugSplashProxy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"resolvedDelegateProxy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"permissionedDisputeGame1\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"permissionedDisputeGame2\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"permissionlessDisputeGame1\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"permissionlessDisputeGame2\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superPermissionedDisputeGame1\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superPermissionedDisputeGame2\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superPermissionlessDisputeGame1\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superPermissionlessDisputeGame2\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"chainIdToBatchInboxAddress\",\"inputs\":[{\"name\":\"_l2ChainId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deploy\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.DeployInput\",\"components\":[{\"name\":\"roles\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.Roles\",\"components\":[{\"name\":\"opChainProxyAdminOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"systemConfigOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"batcher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"unsafeBlockSigner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"challenger\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"basefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"blobBasefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"l2ChainId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startingAnchorRoot\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"saltMixer\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"disputeGameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"disputeAbsolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"disputeMaxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"disputeSplitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"disputeClockExtension\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"disputeMaxClockDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.DeployOutput\",\"components\":[{\"name\":\"opChainProxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"},{\"name\":\"addressManager\",\"type\":\"address\",\"internalType\":\"contractIAddressManager\"},{\"name\":\"l1ERC721BridgeProxy\",\"type\":\"address\",\"internalType\":\"contractIL1ERC721Bridge\"},{\"name\":\"systemConfigProxy\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"optimismMintableERC20FactoryProxy\",\"type\":\"address\",\"internalType\":\"contractIOptimismMintableERC20Factory\"},{\"name\":\"l1StandardBridgeProxy\",\"type\":\"address\",\"internalType\":\"contractIL1StandardBridge\"},{\"name\":\"l1CrossDomainMessengerProxy\",\"type\":\"address\",\"internalType\":\"contractIL1CrossDomainMessenger\"},{\"name\":\"ethLockboxProxy\",\"type\":\"address\",\"internalType\":\"contractIETHLockbox\"},{\"name\":\"optimismPortalProxy\",\"type\":\"address\",\"internalType\":\"contractIOptimismPortal2\"},{\"name\":\"disputeGameFactoryProxy\",\"type\":\"address\",\"internalType\":\"contractIDisputeGameFactory\"},{\"name\":\"anchorStateRegistryProxy\",\"type\":\"address\",\"internalType\":\"contractIAnchorStateRegistry\"},{\"name\":\"faultDisputeGame\",\"type\":\"address\",\"internalType\":\"contractIFaultDisputeGame\"},{\"name\":\"permissionedDisputeGame\",\"type\":\"address\",\"internalType\":\"contractIPermissionedDisputeGame\"},{\"name\":\"delayedWETHPermissionedGameProxy\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"},{\"name\":\"delayedWETHPermissionlessGameProxy\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"}]}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"devFeatureBitmap\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"implementations\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManager.Implementations\",\"components\":[{\"name\":\"superchainConfigImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"protocolVersionsImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1ERC721BridgeImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismPortalImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismPortalInteropImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"ethLockboxImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"systemConfigImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismMintableERC20FactoryImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1CrossDomainMessengerImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1StandardBridgeImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"disputeGameFactoryImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"anchorStateRegistryImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"delayedWETHImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"mipsImpl\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isDevFeatureEnabled\",\"inputs\":[{\"name\":\"_feature\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"migrate\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerInteropMigrator.MigrateInput\",\"components\":[{\"name\":\"usePermissionlessGame\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"startingAnchorRoot\",\"type\":\"tuple\",\"internalType\":\"structProposal\",\"components\":[{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"Hash\"},{\"name\":\"l2SequenceNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"gameParameters\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerInteropMigrator.GameParameters\",\"components\":[{\"name\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"challenger\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"maxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"splitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"initBond\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"clockExtension\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"maxClockDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"}]},{\"name\":\"opChainConfigs\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.OpChainConfig[]\",\"components\":[{\"name\":\"systemConfigProxy\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"opcmDeployer\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerDeployer\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"opcmGameTypeAdder\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerGameTypeAdder\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"opcmInteropMigrator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerInteropMigrator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"opcmStandardValidator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerStandardValidator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"opcmUpgrader\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOPContractsManagerUpgrader\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"protocolVersions\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIProtocolVersions\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"superchainConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISuperchainConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"superchainProxyAdmin\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updatePrestate\",\"inputs\":[{\"name\":\"_prestateUpdateInputs\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.UpdatePrestateInput[]\",\"components\":[{\"name\":\"systemConfigProxy\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"cannonPrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"cannonKonaPrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgrade\",\"inputs\":[{\"name\":\"_opChainConfigs\",\"type\":\"tuple[]\",\"internalType\":\"structOPContractsManager.OpChainConfig[]\",\"components\":[{\"name\":\"systemConfigProxy\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeSuperchainConfig\",\"inputs\":[{\"name\":\"_superchainConfig\",\"type\":\"address\",\"internalType\":\"contractISuperchainConfig\"},{\"name\":\"_superchainProxyAdmin\",\"type\":\"address\",\"internalType\":\"contractIProxyAdmin\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"validate\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerStandardValidator.ValidationInput\",\"components\":[{\"name\":\"sysCfg\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"l2ChainID\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"_allowFailure\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validateWithOverrides\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerStandardValidator.ValidationInput\",\"components\":[{\"name\":\"sysCfg\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"l2ChainID\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"_allowFailure\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_overrides\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerStandardValidator.ValidationOverrides\",\"components\":[{\"name\":\"l1PAOMultisig\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"challenger\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"pure\"},{\"type\":\"error\",\"name\":\"AddressHasNoCode\",\"inputs\":[{\"name\":\"who\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AddressNotFound\",\"inputs\":[{\"name\":\"who\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AlreadyReleased\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidChainId\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidGameConfigs\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidRoleAddress\",\"inputs\":[{\"name\":\"role\",\"type\":\"string\",\"internalType\":\"string\"}]},{\"type\":\"error\",\"name\":\"InvalidStartingAnchorRoot\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"LatestReleaseNotSet\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyDelegatecall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PrestateNotSet\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PrestateRequired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SuperchainConfigMismatch\",\"inputs\":[{\"name\":\"systemConfig\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"}]},{\"type\":\"error\",\"name\":\"SuperchainProxyAdminMismatch\",\"inputs\":[]}]", + Bin: "0x6101a06040523480156200001257600080fd5b5060405162002c0538038062002c0583398101604081905262000035916200030c565b60405163b6a4cd2160e01b81526001600160a01b03848116600483015288169063b6a4cd219060240160006040518083038186803b1580156200007757600080fd5b505afa1580156200008c573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0385811660048301528a16925063b6a4cd21915060240160006040518083038186803b158015620000d257600080fd5b505afa158015620000e7573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b038b811660048301528a16925063b6a4cd21915060240160006040518083038186803b1580156200012d57600080fd5b505afa15801562000142573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b038a1660048201819052925063b6a4cd21915060240160006040518083038186803b1580156200018757600080fd5b505afa1580156200019c573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0389811660048301528a16925063b6a4cd21915060240160006040518083038186803b158015620001e257600080fd5b505afa158015620001f7573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0388811660048301528a16925063b6a4cd21915060240160006040518083038186803b1580156200023d57600080fd5b505afa15801562000252573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0387811660048301528a16925063b6a4cd21915060240160006040518083038186803b1580156200029857600080fd5b505afa158015620002ad573d6000803e3d6000fd5b5050506001600160a01b039889166080525095871660a05293861660c05291851660e05284166101005283166101205282166101405216610160523061018052620003cd565b6001600160a01b03811681146200030957600080fd5b50565b600080600080600080600080610100898b0312156200032a57600080fd5b88516200033781620002f3565b60208a01519098506200034a81620002f3565b60408a01519097506200035d81620002f3565b60608a01519096506200037081620002f3565b60808a01519095506200038381620002f3565b60a08a01519094506200039681620002f3565b60c08a0151909350620003a981620002f3565b60e08a0151909250620003bc81620002f3565b809150509295985092959890939650565b60805160a05160c05160e0516101005161012051610140516101605161018051612749620004bc600039600081816104520152818161077a015281816109d501528181610c420152610d4e0152600061022201526000610341015260008181610271015261095d0152600081816103ff01528181610bc20152610f970152600081816101e50152610a9f01526000818161018c0152818161051c0152610d1901526000818161031a0152818161054a01528181610642015281816106f50152818161092601528181610af60152610ea8015260008181610426015281816108460152610e1801526127496000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063622d56f1116100d8578063b0b807eb1161008c578063b806c80511610066578063b806c805146103e7578063ba7903db146103fa578063becbdf4a1461042157600080fd5b8063b0b807eb146103ac578063b23cc044146103bf578063b51f9c2b146103d257600080fd5b80636d510c5e116100bd5780636d510c5e1461036357806378ecabce14610376578063a9008b691461039957600080fd5b8063622d56f1146103155780636624856a1461033c57600080fd5b806330e9012c1161013a57806354fd4d501161011457806354fd4d5014610293578063604aa628146102d5578063613e827b146102f557600080fd5b806330e9012c14610244578063318b1b801461025957806335e80ab31461026c57600080fd5b80631481a7241161016b5780631481a724146101e05780631d8a4e92146102075780632b96b8391461021d57600080fd5b806303dbe68c146101875780630b8bd7cb146101cb575b600080fd5b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6101de6101d93660046111fd565b610448565b005b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b61020f610546565b6040519081526020016101c2565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b61024c6105cf565b6040516101c291906112c1565b6101ae6102673660046113f5565b6106c3565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b60408051808201909152600581527f342e312e3000000000000000000000000000000000000000000000000000000060208201525b6040516101c29190611466565b6102e86102e3366004611540565b61076e565b6040516101c291906116d5565b610308610303366004611731565b610889565b6040516101c2919061176d565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6101de6103713660046118aa565b6109cb565b6103896103843660046113f5565b610ac4565b60405190151581526020016101c2565b6102c86103a736600461192b565b610b69565b6101de6103ba366004611963565b610c38565b6101de6103cd366004611991565b610d44565b6103da610e3d565b6040516101c29190611a58565b6102c86103f5366004611b7b565b610f29565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036104aa576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816040516024016104bd9190611c15565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0b8bd7cb0000000000000000000000000000000000000000000000000000000017905290506105417f000000000000000000000000000000000000000000000000000000000000000082611006565b505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631d8a4e926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ca9190611c60565b905090565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166330e9012c6040518163ffffffff1660e01b81526004016101c060405180830381865afa15801561069f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ca9190611c84565b6040517f318b1b80000000000000000000000000000000000000000000000000000000008152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063318b1b8090602401602060405180830381865afa158015610744573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107689190611d94565b92915050565b60606001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036107d2576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826040516024016107e59190611db1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f604aa628000000000000000000000000000000000000000000000000000000001790529050600061086b7f000000000000000000000000000000000000000000000000000000000000000083611006565b9050808060200190518101906108819190611ee6565b949350505050565b604080516101e081018252600080825260208201819052818301819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082015290517fb2e48a3f0000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b2e48a3f906109879085907f00000000000000000000000000000000000000000000000000000000000000009033906004016120cb565b6101e0604051808303816000875af11580156109a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107689190612280565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610a2d576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081604051602401610a409190612451565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f6d510c5e0000000000000000000000000000000000000000000000000000000017905290506105417f000000000000000000000000000000000000000000000000000000000000000082611006565b6040517f78ecabce000000000000000000000000000000000000000000000000000000008152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906378ecabce90602401602060405180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610768919061254d565b604080517fa9008b6900000000000000000000000000000000000000000000000000000000815283516001600160a01b0390811660048301526020850151602483015291840151604482015282151560648201526060917f0000000000000000000000000000000000000000000000000000000000000000169063a9008b6990608401600060405180830381865afa158015610c09573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c31919081019061256a565b9392505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610c9a576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b0380841660248301528216604482015260009060640160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb0b807eb000000000000000000000000000000000000000000000000000000001790529050610d3e7f000000000000000000000000000000000000000000000000000000000000000082611006565b50505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610da6576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081604051602401610db991906125d8565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb23cc0440000000000000000000000000000000000000000000000000000000017905290506105417f000000000000000000000000000000000000000000000000000000000000000082611006565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b51f9c2b6040518163ffffffff1660e01b81526004016101a060405180830381865afa158015610f05573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ca919061262d565b604080517fb806c80500000000000000000000000000000000000000000000000000000000815284516001600160a01b0390811660048301526020808701516024840152928601516044830152841515606483015283518116608483015291830151821660a48201526060917f0000000000000000000000000000000000000000000000000000000000000000169063b806c8059060c401600060405180830381865afa158015610fde573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610881919081019061256a565b6060600080846001600160a01b0316846040516110239190612720565b600060405180830381855af49150503d806000811461105e576040519150601f19603f3d011682016040523d82523d6000602084013e611063565b606091505b50915091508161088157805160208201fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156110c7576110c7611075565b60405290565b604051610180810167ffffffffffffffff811182821017156110c7576110c7611075565b6040516060810167ffffffffffffffff811182821017156110c7576110c7611075565b6040516101c0810167ffffffffffffffff811182821017156110c7576110c7611075565b6040516101e0810167ffffffffffffffff811182821017156110c7576110c7611075565b6040516101a0810167ffffffffffffffff811182821017156110c7576110c7611075565b604051601f8201601f1916810167ffffffffffffffff811182821017156111a9576111a9611075565b604052919050565b600067ffffffffffffffff8211156111cb576111cb611075565b5060051b60200190565b6001600160a01b03811681146111ea57600080fd5b50565b80356111f8816111d5565b919050565b6000602080838503121561121057600080fd5b823567ffffffffffffffff81111561122757600080fd5b8301601f8101851361123857600080fd5b803561124b611246826111b1565b611180565b81815260069190911b8201830190838101908783111561126a57600080fd5b928401925b828410156112b657604084890312156112885760008081fd5b6112906110a4565b843561129b816111d5565b8152848601358682015282526040909301929084019061126f565b979650505050505050565b81516001600160a01b031681526101c0810160208301516112ed60208401826001600160a01b03169052565b50604083015161130860408401826001600160a01b03169052565b50606083015161132360608401826001600160a01b03169052565b50608083015161133e60808401826001600160a01b03169052565b5060a083015161135960a08401826001600160a01b03169052565b5060c083015161137460c08401826001600160a01b03169052565b5060e083015161138f60e08401826001600160a01b03169052565b50610100838101516001600160a01b0390811691840191909152610120808501518216908401526101408085015182169084015261016080850151821690840152610180808501518216908401526101a08085015191821681850152905b505092915050565b60006020828403121561140757600080fd5b5035919050565b60005b83811015611429578181015183820152602001611411565b83811115610d3e5750506000910152565b6000815180845261145281602086016020860161140e565b601f01601f19169290920160200192915050565b602081526000610c31602083018461143a565b600067ffffffffffffffff82111561149357611493611075565b50601f01601f191660200190565b600082601f8301126114b257600080fd5b81356114c061124682611479565b8181528460208386010111156114d557600080fd5b816020850160208301376000918101602001919091529392505050565b803563ffffffff811681146111f857600080fd5b67ffffffffffffffff811681146111ea57600080fd5b80356111f881611506565b80151581146111ea57600080fd5b80356111f881611527565b6000602080838503121561155357600080fd5b823567ffffffffffffffff8082111561156b57600080fd5b818501915085601f83011261157f57600080fd5b813561158d611246826111b1565b81815260059190911b830184019084810190888311156115ac57600080fd5b8585015b838110156116c8578035858111156115c85760008081fd5b8601610180818c03601f19018113156115e15760008081fd5b6115e96110cd565b89830135888111156115fb5760008081fd5b6116098e8c838701016114a1565b82525060406116198185016111ed565b8b830152606061162a8186016111ed565b828401526080915061163d8286016114f2565b818401525060a0808501358284015260c0915081850135818401525060e08085013582840152610100915061167382860161151c565b9083015261012061168585820161151c565b8284015261014091508185013581840152506101606116a58186016111ed565b828401526116b4848601611535565b9083015250855250509186019186016115b0565b5098975050505050505050565b602080825282518282018190526000919060409081850190868401855b8281101561172457815180516001600160a01b03908116865290870151168685015292840192908501906001016116f2565b5091979650505050505050565b60006020828403121561174357600080fd5b813567ffffffffffffffff81111561175a57600080fd5b82016102408185031215610c3157600080fd5b81516001600160a01b031681526101e08101602083015161179960208401826001600160a01b03169052565b5060408301516117b460408401826001600160a01b03169052565b5060608301516117cf60608401826001600160a01b03169052565b5060808301516117ea60808401826001600160a01b03169052565b5060a083015161180560a08401826001600160a01b03169052565b5060c083015161182060c08401826001600160a01b03169052565b5060e083015161183b60e08401826001600160a01b03169052565b50610100838101516001600160a01b0390811691840191909152610120808501518216908401526101408085015182169084015261016080850151821690840152610180808501518216908401526101a0808501518216908401526101c08085015191821681850152906113ed565b6000602082840312156118bc57600080fd5b813567ffffffffffffffff8111156118d357600080fd5b82016101608185031215610c3157600080fd5b6000606082840312156118f857600080fd5b6119006110f1565b9050813561190d816111d5565b80825250602082013560208201526040820135604082015292915050565b6000806080838503121561193e57600080fd5b61194884846118e6565b9150606083013561195881611527565b809150509250929050565b6000806040838503121561197657600080fd5b8235611981816111d5565b91506020830135611958816111d5565b600060208083850312156119a457600080fd5b823567ffffffffffffffff8111156119bb57600080fd5b8301601f810185136119cc57600080fd5b80356119da611246826111b1565b818152606091820283018401918482019190888411156119f957600080fd5b938501935b83851015611a4c5780858a031215611a165760008081fd5b611a1e6110f1565b8535611a29816111d5565b8152858701358782015260408087013590820152835293840193918501916119fe565b50979650505050505050565b81516001600160a01b031681526101a081016020830151611a8460208401826001600160a01b03169052565b506040830151611a9f60408401826001600160a01b03169052565b506060830151611aba60608401826001600160a01b03169052565b506080830151611ad560808401826001600160a01b03169052565b5060a0830151611af060a08401826001600160a01b03169052565b5060c0830151611b0b60c08401826001600160a01b03169052565b5060e0830151611b2660e08401826001600160a01b03169052565b50610100838101516001600160a01b03908116918401919091526101208085015182169084015261014080850151821690840152610160808501518216908401526101808085015191821681850152906113ed565b600080600083850360c0811215611b9157600080fd5b611b9b86866118e6565b93506060850135611bab81611527565b925060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082011215611bdd57600080fd5b50611be66110a4565b6080850135611bf4816111d5565b815260a0850135611c04816111d5565b602082015292959194509192509050565b602080825282518282018190526000919060409081850190868401855b8281101561172457815180516001600160a01b03168552860151868501529284019290850190600101611c32565b600060208284031215611c7257600080fd5b5051919050565b80516111f8816111d5565b60006101c08284031215611c9757600080fd5b611c9f611114565b611ca883611c79565b8152611cb660208401611c79565b6020820152611cc760408401611c79565b6040820152611cd860608401611c79565b6060820152611ce960808401611c79565b6080820152611cfa60a08401611c79565b60a0820152611d0b60c08401611c79565b60c0820152611d1c60e08401611c79565b60e0820152610100611d2f818501611c79565b90820152610120611d41848201611c79565b90820152610140611d53848201611c79565b90820152610160611d65848201611c79565b90820152610180611d77848201611c79565b908201526101a0611d89848201611c79565b908201529392505050565b600060208284031215611da657600080fd5b8151610c31816111d5565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611ed8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281516101808151818652611e1d8287018261143a565b91505088820151611e388a8701826001600160a01b03169052565b50878201516001600160a01b03908116868a015260608084015163ffffffff16908701526080808401519087015260a0808401519087015260c0808401519087015260e08084015167ffffffffffffffff9081169188019190915261010080850151909116908701526101208084015190870152610140808401519091169086015261016091820151151591909401529386019390860190600101611dd8565b509098975050505050505050565b60006020808385031215611ef957600080fd5b825167ffffffffffffffff811115611f1057600080fd5b8301601f81018513611f2157600080fd5b8051611f2f611246826111b1565b81815260069190911b82018301908381019087831115611f4e57600080fd5b928401925b828410156112b65760408489031215611f6c5760008081fd5b611f746110a4565b8451611f7f816111d5565b815284860151611f8e816111d5565b8187015282526040939093019290840190611f53565b8035611faf816111d5565b6001600160a01b039081168352602082013590611fcb826111d5565b9081166020840152604082013590611fe2826111d5565b9081166040840152606082013590611ff9826111d5565b9081166060840152608082013590612010826111d5565b908116608084015260a082013590612027826111d5565b80821660a085015250505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261206a57600080fd5b830160208101925035905067ffffffffffffffff81111561208a57600080fd5b80360382131561209957600080fd5b9250929050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b606081526120dc6060820185611fa4565b60006120ea60c086016114f2565b6101206120fe8185018363ffffffff169052565b61210a60e088016114f2565b91506101406121208186018463ffffffff169052565b61016092506101008801358386015261213b82890189612035565b925061024061018081818901526121576102a0890186856120a0565b9450612165848c018c612035565b945092506101a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa089870301818a01526121a08686866120a0565b95506121ad878d0161151c565b96506101c094506121c9858a018867ffffffffffffffff169052565b6121d4828d016114f2565b96506101e093506121ec848a018863ffffffff169052565b6102009650808c0135878a01525050610220838b013581890152828b013582890152612219868c0161151c565b67ffffffffffffffff81166102608a01529550612237818c0161151c565b95505050505061225461028085018367ffffffffffffffff169052565b6001600160a01b0386166020850152915061226c9050565b6001600160a01b0383166040830152610881565b60006101e0828403121561229357600080fd5b61229b611138565b6122a483611c79565b81526122b260208401611c79565b60208201526122c360408401611c79565b60408201526122d460608401611c79565b60608201526122e560808401611c79565b60808201526122f660a08401611c79565b60a082015261230760c08401611c79565b60c082015261231860e08401611c79565b60e082015261010061232b818501611c79565b9082015261012061233d848201611c79565b9082015261014061234f848201611c79565b90820152610160612361848201611c79565b90820152610180612373848201611c79565b908201526101a0612385848201611c79565b908201526101c0611d89848201611c79565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126123cc57600080fd5b830160208101925035905067ffffffffffffffff8111156123ec57600080fd5b8060061b360382131561209957600080fd5b8183526000602080850194508260005b85811015612446578135612421816111d5565b6001600160a01b0316875281830135838801526040968701969091019060010161240e565b509495945050505050565b602081526000823561246281611527565b8015156020840152506020830135604083015260408301356060830152606083013561248d816111d5565b6001600160a01b038082166080850152608085013591506124ad826111d5565b80821660a0850152505060a083013560c083015260c083013560e083015261010060e0840135818401528084013590506124e681611506565b61012067ffffffffffffffff82168185015261250381860161151c565b91505061014061251e8185018367ffffffffffffffff169052565b61252a81860186612397565b6101608681015292509050612544610180850183836123fe565b95945050505050565b60006020828403121561255f57600080fd5b8151610c3181611527565b60006020828403121561257c57600080fd5b815167ffffffffffffffff81111561259357600080fd5b8201601f810184136125a457600080fd5b80516125b261124682611479565b8181528560208385010111156125c757600080fd5b61254482602083016020860161140e565b602080825282518282018190526000919060409081850190868401855b8281101561172457815180516001600160a01b03168552868101518786015285015185850152606090930192908501906001016125f5565b60006101a0828403121561264057600080fd5b61264861115c565b61265183611c79565b815261265f60208401611c79565b602082015261267060408401611c79565b604082015261268160608401611c79565b606082015261269260808401611c79565b60808201526126a360a08401611c79565b60a08201526126b460c08401611c79565b60c08201526126c560e08401611c79565b60e08201526101006126d8818501611c79565b908201526101206126ea848201611c79565b908201526101406126fc848201611c79565b9082015261016061270e848201611c79565b90820152610180611d89848201611c79565b6000825161273281846020870161140e565b919091019291505056fea164736f6c634300080f000a", } // OPContractsManagerABI is the input ABI used to generate the binding from. @@ -194,7 +198,7 @@ var OPContractsManagerABI = OPContractsManagerMetaData.ABI var OPContractsManagerBin = OPContractsManagerMetaData.Bin // DeployOPContractsManager deploys a new Ethereum contract, binding an instance of OPContractsManager to it. -func DeployOPContractsManager(auth *bind.TransactOpts, backend bind.ContractBackend, _opcmGameTypeAdder common.Address, _opcmDeployer common.Address, _opcmUpgrader common.Address, _opcmInteropMigrator common.Address, _opcmStandardValidator common.Address, _superchainConfig common.Address, _protocolVersions common.Address, _superchainProxyAdmin common.Address, _l1PAO common.Address) (common.Address, *types.Transaction, *OPContractsManager, error) { +func DeployOPContractsManager(auth *bind.TransactOpts, backend bind.ContractBackend, _opcmGameTypeAdder common.Address, _opcmDeployer common.Address, _opcmUpgrader common.Address, _opcmInteropMigrator common.Address, _opcmStandardValidator common.Address, _superchainConfig common.Address, _protocolVersions common.Address, _superchainProxyAdmin common.Address) (common.Address, *types.Transaction, *OPContractsManager, error) { parsed, err := OPContractsManagerMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -203,7 +207,7 @@ func DeployOPContractsManager(auth *bind.TransactOpts, backend bind.ContractBack return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OPContractsManagerBin), backend, _opcmGameTypeAdder, _opcmDeployer, _opcmUpgrader, _opcmInteropMigrator, _opcmStandardValidator, _superchainConfig, _protocolVersions, _superchainProxyAdmin, _l1PAO) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OPContractsManagerBin), backend, _opcmGameTypeAdder, _opcmDeployer, _opcmUpgrader, _opcmInteropMigrator, _opcmStandardValidator, _superchainConfig, _protocolVersions, _superchainProxyAdmin) if err != nil { return common.Address{}, nil, nil, err } @@ -755,9 +759,9 @@ func (_OPContractsManager *OPContractsManagerCallerSession) SuperchainProxyAdmin return _OPContractsManager.Contract.SuperchainProxyAdmin(&_OPContractsManager.CallOpts) } -// Validate is a free data retrieval call binding the contract method 0x30d14888. +// Validate is a free data retrieval call binding the contract method 0xa9008b69. // -// Solidity: function validate((address,address,bytes32,uint256) _input, bool _allowFailure) view returns(string) +// Solidity: function validate((address,bytes32,uint256) _input, bool _allowFailure) view returns(string) func (_OPContractsManager *OPContractsManagerCaller) Validate(opts *bind.CallOpts, _input OPContractsManagerStandardValidatorValidationInput, _allowFailure bool) (string, error) { var out []interface{} err := _OPContractsManager.contract.Call(opts, &out, "validate", _input, _allowFailure) @@ -772,23 +776,23 @@ func (_OPContractsManager *OPContractsManagerCaller) Validate(opts *bind.CallOpt } -// Validate is a free data retrieval call binding the contract method 0x30d14888. +// Validate is a free data retrieval call binding the contract method 0xa9008b69. // -// Solidity: function validate((address,address,bytes32,uint256) _input, bool _allowFailure) view returns(string) +// Solidity: function validate((address,bytes32,uint256) _input, bool _allowFailure) view returns(string) func (_OPContractsManager *OPContractsManagerSession) Validate(_input OPContractsManagerStandardValidatorValidationInput, _allowFailure bool) (string, error) { return _OPContractsManager.Contract.Validate(&_OPContractsManager.CallOpts, _input, _allowFailure) } -// Validate is a free data retrieval call binding the contract method 0x30d14888. +// Validate is a free data retrieval call binding the contract method 0xa9008b69. // -// Solidity: function validate((address,address,bytes32,uint256) _input, bool _allowFailure) view returns(string) +// Solidity: function validate((address,bytes32,uint256) _input, bool _allowFailure) view returns(string) func (_OPContractsManager *OPContractsManagerCallerSession) Validate(_input OPContractsManagerStandardValidatorValidationInput, _allowFailure bool) (string, error) { return _OPContractsManager.Contract.Validate(&_OPContractsManager.CallOpts, _input, _allowFailure) } -// ValidateWithOverrides is a free data retrieval call binding the contract method 0x67cda69c. +// ValidateWithOverrides is a free data retrieval call binding the contract method 0xb806c805. // -// Solidity: function validateWithOverrides((address,address,bytes32,uint256) _input, bool _allowFailure, (address,address) _overrides) view returns(string) +// Solidity: function validateWithOverrides((address,bytes32,uint256) _input, bool _allowFailure, (address,address) _overrides) view returns(string) func (_OPContractsManager *OPContractsManagerCaller) ValidateWithOverrides(opts *bind.CallOpts, _input OPContractsManagerStandardValidatorValidationInput, _allowFailure bool, _overrides OPContractsManagerStandardValidatorValidationOverrides) (string, error) { var out []interface{} err := _OPContractsManager.contract.Call(opts, &out, "validateWithOverrides", _input, _allowFailure, _overrides) @@ -803,16 +807,16 @@ func (_OPContractsManager *OPContractsManagerCaller) ValidateWithOverrides(opts } -// ValidateWithOverrides is a free data retrieval call binding the contract method 0x67cda69c. +// ValidateWithOverrides is a free data retrieval call binding the contract method 0xb806c805. // -// Solidity: function validateWithOverrides((address,address,bytes32,uint256) _input, bool _allowFailure, (address,address) _overrides) view returns(string) +// Solidity: function validateWithOverrides((address,bytes32,uint256) _input, bool _allowFailure, (address,address) _overrides) view returns(string) func (_OPContractsManager *OPContractsManagerSession) ValidateWithOverrides(_input OPContractsManagerStandardValidatorValidationInput, _allowFailure bool, _overrides OPContractsManagerStandardValidatorValidationOverrides) (string, error) { return _OPContractsManager.Contract.ValidateWithOverrides(&_OPContractsManager.CallOpts, _input, _allowFailure, _overrides) } -// ValidateWithOverrides is a free data retrieval call binding the contract method 0x67cda69c. +// ValidateWithOverrides is a free data retrieval call binding the contract method 0xb806c805. // -// Solidity: function validateWithOverrides((address,address,bytes32,uint256) _input, bool _allowFailure, (address,address) _overrides) view returns(string) +// Solidity: function validateWithOverrides((address,bytes32,uint256) _input, bool _allowFailure, (address,address) _overrides) view returns(string) func (_OPContractsManager *OPContractsManagerCallerSession) ValidateWithOverrides(_input OPContractsManagerStandardValidatorValidationInput, _allowFailure bool, _overrides OPContractsManagerStandardValidatorValidationOverrides) (string, error) { return _OPContractsManager.Contract.ValidateWithOverrides(&_OPContractsManager.CallOpts, _input, _allowFailure, _overrides) } @@ -848,23 +852,23 @@ func (_OPContractsManager *OPContractsManagerCallerSession) Version() (string, e return _OPContractsManager.Contract.Version(&_OPContractsManager.CallOpts) } -// AddGameType is a paid mutator transaction binding the contract method 0x1661a2e9. +// AddGameType is a paid mutator transaction binding the contract method 0x604aa628. // -// Solidity: function addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[] _gameConfigs) returns((address,address)[]) +// Solidity: function addGameType((string,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[] _gameConfigs) returns((address,address)[]) func (_OPContractsManager *OPContractsManagerTransactor) AddGameType(opts *bind.TransactOpts, _gameConfigs []OPContractsManagerAddGameInput) (*types.Transaction, error) { return _OPContractsManager.contract.Transact(opts, "addGameType", _gameConfigs) } -// AddGameType is a paid mutator transaction binding the contract method 0x1661a2e9. +// AddGameType is a paid mutator transaction binding the contract method 0x604aa628. // -// Solidity: function addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[] _gameConfigs) returns((address,address)[]) +// Solidity: function addGameType((string,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[] _gameConfigs) returns((address,address)[]) func (_OPContractsManager *OPContractsManagerSession) AddGameType(_gameConfigs []OPContractsManagerAddGameInput) (*types.Transaction, error) { return _OPContractsManager.Contract.AddGameType(&_OPContractsManager.TransactOpts, _gameConfigs) } -// AddGameType is a paid mutator transaction binding the contract method 0x1661a2e9. +// AddGameType is a paid mutator transaction binding the contract method 0x604aa628. // -// Solidity: function addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[] _gameConfigs) returns((address,address)[]) +// Solidity: function addGameType((string,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[] _gameConfigs) returns((address,address)[]) func (_OPContractsManager *OPContractsManagerTransactorSession) AddGameType(_gameConfigs []OPContractsManagerAddGameInput) (*types.Transaction, error) { return _OPContractsManager.Contract.AddGameType(&_OPContractsManager.TransactOpts, _gameConfigs) } @@ -890,65 +894,86 @@ func (_OPContractsManager *OPContractsManagerTransactorSession) Deploy(_input OP return _OPContractsManager.Contract.Deploy(&_OPContractsManager.TransactOpts, _input) } -// Migrate is a paid mutator transaction binding the contract method 0x3fe13f3f. +// Migrate is a paid mutator transaction binding the contract method 0x6d510c5e. // -// Solidity: function migrate((bool,(bytes32,uint256),(address,address,uint256,uint256,uint256,uint64,uint64),(address,address,bytes32)[]) _input) returns() +// Solidity: function migrate((bool,(bytes32,uint256),(address,address,uint256,uint256,uint256,uint64,uint64),(address,bytes32)[]) _input) returns() func (_OPContractsManager *OPContractsManagerTransactor) Migrate(opts *bind.TransactOpts, _input OPContractsManagerInteropMigratorMigrateInput) (*types.Transaction, error) { return _OPContractsManager.contract.Transact(opts, "migrate", _input) } -// Migrate is a paid mutator transaction binding the contract method 0x3fe13f3f. +// Migrate is a paid mutator transaction binding the contract method 0x6d510c5e. // -// Solidity: function migrate((bool,(bytes32,uint256),(address,address,uint256,uint256,uint256,uint64,uint64),(address,address,bytes32)[]) _input) returns() +// Solidity: function migrate((bool,(bytes32,uint256),(address,address,uint256,uint256,uint256,uint64,uint64),(address,bytes32)[]) _input) returns() func (_OPContractsManager *OPContractsManagerSession) Migrate(_input OPContractsManagerInteropMigratorMigrateInput) (*types.Transaction, error) { return _OPContractsManager.Contract.Migrate(&_OPContractsManager.TransactOpts, _input) } -// Migrate is a paid mutator transaction binding the contract method 0x3fe13f3f. +// Migrate is a paid mutator transaction binding the contract method 0x6d510c5e. // -// Solidity: function migrate((bool,(bytes32,uint256),(address,address,uint256,uint256,uint256,uint64,uint64),(address,address,bytes32)[]) _input) returns() +// Solidity: function migrate((bool,(bytes32,uint256),(address,address,uint256,uint256,uint256,uint64,uint64),(address,bytes32)[]) _input) returns() func (_OPContractsManager *OPContractsManagerTransactorSession) Migrate(_input OPContractsManagerInteropMigratorMigrateInput) (*types.Transaction, error) { return _OPContractsManager.Contract.Migrate(&_OPContractsManager.TransactOpts, _input) } -// UpdatePrestate is a paid mutator transaction binding the contract method 0x9a72745b. +// UpdatePrestate is a paid mutator transaction binding the contract method 0xb23cc044. // -// Solidity: function updatePrestate((address,address,bytes32)[] _prestateUpdateInputs) returns() -func (_OPContractsManager *OPContractsManagerTransactor) UpdatePrestate(opts *bind.TransactOpts, _prestateUpdateInputs []OPContractsManagerOpChainConfig) (*types.Transaction, error) { +// Solidity: function updatePrestate((address,bytes32,bytes32)[] _prestateUpdateInputs) returns() +func (_OPContractsManager *OPContractsManagerTransactor) UpdatePrestate(opts *bind.TransactOpts, _prestateUpdateInputs []OPContractsManagerUpdatePrestateInput) (*types.Transaction, error) { return _OPContractsManager.contract.Transact(opts, "updatePrestate", _prestateUpdateInputs) } -// UpdatePrestate is a paid mutator transaction binding the contract method 0x9a72745b. +// UpdatePrestate is a paid mutator transaction binding the contract method 0xb23cc044. // -// Solidity: function updatePrestate((address,address,bytes32)[] _prestateUpdateInputs) returns() -func (_OPContractsManager *OPContractsManagerSession) UpdatePrestate(_prestateUpdateInputs []OPContractsManagerOpChainConfig) (*types.Transaction, error) { +// Solidity: function updatePrestate((address,bytes32,bytes32)[] _prestateUpdateInputs) returns() +func (_OPContractsManager *OPContractsManagerSession) UpdatePrestate(_prestateUpdateInputs []OPContractsManagerUpdatePrestateInput) (*types.Transaction, error) { return _OPContractsManager.Contract.UpdatePrestate(&_OPContractsManager.TransactOpts, _prestateUpdateInputs) } -// UpdatePrestate is a paid mutator transaction binding the contract method 0x9a72745b. +// UpdatePrestate is a paid mutator transaction binding the contract method 0xb23cc044. // -// Solidity: function updatePrestate((address,address,bytes32)[] _prestateUpdateInputs) returns() -func (_OPContractsManager *OPContractsManagerTransactorSession) UpdatePrestate(_prestateUpdateInputs []OPContractsManagerOpChainConfig) (*types.Transaction, error) { +// Solidity: function updatePrestate((address,bytes32,bytes32)[] _prestateUpdateInputs) returns() +func (_OPContractsManager *OPContractsManagerTransactorSession) UpdatePrestate(_prestateUpdateInputs []OPContractsManagerUpdatePrestateInput) (*types.Transaction, error) { return _OPContractsManager.Contract.UpdatePrestate(&_OPContractsManager.TransactOpts, _prestateUpdateInputs) } -// Upgrade is a paid mutator transaction binding the contract method 0xff2dd5a1. +// Upgrade is a paid mutator transaction binding the contract method 0x0b8bd7cb. // -// Solidity: function upgrade((address,address,bytes32)[] _opChainConfigs) returns() +// Solidity: function upgrade((address,bytes32)[] _opChainConfigs) returns() func (_OPContractsManager *OPContractsManagerTransactor) Upgrade(opts *bind.TransactOpts, _opChainConfigs []OPContractsManagerOpChainConfig) (*types.Transaction, error) { return _OPContractsManager.contract.Transact(opts, "upgrade", _opChainConfigs) } -// Upgrade is a paid mutator transaction binding the contract method 0xff2dd5a1. +// Upgrade is a paid mutator transaction binding the contract method 0x0b8bd7cb. // -// Solidity: function upgrade((address,address,bytes32)[] _opChainConfigs) returns() +// Solidity: function upgrade((address,bytes32)[] _opChainConfigs) returns() func (_OPContractsManager *OPContractsManagerSession) Upgrade(_opChainConfigs []OPContractsManagerOpChainConfig) (*types.Transaction, error) { return _OPContractsManager.Contract.Upgrade(&_OPContractsManager.TransactOpts, _opChainConfigs) } -// Upgrade is a paid mutator transaction binding the contract method 0xff2dd5a1. +// Upgrade is a paid mutator transaction binding the contract method 0x0b8bd7cb. // -// Solidity: function upgrade((address,address,bytes32)[] _opChainConfigs) returns() +// Solidity: function upgrade((address,bytes32)[] _opChainConfigs) returns() func (_OPContractsManager *OPContractsManagerTransactorSession) Upgrade(_opChainConfigs []OPContractsManagerOpChainConfig) (*types.Transaction, error) { return _OPContractsManager.Contract.Upgrade(&_OPContractsManager.TransactOpts, _opChainConfigs) } + +// UpgradeSuperchainConfig is a paid mutator transaction binding the contract method 0xb0b807eb. +// +// Solidity: function upgradeSuperchainConfig(address _superchainConfig, address _superchainProxyAdmin) returns() +func (_OPContractsManager *OPContractsManagerTransactor) UpgradeSuperchainConfig(opts *bind.TransactOpts, _superchainConfig common.Address, _superchainProxyAdmin common.Address) (*types.Transaction, error) { + return _OPContractsManager.contract.Transact(opts, "upgradeSuperchainConfig", _superchainConfig, _superchainProxyAdmin) +} + +// UpgradeSuperchainConfig is a paid mutator transaction binding the contract method 0xb0b807eb. +// +// Solidity: function upgradeSuperchainConfig(address _superchainConfig, address _superchainProxyAdmin) returns() +func (_OPContractsManager *OPContractsManagerSession) UpgradeSuperchainConfig(_superchainConfig common.Address, _superchainProxyAdmin common.Address) (*types.Transaction, error) { + return _OPContractsManager.Contract.UpgradeSuperchainConfig(&_OPContractsManager.TransactOpts, _superchainConfig, _superchainProxyAdmin) +} + +// UpgradeSuperchainConfig is a paid mutator transaction binding the contract method 0xb0b807eb. +// +// Solidity: function upgradeSuperchainConfig(address _superchainConfig, address _superchainProxyAdmin) returns() +func (_OPContractsManager *OPContractsManagerTransactorSession) UpgradeSuperchainConfig(_superchainConfig common.Address, _superchainProxyAdmin common.Address) (*types.Transaction, error) { + return _OPContractsManager.Contract.UpgradeSuperchainConfig(&_OPContractsManager.TransactOpts, _superchainConfig, _superchainProxyAdmin) +} From ff92c1835cd8bac891da8382c6bff4e0c7152bd0 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Tue, 7 Oct 2025 19:09:22 +0100 Subject: [PATCH 12/35] finally fix op-acceptance tests? --- op-devstack/sysgo/superroot.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/op-devstack/sysgo/superroot.go b/op-devstack/sysgo/superroot.go index d5c989cc52859..6be638e15fcba 100644 --- a/op-devstack/sysgo/superroot.go +++ b/op-devstack/sysgo/superroot.go @@ -175,6 +175,9 @@ func WithSuperRoots(l1ChainID eth.ChainID, l1ELID stack.L1ELNodeID, l2CLID stack delegateCallProxy, oldDisputeGameFactories, ) + + transferOwnershipForDelegateCallProxy(t, l1ChainID.ToBig(), l1PAOKey, client, delegateCallProxy, superchainProxyAdmin, oldSuperchainProxyAdminOwner) + superchainProxyAdminOwner := getOwner(t, w3Client, superchainProxyAdmin) t.Require().Equal(oldSuperchainProxyAdminOwner, superchainProxyAdminOwner, "superchain proxy admin owner is not the L1PAO") From 1418e55540b2ea3cd16be9549c2ce6a24638eb1f Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Wed, 8 Oct 2025 05:12:47 +0100 Subject: [PATCH 13/35] update block number in justfile and not do u16a upgrade on tests --- packages/contracts-bedrock/justfile | 4 +- .../test/L1/OPContractsManager.t.sol | 71 ++++--------------- .../test/setup/ForkLive.s.sol | 39 +++------- 3 files changed, 28 insertions(+), 86 deletions(-) diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index 08bbc114411be..74a2e9f213bad 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -62,8 +62,8 @@ test-dev *ARGS: build-go-ffi # Default block number for the forked upgrade path. -export sepoliaBlockNumber := "9118951" -export mainnetBlockNumber := "23327678" +export sepoliaBlockNumber := "9366100" +export mainnetBlockNumber := "23530400" export pinnedBlockNumber := if env_var_or_default("FORK_BASE_CHAIN", "") == "mainnet" { mainnetBlockNumber diff --git a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol index 7e1f06fe5c68c..3e4b3608a62f6 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol @@ -21,7 +21,6 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { GameType, Duration, Hash, Claim } from "src/dispute/lib/LibUDT.sol"; import { Proposal, GameTypes } from "src/dispute/lib/Types.sol"; import { DevFeatures } from "src/libraries/DevFeatures.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; // Interfaces import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; @@ -39,13 +38,9 @@ import { IOPContractsManager, IOPContractsManagerGameTypeAdder, IOPContractsManagerInteropMigrator, - IOPContractsManagerUpgrader, - IOPContractsManagerPre4_1_0 + IOPContractsManagerUpgrader } from "interfaces/L1/IOPContractsManager.sol"; -import { - IOPContractsManagerStandardValidator, - IOPContractsManagerStandardValidatorPreOPCM4_1_0 -} from "interfaces/L1/IOPContractsManagerStandardValidator.sol"; +import { IOPContractsManagerStandardValidator } from "interfaces/L1/IOPContractsManagerStandardValidator.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; import { ISuperFaultDisputeGame } from "interfaces/dispute/ISuperFaultDisputeGame.sol"; @@ -212,32 +207,15 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { bytes memory delegateCallerCode = address(_delegateCaller).code; vm.etch(_delegateCaller, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller")); - string memory OPCM_VERSION = _opcm.version(); - // Expect the revert if one is specified. if (_revertBytes.length > 0) { vm.expectRevert(_revertBytes); } // Execute the chain upgrade. - // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for - // both interface variants. - if (SemverComp.lt(OPCM_VERSION, "4.1.0")) { - IOPContractsManagerPre4_1_0.OpChainConfig[] memory opChains = - new IOPContractsManagerPre4_1_0.OpChainConfig[](1); - opChains[0] = IOPContractsManagerPre4_1_0.OpChainConfig({ - systemConfigProxy: systemConfig, - proxyAdmin: proxyAdmin, - absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) - }); - DelegateCaller(_delegateCaller).dcForward( - address(_opcm), abi.encodeCall(IOPContractsManagerPre4_1_0.upgrade, (opChains)) - ); - } else { - DelegateCaller(_delegateCaller).dcForward( - address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs)) - ); - } + DelegateCaller(_delegateCaller).dcForward( + address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs)) + ); // Return early if a revert was expected. Otherwise we'll get errors below. if (_revertBytes.length > 0) { @@ -269,8 +247,6 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { // try to apply to this function call instead. IOPContractsManagerStandardValidator validator = _opcm.opcmStandardValidator(); - string memory SV_VERSION = validator.version(); - // If the absolute prestate is zero, we will always get a PDDG-40,PLDG-40 error here in the // standard validator. This happens because an absolute prestate of zero means that the // user is requesting to use the existing prestate. We could avoid the error by grabbing @@ -281,28 +257,14 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { } // Run the StandardValidator checks. - // From StandardValidator version 1.19.0, the proxyAdmin was removed from the ValidationInput struct so we do - // create support for both variants. - if (SemverComp.lt(SV_VERSION, "1.19.0")) { - IOPContractsManagerStandardValidatorPreOPCM4_1_0(address(validator)).validate( - IOPContractsManagerStandardValidatorPreOPCM4_1_0.ValidationInput({ - proxyAdmin: opChainConfigs[0].systemConfigProxy.proxyAdmin(), - sysCfg: opChainConfigs[0].systemConfigProxy, - absolutePrestate: opChainConfigs[0].absolutePrestate.raw(), - l2ChainID: l2ChainId - }), - false - ); - } else { - validator.validate( - IOPContractsManagerStandardValidator.ValidationInput({ - sysCfg: opChainConfigs[0].systemConfigProxy, - absolutePrestate: opChainConfigs[0].absolutePrestate.raw(), - l2ChainID: l2ChainId - }), - false - ); - } + validator.validate( + IOPContractsManagerStandardValidator.ValidationInput({ + sysCfg: opChainConfigs[0].systemConfigProxy, + absolutePrestate: opChainConfigs[0].absolutePrestate.raw(), + l2ChainID: l2ChainId + }), + false + ); } /// @notice Executes all past upgrades that have not yet been executed on mainnet as of the @@ -311,14 +273,11 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { /// upgrades from this function once they've been executed on mainnet and the /// simulation block has been bumped beyond the execution block. /// @param _delegateCaller The address of the delegate caller to use for the upgrade. - function runPastUpgrades(address _delegateCaller) internal { + function runPastUpgrades(address _delegateCaller) internal view { // Run past upgrades depending on network. if (block.chainid == 1) { // Mainnet - // U16a - _runOpcmUpgradeAndChecks( - IOPContractsManager(0x8123739C1368C2DEDc8C564255bc417FEEeBFF9D), _delegateCaller, bytes("") - ); + _delegateCaller; } else { revert UnsupportedChainId(); } diff --git a/packages/contracts-bedrock/test/setup/ForkLive.s.sol b/packages/contracts-bedrock/test/setup/ForkLive.s.sol index 3378322212f16..dee2115c02936 100644 --- a/packages/contracts-bedrock/test/setup/ForkLive.s.sol +++ b/packages/contracts-bedrock/test/setup/ForkLive.s.sol @@ -17,7 +17,6 @@ import { Config } from "scripts/libraries/Config.sol"; import { GameTypes, Claim } from "src/dispute/lib/Types.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { LibString } from "@solady/utils/LibString.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; // Interfaces import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; @@ -28,7 +27,7 @@ import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; import { IAddressManager } from "interfaces/legacy/IAddressManager.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { IOPContractsManager, IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; @@ -199,7 +198,11 @@ contract ForkLive is Deployer, StdAssertions { /// @param _delegateCaller The address of the upgrader to use for the upgrade. function _doUpgrade(IOPContractsManager _opcm, address _delegateCaller) internal { ISystemConfig systemConfig = ISystemConfig(artifacts.mustGetAddress("SystemConfigProxy")); - IProxyAdmin proxyAdmin = IProxyAdmin(EIP1967Helper.getAdmin(address(systemConfig))); + IOPContractsManager.OpChainConfig[] memory opChains = new IOPContractsManager.OpChainConfig[](1); + opChains[0] = IOPContractsManager.OpChainConfig({ + systemConfigProxy: systemConfig, + absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) + }); // Turn the SuperchainPAO into a DelegateCaller so we can try to upgrade the // SuperchainConfig contract. @@ -234,29 +237,9 @@ contract ForkLive is Deployer, StdAssertions { vm.etch(_delegateCaller, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller")); // Upgrade the chain. - // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for - // both interface variants. - if (SemverComp.lt(_opcm.version(), "4.1.0")) { - IOPContractsManagerPre4_1_0.OpChainConfig[] memory opChains = - new IOPContractsManagerPre4_1_0.OpChainConfig[](1); - opChains[0] = IOPContractsManagerPre4_1_0.OpChainConfig({ - systemConfigProxy: systemConfig, - proxyAdmin: proxyAdmin, - absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) - }); - DelegateCaller(_delegateCaller).dcForward( - address(_opcm), abi.encodeCall(IOPContractsManagerPre4_1_0.upgrade, (opChains)) - ); - } else { - IOPContractsManager.OpChainConfig[] memory opChains = new IOPContractsManager.OpChainConfig[](1); - opChains[0] = IOPContractsManager.OpChainConfig({ - systemConfigProxy: systemConfig, - absolutePrestate: Claim.wrap(bytes32(keccak256("absolutePrestate"))) - }); - DelegateCaller(_delegateCaller).dcForward( - address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChains)) - ); - } + DelegateCaller(_delegateCaller).dcForward( + address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChains)) + ); // Reset the upgrader to the original code. vm.etch(_delegateCaller, upgraderCode); @@ -275,8 +258,8 @@ contract ForkLive is Deployer, StdAssertions { // Run past upgrades depending on network. if (block.chainid == 1) { // Mainnet - // U16a. - _doUpgrade(IOPContractsManager(0x8123739C1368C2DEDc8C564255bc417FEEeBFF9D), upgrader); + // This is empty because the block number in the justfile is after the most recent upgrade so there are no + // past upgrades to run. } else { revert UnsupportedChainId(); } From cee38f52e1b4ee9dea91c47f78c8ea69a2352d4e Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Wed, 8 Oct 2025 13:32:25 +0100 Subject: [PATCH 14/35] add upgradeSuperchainConfig pkg and add e2e bootstrap test for it upgrade in v5_0_0 pkg --- .../deployer/integration_test/apply_test.go | 98 +++++++++++++++++ .../pkg/deployer/upgrade/v5_0_0/upgrade.go | 56 ++++++++++ .../v5_0_0/upgrade_superchainconfig.go | 33 ++++++ .../deployer/upgrade/v5_0_0/upgrade_test.go | 38 +++++++ .../scripts/deploy/UpgradeOPChain.s.sol | 45 +++++--- .../deploy/UpgradeSuperchainConfig.s.sol | 93 ++++++++++++++++ .../test/opcm/UpgradeOPChain.t.sol | 41 +++---- .../test/opcm/UpgradeSuperchainConfig.t.sol | 100 ++++++++++++++++++ 8 files changed, 469 insertions(+), 35 deletions(-) create mode 100644 op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go create mode 100644 op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go create mode 100644 op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_test.go create mode 100644 packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol create mode 100644 packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index 390c37de14492..ca12aaaa31bd0 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -11,8 +11,11 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/bootstrap" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/inspect" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/integration_test/shared" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v5_0_0" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/env" "github.com/ethereum/go-ethereum/params" "github.com/ethereum-optimism/optimism/op-service/testutils" @@ -30,6 +33,7 @@ import ( "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rpc" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" @@ -143,6 +147,100 @@ func TestEndToEndBootstrapApply(t *testing.T) { }) } +func TestEndToEndBootstrapApplyWithUpgrade(t *testing.T) { + op_e2e.InitParallel(t) + + lgr := testlog.Logger(t, slog.LevelDebug) + forkedL1, stopL1, err := devnet.NewForkedSepolia(lgr) + pkHex, _, _ := shared.DefaultPrivkey(t) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, stopL1()) + }) + loc, afactsFS := testutil.LocalArtifacts(t) + ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second) + defer cancel() + testCacheDir := testutils.IsolatedTestDirWithAutoCleanup(t) + + superchain, err := standard.SuperchainFor(11155111) + require.NoError(t, err) + + superchainProxyAdmin, err := standard.SuperchainProxyAdminAddrFor(11155111) + require.NoError(t, err) + + superchainProxyAdminOwner, err := standard.L1ProxyAdminOwner(11155111) + require.NoError(t, err) + + impls, err := bootstrap.Implementations(ctx, bootstrap.ImplementationsConfig{ + L1RPCUrl: forkedL1.RPCUrl(), + PrivateKey: pkHex, + ArtifactsLocator: loc, + MIPSVersion: int(standard.MIPSVersion), + WithdrawalDelaySeconds: standard.WithdrawalDelaySeconds, + MinProposalSizeBytes: standard.MinProposalSizeBytes, + ChallengePeriodSeconds: standard.ChallengePeriodSeconds, + ProofMaturityDelaySeconds: standard.ProofMaturityDelaySeconds, + DisputeGameFinalityDelaySeconds: standard.DisputeGameFinalityDelaySeconds, + DevFeatureBitmap: common.Hash{}, + SuperchainConfigProxy: superchain.SuperchainConfigAddr, + ProtocolVersionsProxy: superchain.ProtocolVersionsAddr, + L1ProxyAdminOwner: superchainProxyAdminOwner, + SuperchainProxyAdmin: superchainProxyAdmin, + CacheDir: testCacheDir, + Logger: lgr, + Challenger: common.Address{'C'}, + }) + require.NoError(t, err) + + // Now test the OPCM upgrade using the deployed impls.Opcm + t.Run("opcm upgrade test", func(t *testing.T) { + // Create script host for the upgrade + rpcClient, err := rpc.Dial(forkedL1.RPCUrl()) + require.NoError(t, err) + + host, err := env.DefaultForkedScriptHost( + ctx, + broadcaster.NoopBroadcaster(), + lgr, + superchainProxyAdminOwner, + afactsFS, + rpcClient, + ) + require.NoError(t, err) + + // First run upgradeSuperchainConfig + t.Run("upgrade superchain config", func(t *testing.T) { + upgradeConfig := v5_0_0.UpgradeSuperchainConfigInput{ + Prank: superchainProxyAdminOwner, + Opcm: impls.Opcm, + SuperchainConfig: superchain.SuperchainConfigAddr, + SuperchainProxyAdmin: superchainProxyAdmin, + } + + err = v5_0_0.UpgradeSuperchainConfig(host, upgradeConfig) + require.NoError(t, err, "Superchain config upgrade should succeed") + }) + + // Then run the OPCM upgrade + t.Run("upgrade opcm", func(t *testing.T) { + upgradeConfig := v5_0_0.UpgradeOPChainInput{ + Prank: superchainProxyAdminOwner, + Opcm: impls.Opcm, + EncodedChainConfigs: []v5_0_0.OPChainConfig{ + { + SystemConfigProxy: common.HexToAddress("034edD2A225f7f429A63E0f1D2084B9E0A93b538"), + AbsolutePrestate: common.Hash{'A', 'P'}, + }, + }, + } + + // Test the upgrade + err = v5_0_0.Upgrade(host, upgradeConfig) + require.NoError(t, err, "OPCM upgrade should succeed") + }) + }) +} + func TestEndToEndApply(t *testing.T) { op_e2e.InitParallel(t) diff --git a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go new file mode 100644 index 0000000000000..0ef089451b1b6 --- /dev/null +++ b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go @@ -0,0 +1,56 @@ +package v5_0_0 + +import ( + "encoding/json" + "fmt" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" + "github.com/ethereum/go-ethereum/common" + "github.com/lmittmann/w3" +) + +type UpgradeOPChainInput struct { + Prank common.Address `json:"prank"` + Opcm common.Address `json:"opcm"` + EncodedChainConfigs []OPChainConfig `evm:"-" json:"chainConfigs"` +} + +type OPChainConfig struct { + SystemConfigProxy common.Address `json:"systemConfigProxy"` + AbsolutePrestate common.Hash `json:"absolutePrestate"` +} + +var opChainConfigEncoder = w3.MustNewFunc("dummy((address systemConfigProxy,bytes32 absolutePrestate)[])", "") + +func (u *UpgradeOPChainInput) OpChainConfigs() ([]byte, error) { + data, err := opChainConfigEncoder.EncodeArgs(u.EncodedChainConfigs) + if err != nil { + return nil, fmt.Errorf("failed to encode chain configs: %w", err) + } + return data[4:], nil +} + +type UpgradeOPChain struct { + Run func(input common.Address) +} + +func Upgrade(host *script.Host, input UpgradeOPChainInput) error { + return opcm.RunScriptVoid[UpgradeOPChainInput](host, input, "UpgradeOPChain.s.sol", "UpgradeOPChain") +} + +type Upgrader struct{} + +func (u *Upgrader) Upgrade(host *script.Host, input json.RawMessage) error { + var upgradeInput UpgradeOPChainInput + if err := json.Unmarshal(input, &upgradeInput); err != nil { + return fmt.Errorf("failed to unmarshal input: %w", err) + } + return Upgrade(host, upgradeInput) +} + +func (u *Upgrader) ArtifactsURL() string { + return "tag://" + "op-contracts/v5.0.0" +} + +var DefaultUpgrader = new(Upgrader) diff --git a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go new file mode 100644 index 0000000000000..c8f4926cd4f4b --- /dev/null +++ b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go @@ -0,0 +1,33 @@ +package v5_0_0 + +import ( + "encoding/json" + "fmt" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" + "github.com/ethereum/go-ethereum/common" +) + +type UpgradeSuperchainConfigInput struct { + Prank common.Address `json:"prank"` + Opcm common.Address `json:"opcm"` + SuperchainConfig common.Address `json:"superchainConfig"` + SuperchainProxyAdmin common.Address `json:"superchainProxyAdmin"` +} + +type UpgradeSuperchainConfigScript struct { + Run func(input common.Address) +} + +func UpgradeSuperchainConfig(host *script.Host, input UpgradeSuperchainConfigInput) error { + return opcm.RunScriptVoid[UpgradeSuperchainConfigInput](host, input, "UpgradeSuperchainConfig.s.sol", "UpgradeSuperchainConfig") +} + +func (u *Upgrader) UpgradeSuperchainConfig(host *script.Host, input json.RawMessage) error { + var upgradeInput UpgradeSuperchainConfigInput + if err := json.Unmarshal(input, &upgradeInput); err != nil { + return fmt.Errorf("failed to unmarshal input: %w", err) + } + return UpgradeSuperchainConfig(host, upgradeInput) +} diff --git a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_test.go b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_test.go new file mode 100644 index 0000000000000..7e6b8b483d1c0 --- /dev/null +++ b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_test.go @@ -0,0 +1,38 @@ +package v5_0_0 + +import ( + "encoding/hex" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestUpgradeOPChainInput_OpChainConfigs(t *testing.T) { + input := &UpgradeOPChainInput{ + Prank: common.Address{0xaa}, + Opcm: common.Address{0xbb}, + EncodedChainConfigs: []OPChainConfig{ + { + SystemConfigProxy: common.Address{0x01}, + AbsolutePrestate: common.Hash{0x03}, + }, + { + SystemConfigProxy: common.Address{0x04}, + AbsolutePrestate: common.Hash{0x06}, + }, + }, + } + data, err := input.OpChainConfigs() + require.NoError(t, err) + require.Equal( + t, + "0000000000000000000000000000000000000000000000000000000000000020"+ + "0000000000000000000000000000000000000000000000000000000000000002"+ + "0000000000000000000000000100000000000000000000000000000000000000"+ + "0300000000000000000000000000000000000000000000000000000000000000"+ + "0000000000000000000000000400000000000000000000000000000000000000"+ + "0600000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(data), + ) +} diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index 42e52c7382c24..7ced2e14bf199 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -2,14 +2,13 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; -import { OPContractsManager } from "src/L1/OPContractsManager.sol"; -import { IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManager, IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; import { SemverComp } from "src/libraries/SemverComp.sol"; contract UpgradeOPChainInput is BaseDeployIO { address internal _prank; - OPContractsManager internal _opcm; + IOPContractsManager internal _opcm; bytes _opChainConfigs; // Setter for OPContractsManager type @@ -17,14 +16,14 @@ contract UpgradeOPChainInput is BaseDeployIO { require(address(_value) != address(0), "UpgradeOPCMInput: cannot set zero address"); if (_sel == this.prank.selector) _prank = _value; - else if (_sel == this.opcm.selector) _opcm = OPContractsManager(_value); + else if (_sel == this.opcm.selector) _opcm = IOPContractsManager(_value); else revert("UpgradeOPCMInput: unknown selector"); } - function set(bytes4 _sel, OPContractsManager.OpChainConfig[] memory _value) public { + function set(bytes4 _sel, bytes memory _value) public { require(_value.length > 0, "UpgradeOPCMInput: cannot set empty array"); - if (_sel == this.opChainConfigs.selector) _opChainConfigs = abi.encode(_value); + if (_sel == this.opChainConfigs.selector) _opChainConfigs = _value; else revert("UpgradeOPCMInput: unknown selector"); } @@ -33,20 +32,33 @@ contract UpgradeOPChainInput is BaseDeployIO { return _prank; } - function opcm() public view returns (OPContractsManager) { - require(address(_opcm) != address(0), "UpgradeOPCMInput: not set"); + function opcm() public view returns (IOPContractsManager) { + require(address(_opcm) != address(0), "UpgradeOPCMInput: opcm not set"); return _opcm; } function opChainConfigs() public view returns (bytes memory) { - require(_opChainConfigs.length > 0, "UpgradeOPCMInput: not set"); + require(_opChainConfigs.length > 0, "UpgradeOPCMInput: opChainConfigs not set"); + // apart from the offset and length that take up 64 bytes, the rest should be a multiple of 64 bytes + // (systemConfigProxy and absolutePrestate) + require((_opChainConfigs.length - 64) % 64 == 0, "UpgradeOPCMInput: opChainConfigs Unexpected length"); + + return _opChainConfigs; + } + + function opChainConfigsPre4_1_0() public view returns (bytes memory) { + require(_opChainConfigs.length > 0, "UpgradeOPCMInput: opChainConfigsPre4_1_0 not set"); + // apart from the offset and length that take up 64 bytes, the rest should be a multiple of 96 bytes + // (systemConfigProxy, proxyAdmin and absolutePrestate) + require((_opChainConfigs.length - 64) % 96 == 0, "UpgradeOPCMInput: opChainConfigsPre4_1_0 Unexpected length"); + return _opChainConfigs; } } contract UpgradeOPChain is Script { function run(UpgradeOPChainInput _uoci) external { - OPContractsManager opcm = _uoci.opcm(); + IOPContractsManager opcm = _uoci.opcm(); // Etch DummyCaller contract. This contract is used to mimic the contract that is used // as the source of the delegatecall to the OPCM. In practice this will be the governance @@ -63,13 +75,13 @@ contract UpgradeOPChain is Script { vm.label(prank, "DummyCaller"); IOPContractsManagerPre4_1_0.OpChainConfig[] memory opChainConfigs = - abi.decode(_uoci.opChainConfigs(), (IOPContractsManagerPre4_1_0.OpChainConfig[])); + abi.decode(_uoci.opChainConfigsPre4_1_0(), (IOPContractsManagerPre4_1_0.OpChainConfig[])); // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); (bool success,) = DummyCallerPreOPCM4_1_0(prank).upgrade(opChainConfigs); - require(success, "UpgradeOPChain: upgrade failed"); + require(success, "UpgradeOPChainPre4_1_0: upgrade failed"); } else { bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCaller"); vm.etch(prank, code); @@ -77,8 +89,8 @@ contract UpgradeOPChain is Script { vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); vm.label(prank, "DummyCaller"); - OPContractsManager.OpChainConfig[] memory opChainConfigs = - abi.decode(_uoci.opChainConfigs(), (OPContractsManager.OpChainConfig[])); + IOPContractsManager.OpChainConfig[] memory opChainConfigs = + abi.decode(_uoci.opChainConfigs(), (IOPContractsManager.OpChainConfig[])); // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); @@ -95,7 +107,10 @@ contract UpgradeOPChain is Script { contract DummyCaller { address internal _opcmAddr; - function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs) external returns (bool, bytes memory) { + function upgrade(IOPContractsManager.OpChainConfig[] memory _opChainConfigs) + external + returns (bool, bytes memory) + { bytes memory data = abi.encodeCall(DummyCaller.upgrade, _opChainConfigs); (bool success, bytes memory result) = _opcmAddr.delegatecall(data); return (success, result); diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol new file mode 100644 index 0000000000000..c1a3f4dbf6964 --- /dev/null +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Script } from "forge-std/Script.sol"; +import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; +import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; +import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; +import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; + +contract UpgradeSuperchainConfigInput is BaseDeployIO { + address internal _prank; + IOPContractsManager internal _opcm; + ISuperchainConfig internal _superchainConfig; + IProxyAdmin internal _superchainProxyAdmin; + + // Setter for OPContractsManager type + function set(bytes4 _sel, address _value) public { + require(address(_value) != address(0), "UpgradeSuperchainConfigInput: cannot set zero address"); + + if (_sel == this.prank.selector) _prank = _value; + else if (_sel == this.opcm.selector) _opcm = IOPContractsManager(_value); + else if (_sel == this.superchainConfig.selector) _superchainConfig = ISuperchainConfig(_value); + else if (_sel == this.superchainProxyAdmin.selector) _superchainProxyAdmin = IProxyAdmin(_value); + else revert("UpgradeSuperchainConfigInput: unknown selector"); + } + + function prank() public view returns (address) { + require(address(_prank) != address(0), "UpgradeSuperchainConfigInput: prank not set"); + return _prank; + } + + function opcm() public view returns (IOPContractsManager) { + require(address(_opcm) != address(0), "UpgradeSuperchainConfigInput: opcm not set"); + return _opcm; + } + + function superchainConfig() public view returns (ISuperchainConfig) { + require(address(_superchainConfig) != address(0), "UpgradeSuperchainConfigInput: superchainConfig not set"); + return _superchainConfig; + } + + function superchainProxyAdmin() public view returns (IProxyAdmin) { + require( + address(_superchainProxyAdmin) != address(0), "UpgradeSuperchainConfigInput: superchainProxyAdmin not set" + ); + return _superchainProxyAdmin; + } +} + +contract UpgradeSuperchainConfig is Script { + function run(UpgradeSuperchainConfigInput _uoci) external { + IOPContractsManager opcm = _uoci.opcm(); + + // Etch DummyCaller contract. This contract is used to mimic the contract that is used + // as the source of the delegatecall to the OPCM. In practice this will be the governance + // 2/2 or similar. + address prank = _uoci.prank(); + + bytes memory code = vm.getDeployedCode("UpgradeSuperchainConfig.s.sol:DummyCaller"); + vm.etch(prank, code); + + vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); + vm.label(prank, "DummyCaller"); + + ISuperchainConfig superchainConfig = _uoci.superchainConfig(); + IProxyAdmin superchainProxyAdmin = _uoci.superchainProxyAdmin(); + + // Call into the DummyCaller to perform the delegatecall + vm.broadcast(msg.sender); + + (bool success,) = DummyCaller(prank).upgradeSuperchainConfig(superchainConfig, superchainProxyAdmin); + require(success, "UpgradeSuperchainConfig: upgradeSuperchainConfig failed"); + } +} + +/// @title DummyCaller +/// @notice This contract is used to mimic the contract that is used as the source of the delegatecall to the OPCM. +contract DummyCaller { + address internal _opcmAddr; + + function upgradeSuperchainConfig( + ISuperchainConfig _superchainConfig, + IProxyAdmin _superchainProxyAdmin + ) + external + returns (bool, bytes memory) + { + bytes memory data = + abi.encodeCall(DummyCaller.upgradeSuperchainConfig, (_superchainConfig, _superchainProxyAdmin)); + (bool success, bytes memory result) = _opcmAddr.delegatecall(data); + return (success, result); + } +} diff --git a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol index dce5d4446ef5e..696a9907e9f64 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol @@ -6,7 +6,7 @@ import { Claim } from "src/dispute/lib/Types.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { OPContractsManager } from "src/L1/OPContractsManager.sol"; +import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { UpgradeOPChain, UpgradeOPChainInput } from "scripts/deploy/UpgradeOPChain.s.sol"; contract UpgradeOPChainInput_Test is Test { @@ -20,11 +20,14 @@ contract UpgradeOPChainInput_Test is Test { vm.expectRevert("UpgradeOPCMInput: prank not set"); input.prank(); - vm.expectRevert("UpgradeOPCMInput: not set"); + vm.expectRevert("UpgradeOPCMInput: opcm not set"); input.opcm(); - vm.expectRevert("UpgradeOPCMInput: not set"); + vm.expectRevert("UpgradeOPCMInput: opChainConfigs not set"); input.opChainConfigs(); + + vm.expectRevert("UpgradeOPCMInput: opChainConfigsPre4_1_0 not set"); + input.opChainConfigsPre4_1_0(); } function test_setAddress_succeeds() public { @@ -43,7 +46,7 @@ contract UpgradeOPChainInput_Test is Test { function test_setOpChainConfigs_succeeds() public { // Create sample OpChainConfig array - OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](2); + IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](2); // Setup mock addresses and contracts for first config address systemConfig1 = makeAddr("systemConfig1"); @@ -51,7 +54,7 @@ contract UpgradeOPChainInput_Test is Test { vm.etch(systemConfig1, hex"01"); vm.etch(proxyAdmin1, hex"01"); - configs[0] = OPContractsManager.OpChainConfig({ + configs[0] = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(systemConfig1), absolutePrestate: Claim.wrap(bytes32(uint256(1))) }); @@ -62,19 +65,19 @@ contract UpgradeOPChainInput_Test is Test { vm.etch(systemConfig2, hex"01"); vm.etch(proxyAdmin2, hex"01"); - configs[1] = OPContractsManager.OpChainConfig({ + configs[1] = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(systemConfig2), absolutePrestate: Claim.wrap(bytes32(uint256(2))) }); - input.set(input.opChainConfigs.selector, configs); + input.set(input.opChainConfigs.selector, abi.encode(configs)); bytes memory storedConfigs = input.opChainConfigs(); assertEq(storedConfigs, abi.encode(configs)); // Additional verification of stored claims if needed - OPContractsManager.OpChainConfig[] memory decodedConfigs = - abi.decode(storedConfigs, (OPContractsManager.OpChainConfig[])); + IOPContractsManager.OpChainConfig[] memory decodedConfigs = + abi.decode(storedConfigs, (IOPContractsManager.OpChainConfig[])); assertEq(Claim.unwrap(decodedConfigs[0].absolutePrestate), bytes32(uint256(1))); assertEq(Claim.unwrap(decodedConfigs[1].absolutePrestate), bytes32(uint256(2))); } @@ -88,10 +91,8 @@ contract UpgradeOPChainInput_Test is Test { } function test_setOpChainConfigs_withEmptyArray_reverts() public { - OPContractsManager.OpChainConfig[] memory emptyConfigs = new OPContractsManager.OpChainConfig[](0); - vm.expectRevert("UpgradeOPCMInput: cannot set empty array"); - input.set(input.opChainConfigs.selector, emptyConfigs); + input.set(input.opChainConfigs.selector, new bytes(0)); } function test_set_withInvalidSelector_reverts() public { @@ -99,26 +100,26 @@ contract UpgradeOPChainInput_Test is Test { input.set(bytes4(0xdeadbeef), makeAddr("test")); // Create a single config for testing invalid selector - OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](1); + IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](1); address mockSystemConfig = makeAddr("systemConfig"); address mockProxyAdmin = makeAddr("proxyAdmin"); vm.etch(mockSystemConfig, hex"01"); vm.etch(mockProxyAdmin, hex"01"); - configs[0] = OPContractsManager.OpChainConfig({ + configs[0] = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(mockSystemConfig), absolutePrestate: Claim.wrap(bytes32(uint256(1))) }); vm.expectRevert("UpgradeOPCMInput: unknown selector"); - input.set(bytes4(0xdeadbeef), configs); + input.set(bytes4(0xdeadbeef), abi.encode(configs)); } } contract MockOPCM { event UpgradeCalled(address indexed sysCfgProxy, bytes32 indexed absolutePrestate); - function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs) public { + function upgrade(IOPContractsManager.OpChainConfig[] memory _opChainConfigs) public { emit UpgradeCalled( address(_opChainConfigs[0].systemConfigProxy), Claim.unwrap(_opChainConfigs[0].absolutePrestate) ); @@ -132,7 +133,7 @@ contract MockOPCM { contract UpgradeOPChain_Test is Test { MockOPCM mockOPCM; UpgradeOPChainInput uoci; - OPContractsManager.OpChainConfig config; + IOPContractsManager.OpChainConfig config; UpgradeOPChain upgradeOPChain; address prank; @@ -142,13 +143,13 @@ contract UpgradeOPChain_Test is Test { mockOPCM = new MockOPCM(); uoci = new UpgradeOPChainInput(); uoci.set(uoci.opcm.selector, address(mockOPCM)); - config = OPContractsManager.OpChainConfig({ + config = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(makeAddr("systemConfigProxy")), absolutePrestate: Claim.wrap(keccak256("absolutePrestate")) }); - OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](1); + IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](1); configs[0] = config; - uoci.set(uoci.opChainConfigs.selector, configs); + uoci.set(uoci.opChainConfigs.selector, abi.encode(configs)); prank = makeAddr("prank"); uoci.set(uoci.prank.selector, prank); upgradeOPChain = new UpgradeOPChain(); diff --git a/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol new file mode 100644 index 0000000000000..76ab1b522b9c5 --- /dev/null +++ b/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test } from "forge-std/Test.sol"; + +import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; +import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; + +import { UpgradeSuperchainConfig, UpgradeSuperchainConfigInput } from "scripts/deploy/UpgradeSuperchainConfig.s.sol"; + +contract UpgradeSuperchainConfigInput_Test is Test { + UpgradeSuperchainConfigInput input; + + function setUp() public { + input = new UpgradeSuperchainConfigInput(); + } + + function test_getters_whenNotSet_reverts() public { + vm.expectRevert("UpgradeSuperchainConfigInput: prank not set"); + input.prank(); + + vm.expectRevert("UpgradeSuperchainConfigInput: opcm not set"); + input.opcm(); + + vm.expectRevert("UpgradeSuperchainConfigInput: superchainConfig not set"); + input.superchainConfig(); + + vm.expectRevert("UpgradeSuperchainConfigInput: superchainProxyAdmin not set"); + input.superchainProxyAdmin(); + } + + function test_setAddress_succeeds() public { + address mockPrank = makeAddr("prank"); + address mockOPCM = makeAddr("opcm"); + + // Create mock contract at OPCM address + vm.etch(mockOPCM, hex"01"); + + input.set(input.prank.selector, mockPrank); + input.set(input.opcm.selector, mockOPCM); + + assertEq(input.prank(), mockPrank); + assertEq(address(input.opcm()), mockOPCM); + } + + function test_setAddress_withZeroAddress_reverts() public { + vm.expectRevert("UpgradeSuperchainConfigInput: cannot set zero address"); + input.set(input.prank.selector, address(0)); + + vm.expectRevert("UpgradeSuperchainConfigInput: cannot set zero address"); + input.set(input.opcm.selector, address(0)); + } + + function test_set_withInvalidSelector_reverts() public { + vm.expectRevert("UpgradeSuperchainConfigInput: unknown selector"); + input.set(bytes4(0xdeadbeef), makeAddr("test")); + } +} + +contract MockOPCM { + event UpgradeCalled(address indexed superchainConfig, address indexed superchainProxyAdmin); + + function upgradeSuperchainConfig(ISuperchainConfig _superchainConfig, IProxyAdmin _superchainProxyAdmin) public { + emit UpgradeCalled(address(_superchainConfig), address(_superchainProxyAdmin)); + } +} + +contract UpgradeSuperchainConfig_Test is Test { + MockOPCM mockOPCM; + UpgradeSuperchainConfigInput uoci; + UpgradeSuperchainConfig upgradeSuperchainConfig; + address prank; + ISuperchainConfig superchainConfig; + IProxyAdmin superchainProxyAdmin; + + event UpgradeCalled(address indexed superchainConfig, address indexed superchainProxyAdmin); + + function setUp() public virtual { + mockOPCM = new MockOPCM(); + uoci = new UpgradeSuperchainConfigInput(); + uoci.set(uoci.opcm.selector, address(mockOPCM)); + + superchainConfig = ISuperchainConfig(makeAddr("superchainConfig")); + superchainProxyAdmin = IProxyAdmin(makeAddr("superchainProxyAdmin")); + prank = makeAddr("prank"); + + uoci.set(uoci.superchainConfig.selector, address(superchainConfig)); + uoci.set(uoci.superchainProxyAdmin.selector, address(superchainProxyAdmin)); + uoci.set(uoci.prank.selector, prank); + + upgradeSuperchainConfig = new UpgradeSuperchainConfig(); + } + + function test_upgrade_succeeds() public { + // UpgradeCalled should be emitted by the prank since it's a delegate call. + vm.expectEmit(address(prank)); + emit UpgradeCalled(address(superchainConfig), address(superchainProxyAdmin)); + upgradeSuperchainConfig.run(uoci); + } +} From db0b47d513dcbf7899a17b0cf47625451f2a3ddb Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Wed, 8 Oct 2025 15:54:38 +0100 Subject: [PATCH 15/35] fix failing upgrade go test, add more upgradeOPChain solidity test --- .../scripts/deploy/UpgradeOPChain.s.sol | 48 +++++++------ .../test/opcm/UpgradeOPChain.t.sol | 69 +++++++++++++++---- 2 files changed, 80 insertions(+), 37 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index 7ced2e14bf199..c1544eaac5002 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -13,44 +13,32 @@ contract UpgradeOPChainInput is BaseDeployIO { // Setter for OPContractsManager type function set(bytes4 _sel, address _value) public { - require(address(_value) != address(0), "UpgradeOPCMInput: cannot set zero address"); + require(address(_value) != address(0), "UpgradeOPChainInput: cannot set zero address"); if (_sel == this.prank.selector) _prank = _value; else if (_sel == this.opcm.selector) _opcm = IOPContractsManager(_value); - else revert("UpgradeOPCMInput: unknown selector"); + else revert("UpgradeOPChainInput: unknown selector"); } function set(bytes4 _sel, bytes memory _value) public { - require(_value.length > 0, "UpgradeOPCMInput: cannot set empty array"); + require(_value.length > 0, "UpgradeOPChainInput: cannot set empty array"); if (_sel == this.opChainConfigs.selector) _opChainConfigs = _value; - else revert("UpgradeOPCMInput: unknown selector"); + else revert("UpgradeOPChainInput: unknown selector"); } function prank() public view returns (address) { - require(address(_prank) != address(0), "UpgradeOPCMInput: prank not set"); + require(address(_prank) != address(0), "UpgradeOPChainInput: prank not set"); return _prank; } function opcm() public view returns (IOPContractsManager) { - require(address(_opcm) != address(0), "UpgradeOPCMInput: opcm not set"); + require(address(_opcm) != address(0), "UpgradeOPChainInput: opcm not set"); return _opcm; } function opChainConfigs() public view returns (bytes memory) { - require(_opChainConfigs.length > 0, "UpgradeOPCMInput: opChainConfigs not set"); - // apart from the offset and length that take up 64 bytes, the rest should be a multiple of 64 bytes - // (systemConfigProxy and absolutePrestate) - require((_opChainConfigs.length - 64) % 64 == 0, "UpgradeOPCMInput: opChainConfigs Unexpected length"); - - return _opChainConfigs; - } - - function opChainConfigsPre4_1_0() public view returns (bytes memory) { - require(_opChainConfigs.length > 0, "UpgradeOPCMInput: opChainConfigsPre4_1_0 not set"); - // apart from the offset and length that take up 64 bytes, the rest should be a multiple of 96 bytes - // (systemConfigProxy, proxyAdmin and absolutePrestate) - require((_opChainConfigs.length - 64) % 96 == 0, "UpgradeOPCMInput: opChainConfigsPre4_1_0 Unexpected length"); + require(_opChainConfigs.length > 0, "UpgradeOPChainInput: opChainConfigs not set"); return _opChainConfigs; } @@ -74,14 +62,22 @@ contract UpgradeOPChain is Script { vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); vm.label(prank, "DummyCaller"); + bytes memory encoded = _uoci.opChainConfigs(); IOPContractsManagerPre4_1_0.OpChainConfig[] memory opChainConfigs = - abi.decode(_uoci.opChainConfigsPre4_1_0(), (IOPContractsManagerPre4_1_0.OpChainConfig[])); + abi.decode(encoded, (IOPContractsManagerPre4_1_0.OpChainConfig[])); + + // apart from the offset and length that take up 64 bytes, the rest should be a multiple of 96 bytes + // (systemConfigProxy, proxyAdmin and absolutePrestate) + require( + (((encoded.length - 64) / 96) == opChainConfigs.length) && (((encoded.length - 64) % 96) == 0), + "UpgradeOPChain: opChainConfigsPre410 Unexpected encoding" + ); // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); (bool success,) = DummyCallerPreOPCM4_1_0(prank).upgrade(opChainConfigs); - require(success, "UpgradeOPChainPre4_1_0: upgrade failed"); + require(success, "UpgradeOPChain: Pre4_1_0 upgrade failed"); } else { bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCaller"); vm.etch(prank, code); @@ -89,8 +85,16 @@ contract UpgradeOPChain is Script { vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); vm.label(prank, "DummyCaller"); + bytes memory encoded = _uoci.opChainConfigs(); IOPContractsManager.OpChainConfig[] memory opChainConfigs = - abi.decode(_uoci.opChainConfigs(), (IOPContractsManager.OpChainConfig[])); + abi.decode(encoded, (IOPContractsManager.OpChainConfig[])); + + // apart from the offset and length that take up 64 bytes, the rest should be a multiple of 64 bytes + // (systemConfigProxy and absolutePrestate) + require( + ((encoded.length - 64) / 64 == opChainConfigs.length) && (((encoded.length - 64) % 64) == 0), + "UpgradeOPChain: opChainConfigs Unexpected encoding" + ); // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); diff --git a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol index 696a9907e9f64..df52f8107cfb9 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol @@ -5,8 +5,9 @@ import { Test } from "forge-std/Test.sol"; import { Claim } from "src/dispute/lib/Types.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; +import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManager, IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; import { UpgradeOPChain, UpgradeOPChainInput } from "scripts/deploy/UpgradeOPChain.s.sol"; contract UpgradeOPChainInput_Test is Test { @@ -17,17 +18,14 @@ contract UpgradeOPChainInput_Test is Test { } function test_getters_whenNotSet_reverts() public { - vm.expectRevert("UpgradeOPCMInput: prank not set"); + vm.expectRevert("UpgradeOPChainInput: prank not set"); input.prank(); - vm.expectRevert("UpgradeOPCMInput: opcm not set"); + vm.expectRevert("UpgradeOPChainInput: opcm not set"); input.opcm(); - vm.expectRevert("UpgradeOPCMInput: opChainConfigs not set"); + vm.expectRevert("UpgradeOPChainInput: opChainConfigs not set"); input.opChainConfigs(); - - vm.expectRevert("UpgradeOPCMInput: opChainConfigsPre4_1_0 not set"); - input.opChainConfigsPre4_1_0(); } function test_setAddress_succeeds() public { @@ -83,20 +81,20 @@ contract UpgradeOPChainInput_Test is Test { } function test_setAddress_withZeroAddress_reverts() public { - vm.expectRevert("UpgradeOPCMInput: cannot set zero address"); + vm.expectRevert("UpgradeOPChainInput: cannot set zero address"); input.set(input.prank.selector, address(0)); - vm.expectRevert("UpgradeOPCMInput: cannot set zero address"); + vm.expectRevert("UpgradeOPChainInput: cannot set zero address"); input.set(input.opcm.selector, address(0)); } function test_setOpChainConfigs_withEmptyArray_reverts() public { - vm.expectRevert("UpgradeOPCMInput: cannot set empty array"); + vm.expectRevert("UpgradeOPChainInput: cannot set empty array"); input.set(input.opChainConfigs.selector, new bytes(0)); } function test_set_withInvalidSelector_reverts() public { - vm.expectRevert("UpgradeOPCMInput: unknown selector"); + vm.expectRevert("UpgradeOPChainInput: unknown selector"); input.set(bytes4(0xdeadbeef), makeAddr("test")); // Create a single config for testing invalid selector @@ -111,7 +109,7 @@ contract UpgradeOPChainInput_Test is Test { absolutePrestate: Claim.wrap(bytes32(uint256(1))) }); - vm.expectRevert("UpgradeOPCMInput: unknown selector"); + vm.expectRevert("UpgradeOPChainInput: unknown selector"); input.set(bytes4(0xdeadbeef), abi.encode(configs)); } } @@ -130,19 +128,36 @@ contract MockOPCM { } } +contract MockOPCMPre410 { + event UpgradeCalled(address indexed sysCfgProxy, address indexed proxyAdmin, bytes32 indexed absolutePrestate); + + function upgrade(IOPContractsManagerPre4_1_0.OpChainConfig[] memory _opChainConfigs) public { + emit UpgradeCalled( + address(_opChainConfigs[0].systemConfigProxy), + address(_opChainConfigs[0].proxyAdmin), + Claim.unwrap(_opChainConfigs[0].absolutePrestate) + ); + } + + function version() public pure returns (string memory) { + return "4.0.0"; + } +} + contract UpgradeOPChain_Test is Test { - MockOPCM mockOPCM; + address mockOPCM; UpgradeOPChainInput uoci; IOPContractsManager.OpChainConfig config; UpgradeOPChain upgradeOPChain; address prank; event UpgradeCalled(address indexed sysCfgProxy, bytes32 indexed absolutePrestate); + event UpgradeCalled(address indexed sysCfgProxy, address indexed proxyAdmin, bytes32 indexed absolutePrestate); function setUp() public virtual { - mockOPCM = new MockOPCM(); + mockOPCM = address(new MockOPCM()); uoci = new UpgradeOPChainInput(); - uoci.set(uoci.opcm.selector, address(mockOPCM)); + uoci.set(uoci.opcm.selector, mockOPCM); config = IOPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(makeAddr("systemConfigProxy")), absolutePrestate: Claim.wrap(keccak256("absolutePrestate")) @@ -156,9 +171,33 @@ contract UpgradeOPChain_Test is Test { } function test_upgrade_succeeds() public { + // For opcm >= 4.1.0 // UpgradeCalled should be emitted by the prank since it's a delegate call. vm.expectEmit(address(prank)); emit UpgradeCalled(address(config.systemConfigProxy), Claim.unwrap(config.absolutePrestate)); upgradeOPChain.run(uoci); + + // For opcm < 4.1.0 + IOPContractsManagerPre4_1_0.OpChainConfig memory configPre410 = IOPContractsManagerPre4_1_0.OpChainConfig({ + systemConfigProxy: ISystemConfig(makeAddr("systemConfigProxy")), + proxyAdmin: IProxyAdmin(makeAddr("proxyAdmin")), + absolutePrestate: Claim.wrap(keccak256("absolutePrestate")) + }); + IOPContractsManagerPre4_1_0.OpChainConfig[] memory configsPre410 = + new IOPContractsManagerPre4_1_0.OpChainConfig[](1); + configsPre410[0] = configPre410; + uoci.set(uoci.opChainConfigs.selector, abi.encode(configsPre410)); + mockOPCM = address(new MockOPCMPre410()); + uoci.set(uoci.opcm.selector, mockOPCM); + // UpgradeCalled should be emitted by the prank since it's a delegate call. + vm.expectEmit(address(prank)); + emit UpgradeCalled( + address(configPre410.systemConfigProxy), + address(configPre410.proxyAdmin), + Claim.unwrap(configPre410.absolutePrestate) + ); + upgradeOPChain.run(uoci); } + + function test_upgrade_unexpectedEncoding_reverts() public { } } From 3935cc70fce21c1ef2fffe7f4d53ffd6d7e5dfbd Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Wed, 8 Oct 2025 16:45:37 +0100 Subject: [PATCH 16/35] rm old validate fn from sv interface --- .../IOPContractsManagerStandardValidator.sol | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol index e4ea81632c38e..9079ef2fbdd45 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol @@ -74,27 +74,3 @@ interface IOPContractsManagerStandardValidator { ) external; } - -interface IOPContractsManagerStandardValidatorPreOPCM4_1_0 { - struct ValidationInput { - IProxyAdmin proxyAdmin; - ISystemConfig sysCfg; - bytes32 absolutePrestate; - uint256 l2ChainID; - } - - struct ValidationOverrides { - address l1PAOMultisig; - address challenger; - } - - function validateWithOverrides( - ValidationInput memory _input, - bool _allowFailure, - ValidationOverrides memory _overrides - ) - external - view - returns (string memory); - function validate(ValidationInput memory _input, bool _allowFailure) external view returns (string memory); -} From 4039cf6bc93716f80b4730b3a414745660e77c18 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Wed, 8 Oct 2025 17:39:34 +0100 Subject: [PATCH 17/35] rm unused import --- .../interfaces/L1/IOPContractsManagerStandardValidator.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol index 9079ef2fbdd45..02a02a342f847 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.0; // Interfaces import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; interface IOPContractsManagerStandardValidator { struct Implementations { From 80f6105c1dc5f4c5060e35872b05a7ea47b64540 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Wed, 8 Oct 2025 18:30:29 +0100 Subject: [PATCH 18/35] add unexpectedEncoding revert test and improved assertion to upgradOPChainInput --- .../scripts/deploy/UpgradeOPChain.s.sol | 2 +- .../test/opcm/UpgradeOPChain.t.sol | 47 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index c1544eaac5002..8f177faadaf2b 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -21,7 +21,7 @@ contract UpgradeOPChainInput is BaseDeployIO { } function set(bytes4 _sel, bytes memory _value) public { - require(_value.length > 0, "UpgradeOPChainInput: cannot set empty array"); + require(_value.length > 64, "UpgradeOPChainInput: cannot set empty array"); if (_sel == this.opChainConfigs.selector) _opChainConfigs = _value; else revert("UpgradeOPChainInput: unknown selector"); diff --git a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol index df52f8107cfb9..a7c983d2ec323 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol @@ -89,6 +89,10 @@ contract UpgradeOPChainInput_Test is Test { } function test_setOpChainConfigs_withEmptyArray_reverts() public { + IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](0); + vm.expectRevert("UpgradeOPChainInput: cannot set empty array"); + input.set(input.opChainConfigs.selector, abi.encode(configs)); + vm.expectRevert("UpgradeOPChainInput: cannot set empty array"); input.set(input.opChainConfigs.selector, new bytes(0)); } @@ -199,5 +203,46 @@ contract UpgradeOPChain_Test is Test { upgradeOPChain.run(uoci); } - function test_upgrade_unexpectedEncoding_reverts() public { } + function test_upgrade_unexpectedEncoding_reverts( + IOPContractsManager.OpChainConfig[] memory _opChainConfigs, + IOPContractsManagerPre4_1_0.OpChainConfig[] memory _opChainConfigsPre410 + ) + public + { + vm.assume(_opChainConfigsPre410.length > 0); + vm.assume(_opChainConfigs.length > 0); + + // Currently the mockOPCM set in the input contract is that of a version >= 4.1.0 + // So lets try to set opChainConfigs to be one of < 4.1.0 and expect a revert. + uoci.set(uoci.opChainConfigs.selector, abi.encode(_opChainConfigsPre410)); + // It can revert because it could not decode the opChainConfigs (this happens if it expects an address but sees + // a value with upper 12 bits dirty). If it does not see this it will still revert with a custom string error + // because it decoded into the wrong type. + (bool success, bytes memory result) = address(upgradeOPChain).call(abi.encodeCall(upgradeOPChain.run, (uoci))); + assertFalse(success, "UpgradeOPChain_Test: call should revert"); + assertTrue( + keccak256(result) + == keccak256(abi.encodeWithSignature("Error(string)", "UpgradeOPChain: opChainConfigs Unexpected encoding")) + || keccak256(result) == keccak256(""), + "UpgradeOPChain_Test: result should be the expected error" + ); + + // Now lets set the mockOPCM to be a version < 4.1.0 and expect a revert when we set the opChainConfigs to be + // that of version >= 4.1.0 and calling run. + mockOPCM = address(new MockOPCMPre410()); + uoci.set(uoci.opcm.selector, mockOPCM); + uoci.set(uoci.opChainConfigs.selector, abi.encode(_opChainConfigs)); + // It can revert because it could not decode the opChainConfigs (this happens if it expects an address but sees + // a value with upper 12 bits dirty). If it does not see this it will still revert with a custom string error + // because it decoded into the wrong type. + (success, result) = address(upgradeOPChain).call(abi.encodeCall(upgradeOPChain.run, (uoci))); + assertFalse(success, "UpgradeOPChain_Test: opChainConfigsPre410 call should revert"); + assertTrue( + keccak256(result) + == keccak256( + abi.encodeWithSignature("Error(string)", "UpgradeOPChain: opChainConfigsPre410 Unexpected encoding") + ) || keccak256(result) == keccak256(""), + "UpgradeOPChain_Test: opChainConfigsPre410 result should be the expected error" + ); + } } From b595ce655f3a96d6fd4b161a96da5e9b9a0083b7 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Wed, 8 Oct 2025 18:37:16 +0100 Subject: [PATCH 19/35] fix semgrep --- .../contracts-bedrock/test/opcm/UpgradeOPChain.t.sol | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol index a7c983d2ec323..eac9e19f17e4a 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol @@ -222,8 +222,11 @@ contract UpgradeOPChain_Test is Test { assertFalse(success, "UpgradeOPChain_Test: call should revert"); assertTrue( keccak256(result) - == keccak256(abi.encodeWithSignature("Error(string)", "UpgradeOPChain: opChainConfigs Unexpected encoding")) - || keccak256(result) == keccak256(""), + == keccak256( + bytes.concat( + bytes4(keccak256("Error(string)")), abi.encode("UpgradeOPChain: opChainConfigs Unexpected encoding") + ) + ) || keccak256(result) == keccak256(""), "UpgradeOPChain_Test: result should be the expected error" ); @@ -240,7 +243,10 @@ contract UpgradeOPChain_Test is Test { assertTrue( keccak256(result) == keccak256( - abi.encodeWithSignature("Error(string)", "UpgradeOPChain: opChainConfigsPre410 Unexpected encoding") + bytes.concat( + bytes4(keccak256("Error(string)")), + abi.encode("UpgradeOPChain: opChainConfigsPre410 Unexpected encoding") + ) ) || keccak256(result) == keccak256(""), "UpgradeOPChain_Test: opChainConfigsPre410 result should be the expected error" ); From 0f6bd52c900b768bc35b899bf6c7a94aa633f78d Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Thu, 9 Oct 2025 16:04:35 +0100 Subject: [PATCH 20/35] fix upgradeSuperchainConfig script --- .../v5_0_0/upgrade_superchainconfig.go | 18 +++-- .../deploy/UpgradeSuperchainConfig.s.sol | 56 ++++------------ .../test/opcm/UpgradeSuperchainConfig.t.sol | 66 +++---------------- 3 files changed, 34 insertions(+), 106 deletions(-) diff --git a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go index c8f4926cd4f4b..3f6e29fb3df83 100644 --- a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go +++ b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/ethereum-optimism/optimism/op-chain-ops/script" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" "github.com/ethereum/go-ethereum/common" ) @@ -16,12 +15,23 @@ type UpgradeSuperchainConfigInput struct { SuperchainProxyAdmin common.Address `json:"superchainProxyAdmin"` } -type UpgradeSuperchainConfigScript struct { - Run func(input common.Address) +type UpgradeSuperchainConfigScript script.DeployScriptWithoutOutput[UpgradeSuperchainConfigInput] + +// NewDeployImplementationsScript loads and validates the DeployImplementations script contract +func NewUpgradeSuperchainConfigScript(host *script.Host) (UpgradeSuperchainConfigScript, error) { + return script.NewDeployScriptWithoutOutputFromFile[UpgradeSuperchainConfigInput](host, "UpgradeSuperchainConfig.s.sol", "UpgradeSuperchainConfig") } func UpgradeSuperchainConfig(host *script.Host, input UpgradeSuperchainConfigInput) error { - return opcm.RunScriptVoid[UpgradeSuperchainConfigInput](host, input, "UpgradeSuperchainConfig.s.sol", "UpgradeSuperchainConfig") + upgradeScript, err := NewUpgradeSuperchainConfigScript(host) + if err != nil { + return fmt.Errorf("failed to load UpgradeSuperchainConfig script: %w", err) + } + err = upgradeScript.Run(input) + if err != nil { + return fmt.Errorf("failed to run UpgradeSuperchainConfig script: %w", err) + } + return nil } func (u *Upgrader) UpgradeSuperchainConfig(host *script.Host, input json.RawMessage) error { diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol index c1a3f4dbf6964..d0ce4454795fb 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol @@ -5,56 +5,22 @@ import { Script } from "forge-std/Script.sol"; import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; -contract UpgradeSuperchainConfigInput is BaseDeployIO { - address internal _prank; - IOPContractsManager internal _opcm; - ISuperchainConfig internal _superchainConfig; - IProxyAdmin internal _superchainProxyAdmin; - - // Setter for OPContractsManager type - function set(bytes4 _sel, address _value) public { - require(address(_value) != address(0), "UpgradeSuperchainConfigInput: cannot set zero address"); - - if (_sel == this.prank.selector) _prank = _value; - else if (_sel == this.opcm.selector) _opcm = IOPContractsManager(_value); - else if (_sel == this.superchainConfig.selector) _superchainConfig = ISuperchainConfig(_value); - else if (_sel == this.superchainProxyAdmin.selector) _superchainProxyAdmin = IProxyAdmin(_value); - else revert("UpgradeSuperchainConfigInput: unknown selector"); - } - - function prank() public view returns (address) { - require(address(_prank) != address(0), "UpgradeSuperchainConfigInput: prank not set"); - return _prank; - } - - function opcm() public view returns (IOPContractsManager) { - require(address(_opcm) != address(0), "UpgradeSuperchainConfigInput: opcm not set"); - return _opcm; - } - - function superchainConfig() public view returns (ISuperchainConfig) { - require(address(_superchainConfig) != address(0), "UpgradeSuperchainConfigInput: superchainConfig not set"); - return _superchainConfig; - } - - function superchainProxyAdmin() public view returns (IProxyAdmin) { - require( - address(_superchainProxyAdmin) != address(0), "UpgradeSuperchainConfigInput: superchainProxyAdmin not set" - ); - return _superchainProxyAdmin; +contract UpgradeSuperchainConfig is Script { + struct Input { + address prank; + IOPContractsManager opcm; + ISuperchainConfig superchainConfig; + IProxyAdmin superchainProxyAdmin; } -} -contract UpgradeSuperchainConfig is Script { - function run(UpgradeSuperchainConfigInput _uoci) external { - IOPContractsManager opcm = _uoci.opcm(); + function run(Input memory _input) external { + IOPContractsManager opcm = _input.opcm; // Etch DummyCaller contract. This contract is used to mimic the contract that is used // as the source of the delegatecall to the OPCM. In practice this will be the governance // 2/2 or similar. - address prank = _uoci.prank(); + address prank = _input.prank; bytes memory code = vm.getDeployedCode("UpgradeSuperchainConfig.s.sol:DummyCaller"); vm.etch(prank, code); @@ -62,8 +28,8 @@ contract UpgradeSuperchainConfig is Script { vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); vm.label(prank, "DummyCaller"); - ISuperchainConfig superchainConfig = _uoci.superchainConfig(); - IProxyAdmin superchainProxyAdmin = _uoci.superchainProxyAdmin(); + ISuperchainConfig superchainConfig = _input.superchainConfig; + IProxyAdmin superchainProxyAdmin = _input.superchainProxyAdmin; // Call into the DummyCaller to perform the delegatecall vm.broadcast(msg.sender); diff --git a/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol index 76ab1b522b9c5..aa90a52840890 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol @@ -6,56 +6,8 @@ import { Test } from "forge-std/Test.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { UpgradeSuperchainConfig, UpgradeSuperchainConfigInput } from "scripts/deploy/UpgradeSuperchainConfig.s.sol"; - -contract UpgradeSuperchainConfigInput_Test is Test { - UpgradeSuperchainConfigInput input; - - function setUp() public { - input = new UpgradeSuperchainConfigInput(); - } - - function test_getters_whenNotSet_reverts() public { - vm.expectRevert("UpgradeSuperchainConfigInput: prank not set"); - input.prank(); - - vm.expectRevert("UpgradeSuperchainConfigInput: opcm not set"); - input.opcm(); - - vm.expectRevert("UpgradeSuperchainConfigInput: superchainConfig not set"); - input.superchainConfig(); - - vm.expectRevert("UpgradeSuperchainConfigInput: superchainProxyAdmin not set"); - input.superchainProxyAdmin(); - } - - function test_setAddress_succeeds() public { - address mockPrank = makeAddr("prank"); - address mockOPCM = makeAddr("opcm"); - - // Create mock contract at OPCM address - vm.etch(mockOPCM, hex"01"); - - input.set(input.prank.selector, mockPrank); - input.set(input.opcm.selector, mockOPCM); - - assertEq(input.prank(), mockPrank); - assertEq(address(input.opcm()), mockOPCM); - } - - function test_setAddress_withZeroAddress_reverts() public { - vm.expectRevert("UpgradeSuperchainConfigInput: cannot set zero address"); - input.set(input.prank.selector, address(0)); - - vm.expectRevert("UpgradeSuperchainConfigInput: cannot set zero address"); - input.set(input.opcm.selector, address(0)); - } - - function test_set_withInvalidSelector_reverts() public { - vm.expectRevert("UpgradeSuperchainConfigInput: unknown selector"); - input.set(bytes4(0xdeadbeef), makeAddr("test")); - } -} +import { UpgradeSuperchainConfig } from "scripts/deploy/UpgradeSuperchainConfig.s.sol"; +import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; contract MockOPCM { event UpgradeCalled(address indexed superchainConfig, address indexed superchainProxyAdmin); @@ -67,7 +19,7 @@ contract MockOPCM { contract UpgradeSuperchainConfig_Test is Test { MockOPCM mockOPCM; - UpgradeSuperchainConfigInput uoci; + UpgradeSuperchainConfig.Input input; UpgradeSuperchainConfig upgradeSuperchainConfig; address prank; ISuperchainConfig superchainConfig; @@ -77,16 +29,16 @@ contract UpgradeSuperchainConfig_Test is Test { function setUp() public virtual { mockOPCM = new MockOPCM(); - uoci = new UpgradeSuperchainConfigInput(); - uoci.set(uoci.opcm.selector, address(mockOPCM)); + + input.opcm = IOPContractsManager(address(mockOPCM)); superchainConfig = ISuperchainConfig(makeAddr("superchainConfig")); superchainProxyAdmin = IProxyAdmin(makeAddr("superchainProxyAdmin")); prank = makeAddr("prank"); - uoci.set(uoci.superchainConfig.selector, address(superchainConfig)); - uoci.set(uoci.superchainProxyAdmin.selector, address(superchainProxyAdmin)); - uoci.set(uoci.prank.selector, prank); + input.superchainConfig = superchainConfig; + input.superchainProxyAdmin = superchainProxyAdmin; + input.prank = prank; upgradeSuperchainConfig = new UpgradeSuperchainConfig(); } @@ -95,6 +47,6 @@ contract UpgradeSuperchainConfig_Test is Test { // UpgradeCalled should be emitted by the prank since it's a delegate call. vm.expectEmit(address(prank)); emit UpgradeCalled(address(superchainConfig), address(superchainProxyAdmin)); - upgradeSuperchainConfig.run(uoci); + upgradeSuperchainConfig.run(input); } } From e1da10cc76ea29b288475eaf56599629e65448f6 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Thu, 9 Oct 2025 16:19:11 +0100 Subject: [PATCH 21/35] make upgrade test fork a specific block --- op-deployer/pkg/deployer/integration_test/apply_test.go | 2 +- op-service/testutils/devnet/anvil.go | 6 ++++++ op-service/testutils/devnet/canned.go | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index ca12aaaa31bd0..764defdc995f3 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -151,7 +151,7 @@ func TestEndToEndBootstrapApplyWithUpgrade(t *testing.T) { op_e2e.InitParallel(t) lgr := testlog.Logger(t, slog.LevelDebug) - forkedL1, stopL1, err := devnet.NewForkedSepolia(lgr) + forkedL1, stopL1, err := devnet.NewForkedSepoliaFromBlock(lgr, 9366100) pkHex, _, _ := shared.DefaultPrivkey(t) require.NoError(t, err) t.Cleanup(func() { diff --git a/op-service/testutils/devnet/anvil.go b/op-service/testutils/devnet/anvil.go index 841e126722601..2440af5afd2c1 100644 --- a/op-service/testutils/devnet/anvil.go +++ b/op-service/testutils/devnet/anvil.go @@ -61,6 +61,12 @@ func WithChainID(id uint64) AnvilOption { } } +func WithForkBlockNumber(block uint64) AnvilOption { + return func(a *Anvil) { + a.args["--fork-block-number"] = strconv.FormatUint(block, 10) + } +} + func NewAnvil(logger log.Logger, opts ...AnvilOption) (*Anvil, error) { if _, err := exec.LookPath("anvil"); err != nil { return nil, fmt.Errorf("anvil not found in PATH: %w", err) diff --git a/op-service/testutils/devnet/canned.go b/op-service/testutils/devnet/canned.go index 8c787aa4a1c66..621781e55ff6e 100644 --- a/op-service/testutils/devnet/canned.go +++ b/op-service/testutils/devnet/canned.go @@ -46,3 +46,11 @@ func NewForkedSepolia(lgr log.Logger) (*Anvil, CleanupFunc, error) { } return NewForked(lgr, url) } + +func NewForkedSepoliaFromBlock(lgr log.Logger, block uint64) (*Anvil, CleanupFunc, error) { + url := os.Getenv("SEPOLIA_RPC_URL") + if url == "" { + return nil, nil, fmt.Errorf("SEPOLIA_RPC_URL not set") + } + return NewForked(lgr, url, WithForkBlockNumber(block)) +} From 228447fe54a4985bd8ea920c879a7a9b57c2c89d Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Thu, 9 Oct 2025 17:42:01 +0100 Subject: [PATCH 22/35] update addGameType to support the new opcm addGameType interface --- .../deployer/integration_test/apply_test.go | 3 +- .../pkg/deployer/manage/add_game_type.go | 8 -- .../pkg/deployer/manage/add_game_type_test.go | 90 +++++++----- .../pkg/deployer/opcm/add_game_type.go | 4 - .../pkg/deployer/opcm/add_game_type_test.go | 3 - .../scripts/deploy/AddGameType.s.sol | 136 +++++------------- 6 files changed, 93 insertions(+), 151 deletions(-) diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index 764defdc995f3..27004308a6da6 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -208,7 +208,8 @@ func TestEndToEndBootstrapApplyWithUpgrade(t *testing.T) { ) require.NoError(t, err) - // First run upgradeSuperchainConfig + // First run upgradeSuperchainConfig because the version on the fork is < than that + // of the contracts-bedrock folder so upgrading directly would revert. t.Run("upgrade superchain config", func(t *testing.T) { upgradeConfig := v5_0_0.UpgradeSuperchainConfigInput{ Prank: superchainProxyAdminOwner, diff --git a/op-deployer/pkg/deployer/manage/add_game_type.go b/op-deployer/pkg/deployer/manage/add_game_type.go index a7280b20fbe65..a446e9dc0b507 100644 --- a/op-deployer/pkg/deployer/manage/add_game_type.go +++ b/op-deployer/pkg/deployer/manage/add_game_type.go @@ -35,7 +35,6 @@ type AddGameTypeConfig struct { L1ProxyAdminOwner common.Address OPCMImpl common.Address SystemConfigProxy common.Address - OPChainProxyAdmin common.Address DelayedWETHProxy common.Address DisputeGameType uint32 DisputeAbsolutePrestate common.Hash @@ -78,10 +77,6 @@ func (c *AddGameTypeConfig) Check() error { return fmt.Errorf("systemConfigProxy address must be specified") } - if c.OPChainProxyAdmin == (common.Address{}) { - return fmt.Errorf("opChainProxyAdmin address must be specified") - } - if c.DisputeAbsolutePrestate == (common.Hash{}) { return fmt.Errorf("disputeAbsolutePrestate must be specified") } @@ -222,7 +217,6 @@ func populateConfigFromWorkdir(cfg *AddGameTypeConfig, cliCtx *cli.Context) erro } cfg.OPCMImpl = *state.AppliedIntent.OPCMAddress cfg.SystemConfigProxy = chainState.SystemConfigProxy - cfg.OPChainProxyAdmin = chainState.OpChainProxyAdminImpl cfg.VM = state.ImplementationsDeployment.MipsImpl return nil } @@ -235,7 +229,6 @@ func populateConfigFromFlags(cfg *AddGameTypeConfig, cliCtx *cli.Context) error cfg.L1ProxyAdminOwner = common.HexToAddress(cliCtx.String(L1ProxyAdminOwnerFlag.Name)) cfg.OPCMImpl = common.HexToAddress(cliCtx.String(OPCMImplFlag.Name)) cfg.SystemConfigProxy = common.HexToAddress(cliCtx.String(SystemConfigProxyFlag.Name)) - cfg.OPChainProxyAdmin = common.HexToAddress(cliCtx.String(OPChainProxyAdminFlag.Name)) cfg.VM = common.HexToAddress(cliCtx.String(VMFlag.Name)) return nil } @@ -281,7 +274,6 @@ func AddGameType(ctx context.Context, cfg AddGameTypeConfig) (opcm.AddGameTypeOu L1ProxyAdminOwner: cfg.L1ProxyAdminOwner, OPCMImpl: cfg.OPCMImpl, SystemConfigProxy: cfg.SystemConfigProxy, - OPChainProxyAdmin: cfg.OPChainProxyAdmin, DelayedWETHProxy: cfg.DelayedWETHProxy, DisputeGameType: cfg.DisputeGameType, DisputeAbsolutePrestate: cfg.DisputeAbsolutePrestate, diff --git a/op-deployer/pkg/deployer/manage/add_game_type_test.go b/op-deployer/pkg/deployer/manage/add_game_type_test.go index b19d51ae6ee32..e2b3b882469cf 100644 --- a/op-deployer/pkg/deployer/manage/add_game_type_test.go +++ b/op-deployer/pkg/deployer/manage/add_game_type_test.go @@ -6,102 +6,120 @@ import ( "fmt" "log/slog" "math/big" - "os" "testing" "time" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum-optimism/optimism/op-service/testutils/devnet" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/bootstrap" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/integration_test/shared" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard" "github.com/ethereum/go-ethereum/superchain" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil" - "github.com/ethereum-optimism/superchain-registry/validation" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" ) // getAddressesOnchain reads addresses from on-chain contracts (using chainConfig to get entrypoints) -func getAddressesOnchain(ctx context.Context, rpcURL string, chainConfig *superchain.ChainConfig) (opChainProxyAdmin, delayedWETHProxy common.Address, err error) { - var proxyAdminFn = w3.MustNewFunc("proxyAdmin()", "address") +func getAddressesOnchain(ctx context.Context, rpcURL string, chainConfig *superchain.ChainConfig) (delayedWETHProxy common.Address, err error) { var gameImplsFn = w3.MustNewFunc("gameImpls(uint32)", "address") var wethFn = w3.MustNewFunc("weth()", "address") client, err := w3.Dial(rpcURL) if err != nil { - return common.Address{}, common.Address{}, fmt.Errorf("failed to connect to RPC: %w", err) + return common.Address{}, fmt.Errorf("failed to connect to RPC: %w", err) } defer client.Close() - systemConfigProxy := *chainConfig.Addresses.SystemConfigProxy disputeGameFactoryProxy := *chainConfig.Addresses.DisputeGameFactoryProxy - // Read OPChainProxyAdmin from systemConfigProxy.proxyAdmin() - err = client.CallCtx(ctx, eth.CallFunc(systemConfigProxy, proxyAdminFn).Returns(&opChainProxyAdmin)) - if err != nil { - return common.Address{}, common.Address{}, fmt.Errorf("failed to read proxyAdmin from SystemConfig: %w", err) - } - // Read permissionless dispute game address from disputeGameFactoryProxy.gameImpls(0) // GameTypes.CANNON = 0 (permissionless) var permissionlessDisputeGame common.Address err = client.CallCtx(ctx, eth.CallFunc(disputeGameFactoryProxy, gameImplsFn, uint32(0)).Returns(&permissionlessDisputeGame)) if err != nil { - return common.Address{}, common.Address{}, fmt.Errorf("failed to read gameImpls(0) from DisputeGameFactory: %w", err) + return common.Address{}, fmt.Errorf("failed to read gameImpls(0) from DisputeGameFactory: %w", err) } // Read DelayedWETHProxy from permissionlessDisputeGame.weth() err = client.CallCtx(ctx, eth.CallFunc(permissionlessDisputeGame, wethFn).Returns(&delayedWETHProxy)) if err != nil { - return common.Address{}, common.Address{}, fmt.Errorf("failed to read weth from permissionless dispute game: %w", err) + return common.Address{}, fmt.Errorf("failed to read weth from permissionless dispute game: %w", err) } - return opChainProxyAdmin, delayedWETHProxy, nil + return delayedWETHProxy, nil } func TestAddGameType(t *testing.T) { - rpcURL := os.Getenv("SEPOLIA_RPC_URL") - require.NotEmpty(t, rpcURL, "must specify RPC url via SEPOLIA_RPC_URL env var") + // Since the opcm version is not yet on sepolia, we create a fork of sepolia then deploy the opcm via deploy implementations. + lgr := testlog.Logger(t, slog.LevelDebug) + forkedL1, stopL1, err := devnet.NewForkedSepoliaFromBlock(lgr, 9366100) + pkHex, _, _ := shared.DefaultPrivkey(t) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, stopL1()) + }) afacts, _ := testutil.LocalArtifacts(t) - v200SepoliaAddrs := validation.StandardVersionsSepolia[standard.ContractsV200Tag] + ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second) + defer cancel() testCacheDir := testutils.IsolatedTestDirWithAutoCleanup(t) - chain, err := superchain.GetChain(11155420) + sChain, err := standard.SuperchainFor(11155111) require.NoError(t, err) - chainConfig, err := chain.Config() + + superchainProxyAdmin, err := standard.SuperchainProxyAdminAddrFor(11155111) require.NoError(t, err) - readCtx, readCancel := context.WithTimeout(context.Background(), 10*time.Second) - defer readCancel() + superchainProxyAdminOwner, err := standard.L1ProxyAdminOwner(11155111) + require.NoError(t, err) - opChainProxyAdmin, delayedWETHProxy, err := getAddressesOnchain(readCtx, rpcURL, chainConfig) - require.NoError(t, err, "failed to read addresses from chain") + impls, err := bootstrap.Implementations(ctx, bootstrap.ImplementationsConfig{ + L1RPCUrl: forkedL1.RPCUrl(), + PrivateKey: pkHex, + ArtifactsLocator: afacts, + MIPSVersion: int(standard.MIPSVersion), + WithdrawalDelaySeconds: standard.WithdrawalDelaySeconds, + MinProposalSizeBytes: standard.MinProposalSizeBytes, + ChallengePeriodSeconds: standard.ChallengePeriodSeconds, + ProofMaturityDelaySeconds: standard.ProofMaturityDelaySeconds, + DisputeGameFinalityDelaySeconds: standard.DisputeGameFinalityDelaySeconds, + DevFeatureBitmap: common.Hash{}, + SuperchainConfigProxy: sChain.SuperchainConfigAddr, + ProtocolVersionsProxy: sChain.ProtocolVersionsAddr, + L1ProxyAdminOwner: superchainProxyAdminOwner, + SuperchainProxyAdmin: superchainProxyAdmin, + CacheDir: testCacheDir, + Logger: lgr, + Challenger: common.Address{'C'}, + }) + require.NoError(t, err) cfg := AddGameTypeConfig{ - L1RPCUrl: rpcURL, + L1RPCUrl: forkedL1.RPCUrl(), Logger: testlog.Logger(t, slog.LevelInfo), ArtifactsLocator: afacts, SaltMixer: "foo", // The values below were pulled from the Superchain Registry for OP Sepolia. - SystemConfigProxy: *chainConfig.Addresses.SystemConfigProxy, - OPChainProxyAdmin: opChainProxyAdmin, - DelayedWETHProxy: delayedWETHProxy, - DisputeGameType: 999, + SystemConfigProxy: common.HexToAddress("034edD2A225f7f429A63E0f1D2084B9E0A93b538"), + DelayedWETHProxy: common.HexToAddress("1Bf7Ea64F9339CE5468c2947151c18E2a1229B76"), + DisputeGameType: 0, DisputeAbsolutePrestate: common.HexToHash("0x1234"), DisputeMaxGameDepth: big.NewInt(73), DisputeSplitDepth: big.NewInt(30), DisputeClockExtension: 10800, DisputeMaxClockDuration: 302400, InitialBond: big.NewInt(1), - VM: common.Address(*v200SepoliaAddrs.Mips.Address), - Permissionless: false, - L1ProxyAdminOwner: *chainConfig.Roles.ProxyAdminOwner, - OPCMImpl: common.Address(*v200SepoliaAddrs.OPContractsManager.Address), + VM: impls.MipsSingleton, + Permissionless: true, + L1ProxyAdminOwner: superchainProxyAdminOwner, + OPCMImpl: impls.Opcm, CacheDir: testCacheDir, } @@ -113,7 +131,7 @@ func TestAddGameType(t *testing.T) { require.Equal(t, 1, len(broadcasts)) // Selector for addGameType - require.EqualValues(t, []byte{0x16, 0x61, 0xa2, 0xe9}, broadcasts[0].Data[0:4]) + require.EqualValues(t, []byte{0x60, 0x4a, 0xa6, 0x28}, broadcasts[0].Data[0:4]) require.NotEqual(t, common.Address{}, output.DelayedWETHProxy) require.NotEqual(t, common.Address{}, output.FaultDisputeGameProxy) @@ -127,7 +145,6 @@ func TestAddGameType_CLI(t *testing.T) { {L1ProxyAdminOwnerFlag, common.Address{0x01}.String()}, {OPCMImplFlag, common.Address{0x02}.String()}, {SystemConfigProxyFlag, common.Address{0x03}.String()}, - {OPChainProxyAdminFlag, common.Address{0x04}.String()}, {VMFlag, common.Address{0x05}.String()}, } @@ -175,7 +192,6 @@ func TestAddGameType_CLI(t *testing.T) { require.Equal(t, common.HexToAddress("0x1eb2ffc903729a0f03966b917003800b145f56e2"), cfg.L1ProxyAdminOwner) require.Equal(t, common.HexToAddress("0xfbceed4de885645fbded164910e10f52febfab35"), cfg.OPCMImpl) - require.Equal(t, common.HexToAddress("0x7bd8879acf1e74547455c7ddc07f5c3f4a3c133d"), cfg.OPChainProxyAdmin) require.Equal(t, common.HexToAddress("0x02f909cf91c2134e70a67950b7f27db7c8ee55d6"), cfg.SystemConfigProxy) require.Equal(t, common.HexToAddress("0x0000000000000000000000000000000000000001"), cfg.VM) }) @@ -186,7 +202,6 @@ func TestAddGameType_CLI(t *testing.T) { flagSet.String(L1ProxyAdminOwnerFlag.Name, "0x1eb2ffc903729a0f03966b917003800b145f56e2", "doc") flagSet.String(OPCMImplFlag.Name, "0xfbceed4de885645fbded164910e10f52febfab35", "doc") - flagSet.String(OPChainProxyAdminFlag.Name, "0x7bd8879acf1e74547455c7ddc07f5c3f4a3c133d", "doc") flagSet.String(SystemConfigProxyFlag.Name, "0x02f909cf91c2134e70a67950b7f27db7c8ee55d6", "doc") flagSet.String(VMFlag.Name, "0x0000000000000000000000000000000000000001", "doc") @@ -197,7 +212,6 @@ func TestAddGameType_CLI(t *testing.T) { require.Equal(t, common.HexToAddress("0x1eb2ffc903729a0f03966b917003800b145f56e2"), cfg.L1ProxyAdminOwner) require.Equal(t, common.HexToAddress("0xfbceed4de885645fbded164910e10f52febfab35"), cfg.OPCMImpl) - require.Equal(t, common.HexToAddress("0x7bd8879acf1e74547455c7ddc07f5c3f4a3c133d"), cfg.OPChainProxyAdmin) require.Equal(t, common.HexToAddress("0x02f909cf91c2134e70a67950b7f27db7c8ee55d6"), cfg.SystemConfigProxy) require.Equal(t, common.HexToAddress("0x0000000000000000000000000000000000000001"), cfg.VM) }) diff --git a/op-deployer/pkg/deployer/opcm/add_game_type.go b/op-deployer/pkg/deployer/opcm/add_game_type.go index ed9cd70681702..6b2798de9e78a 100644 --- a/op-deployer/pkg/deployer/opcm/add_game_type.go +++ b/op-deployer/pkg/deployer/opcm/add_game_type.go @@ -13,7 +13,6 @@ type AddGameTypeInput struct { L1ProxyAdminOwner common.Address `abi:"prank"` OPCMImpl common.Address `abi:"opcmImpl"` SystemConfigProxy common.Address - OPChainProxyAdmin common.Address `abi:"opChainProxyAdmin"` DelayedWETHProxy common.Address DisputeGameType uint32 DisputeAbsolutePrestate common.Hash @@ -31,7 +30,6 @@ type addGameTypeInputJSON struct { Prank common.Address `json:"prank"` OPCMImpl common.Address `json:"opcmimpl"` SystemConfigProxy common.Address `json:"systemConfigProxy"` - OPChainProxyAdmin common.Address `json:"opChainProxyAdmin"` DelayedWETHProxy common.Address `json:"delayedWETHProxy"` DisputeGameType uint32 `json:"disputeGameType"` DisputeAbsolutePrestate common.Hash `json:"disputeAbsolutePrestate"` @@ -54,7 +52,6 @@ func (a *AddGameTypeInput) UnmarshalJSON(b []byte) error { a.L1ProxyAdminOwner = alias.Prank a.OPCMImpl = alias.OPCMImpl a.SystemConfigProxy = alias.SystemConfigProxy - a.OPChainProxyAdmin = alias.OPChainProxyAdmin a.DelayedWETHProxy = alias.DelayedWETHProxy a.DisputeGameType = alias.DisputeGameType a.DisputeAbsolutePrestate = alias.DisputeAbsolutePrestate @@ -86,7 +83,6 @@ func (a AddGameTypeInput) MarshalJSON() ([]byte, error) { Prank: a.L1ProxyAdminOwner, OPCMImpl: a.OPCMImpl, SystemConfigProxy: a.SystemConfigProxy, - OPChainProxyAdmin: a.OPChainProxyAdmin, DelayedWETHProxy: a.DelayedWETHProxy, DisputeGameType: a.DisputeGameType, DisputeAbsolutePrestate: a.DisputeAbsolutePrestate, diff --git a/op-deployer/pkg/deployer/opcm/add_game_type_test.go b/op-deployer/pkg/deployer/opcm/add_game_type_test.go index be7175526d5e3..b87cc435b95e6 100644 --- a/op-deployer/pkg/deployer/opcm/add_game_type_test.go +++ b/op-deployer/pkg/deployer/opcm/add_game_type_test.go @@ -26,7 +26,6 @@ func compareAddGameTypeInputs(t *testing.T, expected, actual AddGameTypeInput) { require.Equal(t, expected.L1ProxyAdminOwner, actual.L1ProxyAdminOwner) require.Equal(t, expected.OPCMImpl, actual.OPCMImpl) require.Equal(t, expected.SystemConfigProxy, actual.SystemConfigProxy) - require.Equal(t, expected.OPChainProxyAdmin, actual.OPChainProxyAdmin) require.Equal(t, expected.DelayedWETHProxy, actual.DelayedWETHProxy) require.Equal(t, expected.DisputeGameType, actual.DisputeGameType) require.Equal(t, expected.DisputeAbsolutePrestate, actual.DisputeAbsolutePrestate) @@ -54,7 +53,6 @@ func TestAddGameTypeInput_MarshalUnmarshalJSON(t *testing.T) { L1ProxyAdminOwner: common.HexToAddress("0x1111111111111111111111111111111111111111"), OPCMImpl: common.HexToAddress("0x2222222222222222222222222222222222222222"), SystemConfigProxy: common.HexToAddress("0x3333333333333333333333333333333333333333"), - OPChainProxyAdmin: common.HexToAddress("0x4444444444444444444444444444444444444444"), DelayedWETHProxy: common.HexToAddress("0x5555555555555555555555555555555555555555"), DisputeGameType: 1, DisputeAbsolutePrestate: common.HexToHash("0x6666666666666666666666666666666666666666666666666666666666666666"), @@ -74,7 +72,6 @@ func TestAddGameTypeInput_MarshalUnmarshalJSON(t *testing.T) { L1ProxyAdminOwner: common.HexToAddress("0x1111111111111111111111111111111111111111"), OPCMImpl: common.HexToAddress("0x2222222222222222222222222222222222222222"), SystemConfigProxy: common.HexToAddress("0x3333333333333333333333333333333333333333"), - OPChainProxyAdmin: common.HexToAddress("0x4444444444444444444444444444444444444444"), DelayedWETHProxy: common.HexToAddress("0x5555555555555555555555555555555555555555"), DisputeGameType: 1, DisputeAbsolutePrestate: common.HexToHash("0x6666666666666666666666666666666666666666666666666666666666666666"), diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index c658efab6a726..f4956c6b4bdf5 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -6,13 +6,10 @@ import { Script } from "forge-std/Script.sol"; // Scripts import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; // Interfaces -import { OPContractsManager } from "src/L1/OPContractsManager.sol"; -import { IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; import { GameType, Duration, Claim } from "src/dispute/lib/Types.sol"; @@ -24,11 +21,9 @@ contract AddGameType is Script { // Address that will be used for the DummyCaller contract address prank; // OPCM contract address - OPContractsManager opcmImpl; + IOPContractsManager opcmImpl; // SystemConfig contract address ISystemConfig systemConfigProxy; - // ProxyAdmin contract address - IProxyAdmin opChainProxyAdmin; // DelayedWETH contract address (optional) IDelayedWETH delayedWETHProxy; // Game type to add @@ -62,79 +57,38 @@ contract AddGameType is Script { // Etch DummyCaller contract address prank = _agi.prank; - // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for - // both interface variants. - if (SemverComp.lt(_agi.opcmImpl.version(), "4.1.0")) { - bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCallerPreOPCM4_1_0"); - vm.etch(prank, code); - vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcmImpl))))); - vm.label(prank, "DummyCaller"); - - // Create the game input - IOPContractsManagerPre4_1_0.AddGameInput[] memory gameConfigs = - new IOPContractsManagerPre4_1_0.AddGameInput[](1); - gameConfigs[0] = IOPContractsManagerPre4_1_0.AddGameInput({ - saltMixer: _agi.saltMixer, - systemConfig: _agi.systemConfigProxy, - proxyAdmin: _agi.opChainProxyAdmin, - delayedWETH: _agi.delayedWETHProxy, - disputeGameType: _agi.disputeGameType, - disputeAbsolutePrestate: _agi.disputeAbsolutePrestate, - disputeMaxGameDepth: _agi.disputeMaxGameDepth, - disputeSplitDepth: _agi.disputeSplitDepth, - disputeClockExtension: _agi.disputeClockExtension, - disputeMaxClockDuration: _agi.disputeMaxClockDuration, - initialBond: _agi.initialBond, - vm: _agi.vm, - permissioned: _agi.permissioned - }); - - // Call into the DummyCaller to perform the delegatecall - vm.broadcast(msg.sender); - - (bool success, bytes memory result) = DummyCallerPreOPCM4_1_0(prank).addGameType(gameConfigs); - require(success, "AddGameType: addGameType failed"); - - // Decode the result and set it in the output - OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); - require(outputs.length == 1, "AddGameType: unexpected number of outputs"); - return - Output({ delayedWETHProxy: outputs[0].delayedWETH, faultDisputeGameProxy: outputs[0].faultDisputeGame }); - } else { - bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCaller"); - vm.etch(prank, code); - vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcmImpl))))); - vm.label(prank, "DummyCaller"); - - // Create the game input - OPContractsManager.AddGameInput[] memory gameConfigs = new OPContractsManager.AddGameInput[](1); - gameConfigs[0] = OPContractsManager.AddGameInput({ - saltMixer: _agi.saltMixer, - systemConfig: _agi.systemConfigProxy, - delayedWETH: _agi.delayedWETHProxy, - disputeGameType: _agi.disputeGameType, - disputeAbsolutePrestate: _agi.disputeAbsolutePrestate, - disputeMaxGameDepth: _agi.disputeMaxGameDepth, - disputeSplitDepth: _agi.disputeSplitDepth, - disputeClockExtension: _agi.disputeClockExtension, - disputeMaxClockDuration: _agi.disputeMaxClockDuration, - initialBond: _agi.initialBond, - vm: _agi.vm, - permissioned: _agi.permissioned - }); - - // Call into the DummyCaller to perform the delegatecall - vm.broadcast(msg.sender); - - (bool success, bytes memory result) = DummyCaller(prank).addGameType(gameConfigs); - require(success, "AddGameType: addGameType failed"); - - // Decode the result and set it in the output - OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); - require(outputs.length == 1, "AddGameType: unexpected number of outputs"); - return - Output({ delayedWETHProxy: outputs[0].delayedWETH, faultDisputeGameProxy: outputs[0].faultDisputeGame }); - } + bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCaller"); + vm.etch(prank, code); + vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcmImpl))))); + vm.label(prank, "DummyCaller"); + + // Create the game input + IOPContractsManager.AddGameInput[] memory gameConfigs = new IOPContractsManager.AddGameInput[](1); + gameConfigs[0] = IOPContractsManager.AddGameInput({ + saltMixer: _agi.saltMixer, + systemConfig: _agi.systemConfigProxy, + delayedWETH: _agi.delayedWETHProxy, + disputeGameType: _agi.disputeGameType, + disputeAbsolutePrestate: _agi.disputeAbsolutePrestate, + disputeMaxGameDepth: _agi.disputeMaxGameDepth, + disputeSplitDepth: _agi.disputeSplitDepth, + disputeClockExtension: _agi.disputeClockExtension, + disputeMaxClockDuration: _agi.disputeMaxClockDuration, + initialBond: _agi.initialBond, + vm: _agi.vm, + permissioned: _agi.permissioned + }); + + // Call into the DummyCaller to perform the delegatecall + vm.broadcast(msg.sender); + + (bool success, bytes memory result) = DummyCaller(prank).addGameType(gameConfigs); + require(success, "AddGameType: addGameType failed"); + + // Decode the result and set it in the output + IOPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (IOPContractsManager.AddGameOutput[])); + require(outputs.length == 1, "AddGameType: unexpected number of outputs"); + return Output({ delayedWETHProxy: outputs[0].delayedWETH, faultDisputeGameProxy: outputs[0].faultDisputeGame }); } function checkOutput(Output memory _ago) internal view { @@ -143,29 +97,17 @@ contract AddGameType is Script { } } -/// @title DummyCallerPreOPCM4_1_0 -/// @notice This contract is used to mimic the contract that is used as the source of the delegatecall to the OPCM. -/// @dev This contract is used for OPCM versions 4.1.0 and below. -contract DummyCallerPreOPCM4_1_0 { - address internal _opcmAddr; - - function addGameType(IOPContractsManagerPre4_1_0.AddGameInput[] memory _gameConfigs) - external - returns (bool, bytes memory) - { - bytes memory data = abi.encodeCall(DummyCallerPreOPCM4_1_0.addGameType, _gameConfigs); - (bool success, bytes memory result) = _opcmAddr.delegatecall(data); - return (success, result); - } -} - /// @title DummyCaller /// @notice This contract is used to mimic the contract that is used as the source of the delegatecall to the OPCM. /// @dev This contract is used for OPCM versions 4.1.0 and above. + contract DummyCaller { address internal _opcmAddr; - function addGameType(OPContractsManager.AddGameInput[] memory _gameConfigs) external returns (bool, bytes memory) { + function addGameType(IOPContractsManager.AddGameInput[] memory _gameConfigs) + external + returns (bool, bytes memory) + { bytes memory data = abi.encodeCall(DummyCaller.addGameType, _gameConfigs); (bool success, bytes memory result) = _opcmAddr.delegatecall(data); return (success, result); From 4fbf6b31aacc138fd24b6af59b9f1524ee9de98f Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Thu, 9 Oct 2025 17:48:25 +0100 Subject: [PATCH 23/35] fix go lint --- .../pkg/deployer/manage/add_game_type_test.go | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/op-deployer/pkg/deployer/manage/add_game_type_test.go b/op-deployer/pkg/deployer/manage/add_game_type_test.go index e2b3b882469cf..409bad131bc62 100644 --- a/op-deployer/pkg/deployer/manage/add_game_type_test.go +++ b/op-deployer/pkg/deployer/manage/add_game_type_test.go @@ -12,13 +12,10 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testutils" "github.com/ethereum-optimism/optimism/op-service/testutils/devnet" - "github.com/lmittmann/w3" - "github.com/lmittmann/w3/module/eth" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/bootstrap" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/integration_test/shared" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard" - "github.com/ethereum/go-ethereum/superchain" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil" "github.com/ethereum/go-ethereum/common" @@ -26,36 +23,6 @@ import ( "github.com/urfave/cli/v2" ) -// getAddressesOnchain reads addresses from on-chain contracts (using chainConfig to get entrypoints) -func getAddressesOnchain(ctx context.Context, rpcURL string, chainConfig *superchain.ChainConfig) (delayedWETHProxy common.Address, err error) { - var gameImplsFn = w3.MustNewFunc("gameImpls(uint32)", "address") - var wethFn = w3.MustNewFunc("weth()", "address") - - client, err := w3.Dial(rpcURL) - if err != nil { - return common.Address{}, fmt.Errorf("failed to connect to RPC: %w", err) - } - defer client.Close() - - disputeGameFactoryProxy := *chainConfig.Addresses.DisputeGameFactoryProxy - - // Read permissionless dispute game address from disputeGameFactoryProxy.gameImpls(0) - // GameTypes.CANNON = 0 (permissionless) - var permissionlessDisputeGame common.Address - err = client.CallCtx(ctx, eth.CallFunc(disputeGameFactoryProxy, gameImplsFn, uint32(0)).Returns(&permissionlessDisputeGame)) - if err != nil { - return common.Address{}, fmt.Errorf("failed to read gameImpls(0) from DisputeGameFactory: %w", err) - } - - // Read DelayedWETHProxy from permissionlessDisputeGame.weth() - err = client.CallCtx(ctx, eth.CallFunc(permissionlessDisputeGame, wethFn).Returns(&delayedWETHProxy)) - if err != nil { - return common.Address{}, fmt.Errorf("failed to read weth from permissionless dispute game: %w", err) - } - - return delayedWETHProxy, nil -} - func TestAddGameType(t *testing.T) { // Since the opcm version is not yet on sepolia, we create a fork of sepolia then deploy the opcm via deploy implementations. lgr := testlog.Logger(t, slog.LevelDebug) From 48659d906faade2b37f4012129b9f2745c09402b Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Mon, 20 Oct 2025 14:20:18 +0100 Subject: [PATCH 24/35] fixes --- .../pkg/deployer/upgrade/v5_0_0/upgrade.go | 56 ------------------- .../v5_0_0/upgrade_superchainconfig.go | 43 -------------- .../deployer/upgrade/v5_0_0/upgrade_test.go | 38 ------------- .../snapshots/semver-lock.json | 6 +- .../src/L1/OPContractsManager.sol | 4 +- 5 files changed, 5 insertions(+), 142 deletions(-) delete mode 100644 op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go delete mode 100644 op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go delete mode 100644 op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_test.go diff --git a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go deleted file mode 100644 index 0ef089451b1b6..0000000000000 --- a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go +++ /dev/null @@ -1,56 +0,0 @@ -package v5_0_0 - -import ( - "encoding/json" - "fmt" - - "github.com/ethereum-optimism/optimism/op-chain-ops/script" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" - "github.com/ethereum/go-ethereum/common" - "github.com/lmittmann/w3" -) - -type UpgradeOPChainInput struct { - Prank common.Address `json:"prank"` - Opcm common.Address `json:"opcm"` - EncodedChainConfigs []OPChainConfig `evm:"-" json:"chainConfigs"` -} - -type OPChainConfig struct { - SystemConfigProxy common.Address `json:"systemConfigProxy"` - AbsolutePrestate common.Hash `json:"absolutePrestate"` -} - -var opChainConfigEncoder = w3.MustNewFunc("dummy((address systemConfigProxy,bytes32 absolutePrestate)[])", "") - -func (u *UpgradeOPChainInput) OpChainConfigs() ([]byte, error) { - data, err := opChainConfigEncoder.EncodeArgs(u.EncodedChainConfigs) - if err != nil { - return nil, fmt.Errorf("failed to encode chain configs: %w", err) - } - return data[4:], nil -} - -type UpgradeOPChain struct { - Run func(input common.Address) -} - -func Upgrade(host *script.Host, input UpgradeOPChainInput) error { - return opcm.RunScriptVoid[UpgradeOPChainInput](host, input, "UpgradeOPChain.s.sol", "UpgradeOPChain") -} - -type Upgrader struct{} - -func (u *Upgrader) Upgrade(host *script.Host, input json.RawMessage) error { - var upgradeInput UpgradeOPChainInput - if err := json.Unmarshal(input, &upgradeInput); err != nil { - return fmt.Errorf("failed to unmarshal input: %w", err) - } - return Upgrade(host, upgradeInput) -} - -func (u *Upgrader) ArtifactsURL() string { - return "tag://" + "op-contracts/v5.0.0" -} - -var DefaultUpgrader = new(Upgrader) diff --git a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go deleted file mode 100644 index 3f6e29fb3df83..0000000000000 --- a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_superchainconfig.go +++ /dev/null @@ -1,43 +0,0 @@ -package v5_0_0 - -import ( - "encoding/json" - "fmt" - - "github.com/ethereum-optimism/optimism/op-chain-ops/script" - "github.com/ethereum/go-ethereum/common" -) - -type UpgradeSuperchainConfigInput struct { - Prank common.Address `json:"prank"` - Opcm common.Address `json:"opcm"` - SuperchainConfig common.Address `json:"superchainConfig"` - SuperchainProxyAdmin common.Address `json:"superchainProxyAdmin"` -} - -type UpgradeSuperchainConfigScript script.DeployScriptWithoutOutput[UpgradeSuperchainConfigInput] - -// NewDeployImplementationsScript loads and validates the DeployImplementations script contract -func NewUpgradeSuperchainConfigScript(host *script.Host) (UpgradeSuperchainConfigScript, error) { - return script.NewDeployScriptWithoutOutputFromFile[UpgradeSuperchainConfigInput](host, "UpgradeSuperchainConfig.s.sol", "UpgradeSuperchainConfig") -} - -func UpgradeSuperchainConfig(host *script.Host, input UpgradeSuperchainConfigInput) error { - upgradeScript, err := NewUpgradeSuperchainConfigScript(host) - if err != nil { - return fmt.Errorf("failed to load UpgradeSuperchainConfig script: %w", err) - } - err = upgradeScript.Run(input) - if err != nil { - return fmt.Errorf("failed to run UpgradeSuperchainConfig script: %w", err) - } - return nil -} - -func (u *Upgrader) UpgradeSuperchainConfig(host *script.Host, input json.RawMessage) error { - var upgradeInput UpgradeSuperchainConfigInput - if err := json.Unmarshal(input, &upgradeInput); err != nil { - return fmt.Errorf("failed to unmarshal input: %w", err) - } - return UpgradeSuperchainConfig(host, upgradeInput) -} diff --git a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_test.go b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_test.go deleted file mode 100644 index 7e6b8b483d1c0..0000000000000 --- a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package v5_0_0 - -import ( - "encoding/hex" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" -) - -func TestUpgradeOPChainInput_OpChainConfigs(t *testing.T) { - input := &UpgradeOPChainInput{ - Prank: common.Address{0xaa}, - Opcm: common.Address{0xbb}, - EncodedChainConfigs: []OPChainConfig{ - { - SystemConfigProxy: common.Address{0x01}, - AbsolutePrestate: common.Hash{0x03}, - }, - { - SystemConfigProxy: common.Address{0x04}, - AbsolutePrestate: common.Hash{0x06}, - }, - }, - } - data, err := input.OpChainConfigs() - require.NoError(t, err) - require.Equal( - t, - "0000000000000000000000000000000000000000000000000000000000000020"+ - "0000000000000000000000000000000000000000000000000000000000000002"+ - "0000000000000000000000000100000000000000000000000000000000000000"+ - "0300000000000000000000000000000000000000000000000000000000000000"+ - "0000000000000000000000000400000000000000000000000000000000000000"+ - "0600000000000000000000000000000000000000000000000000000000000000", - hex.EncodeToString(data), - ) -} diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index fdfeb1b2f67da..6bbb75a15dda3 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -20,8 +20,8 @@ "sourceCodeHash": "0xfca613b5d055ffc4c3cbccb0773ddb9030abedc1aa6508c9e2e7727cc0cd617b" }, "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0x4025118658a1c56c4fc2d0166081e6d27da980318e749e7811c7178115e4413e", - "sourceCodeHash": "0xdb243ac7475b0214b8f662aa04f696d9ff213dade6b1bdade379e84df419b75a" + "initCodeHash": "0x0e6554a739bf23f53e2c9b4402ec35d0f866d821b3c8b7f7a83458375c9c7b52", + "sourceCodeHash": "0x79f24b19529294d070f3fd871d0bfa09e8e5e6ccee43c249fe0313e2b8046a46" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { "initCodeHash": "0x23c1f832faf49fe7843330c15c55541c53858cda975fd91e645b7602528a0c56", @@ -235,4 +235,4 @@ "initCodeHash": "0x2bfce526f82622288333d53ca3f43a0a94306ba1bab99241daa845f8f4b18bd4", "sourceCodeHash": "0xf49d7b0187912a6bb67926a3222ae51121e9239495213c975b3b4b217ee57a1b" } -} +} \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index de83ee25a12e5..3ce5afd36f27e 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -1902,9 +1902,9 @@ contract OPContractsManager is ISemver { // -------- Constants and Variables -------- - /// @custom:semver 4.2.0 + /// @custom:semver 4.3.0 function version() public pure virtual returns (string memory) { - return "4.2.0"; + return "4.3.0"; } OPContractsManagerGameTypeAdder public immutable opcmGameTypeAdder; From cfca5a3a0edeca49a9fcebbb72530861da8fd86f Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Mon, 20 Oct 2025 14:33:31 +0100 Subject: [PATCH 25/35] fixes --- packages/contracts-bedrock/test/L1/OPContractsManager.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol index b7c1b394e73b3..6fc8b84576618 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol @@ -244,7 +244,7 @@ contract OPContractsManager_Upgrade_Harness is CommonTest { // Create validationOverrides IOPContractsManagerStandardValidator.ValidationOverrides memory validationOverrides = IOPContractsManagerStandardValidator.ValidationOverrides({ - l1PAOMultisig: opChainConfigs[0].proxyAdmin.owner(), + l1PAOMultisig: opChainConfigs[0].systemConfigProxy.proxyAdmin().owner(), challenger: IPermissionedDisputeGame(address(disputeGameFactory.gameImpls(GameTypes.PERMISSIONED_CANNON))) .challenger() }); From c6903db802bc56972028ad0ba462e6e85fdedd3a Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Thu, 23 Oct 2025 13:46:32 +0100 Subject: [PATCH 26/35] fixes --- packages/contracts-bedrock/test/L1/OPContractsManager.t.sol | 2 +- .../test/L1/OPContractsManagerStandardValidator.t.sol | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol index 818643fdcf171..33ae9fbdebb6f 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol @@ -272,7 +272,7 @@ contract OPContractsManager_Upgrade_Harness is CommonTest, DisputeGames { // Create validationOverrides IOPContractsManagerStandardValidator.ValidationOverrides memory validationOverrides = IOPContractsManagerStandardValidator.ValidationOverrides({ - l1PAOMultisig: opChainConfigs[0].proxyAdmin.owner(), + l1PAOMultisig: opChainConfigs[0].systemConfigProxy.proxyAdmin().owner(), challenger: initialChallenger }); diff --git a/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol index 6d5e03bcb886a..c8cbfdbbef7e5 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol @@ -267,7 +267,6 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di return IOPContractsManager.AddGameInput({ saltMixer: "hello", systemConfig: systemConfig, - proxyAdmin: proxyAdmin, delayedWETH: delayedWeth, disputeGameType: _gameType, disputeAbsolutePrestate: absolutePrestate, From c7970c58dbf0aacf7cc3eab66924e88bfd03a87f Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Fri, 24 Oct 2025 13:00:52 +0100 Subject: [PATCH 27/35] fix semver and go lint --- op-devstack/sysgo/add_game_type.go | 7 ++++--- packages/contracts-bedrock/snapshots/semver-lock.json | 8 ++++---- packages/contracts-bedrock/src/L1/OPContractsManager.sol | 4 ++-- .../src/L1/OPContractsManagerStandardValidator.sol | 4 ++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/op-devstack/sysgo/add_game_type.go b/op-devstack/sysgo/add_game_type.go index 05de1a0e02a9d..0274928eae2ac 100644 --- a/op-devstack/sysgo/add_game_type.go +++ b/op-devstack/sysgo/add_game_type.go @@ -57,7 +57,6 @@ func addGameType(o *Orchestrator, absolutePrestate common.Hash, gameType uint32, L1ProxyAdminOwner: l1PAO, OPCMImpl: opcmAddr, SystemConfigProxy: o.wb.outL2Deployment[l2ChainID].SystemConfigProxyAddr(), - OPChainProxyAdmin: o.wb.outL2Deployment[l2ChainID].ProxyAdminAddr(), DelayedWETHProxy: o.wb.outL2Deployment[l2ChainID].PermissionlessDelayedWETHProxyAddr(), DisputeGameType: gameType, DisputeAbsolutePrestate: absolutePrestate, @@ -71,6 +70,8 @@ func addGameType(o *Orchestrator, absolutePrestate common.Hash, gameType uint32, SaltMixer: fmt.Sprintf("devstack-%s-%s", l2ChainID, absolutePrestate.Hex()), } + OPChainProxyAdmin := o.wb.outL2Deployment[l2ChainID].ProxyAdminAddr() + _, addGameTypeCalldata, err := manage.AddGameType(t.Ctx(), cfg) require.NoError(err, "failed to create add game type calldata") require.Len(addGameTypeCalldata, 1, "calldata must contain one entry") @@ -85,7 +86,7 @@ func addGameType(o *Orchestrator, absolutePrestate common.Hash, gameType uint32, t.Log("Deploying delegate call proxy contract") delegateCallProxy, proxyContract := deployDelegateCallProxy(t, transactOpts, client, l1PAO) // transfer ownership to the proxy so that we can delegatecall the opcm - transferOwnership(t, l1PAOKey, client, cfg.OPChainProxyAdmin, delegateCallProxy) + transferOwnership(t, l1PAOKey, client, OPChainProxyAdmin, delegateCallProxy) dgf := o.wb.outL2Deployment[l2ChainID].DisputeGameFactoryProxyAddr() transferOwnership(t, l1PAOKey, client, dgf, delegateCallProxy) @@ -96,7 +97,7 @@ func addGameType(o *Orchestrator, absolutePrestate common.Hash, gameType uint32, require.NoError(err, "failed to wait for add game type receipt") // reset ProxyAdmin ownership transfers - transferOwnershipForDelegateCallProxy(t, l1ChainID.ToBig(), l1PAOKey, client, delegateCallProxy, cfg.OPChainProxyAdmin, l1PAO) + transferOwnershipForDelegateCallProxy(t, l1ChainID.ToBig(), l1PAOKey, client, delegateCallProxy, OPChainProxyAdmin, l1PAO) transferOwnershipForDelegateCallProxy(t, l1ChainID.ToBig(), l1PAOKey, client, delegateCallProxy, dgf, l1PAO) } diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index 2ff4fcf1764be..8abaf8d689970 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -20,12 +20,12 @@ "sourceCodeHash": "0xfca613b5d055ffc4c3cbccb0773ddb9030abedc1aa6508c9e2e7727cc0cd617b" }, "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0xa6343febdc2345f7bee612295b339a482e00ec8dfb3179c694dfacb760cbeee3", - "sourceCodeHash": "0x4e6ac6762bceebed05925144c941a53a35fcdb325094c3957d42d472a0d8de5c" + "initCodeHash": "0x162cf9f50209d4d97c727d0b65514e7e4026219dd9b1fe82e18992ce22963a6b", + "sourceCodeHash": "0x40ccedbd08229550f49df419cae6f7dc3d527b9ccd6fa8a520d61707752d374a" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { - "initCodeHash": "0x5533a5f678bf7165614ab491a7f28a7240b729edfbfe2e28d4a3373c480502ff", - "sourceCodeHash": "0x2bd926024b3147071343a50fe1dfb6f731b9aedf0abfc47ae88a4d2c6dc0abc0" + "initCodeHash": "0xeb881ca04001717234c0cb055d92452b97ccb27b2462d8940c506210ccc93e93", + "sourceCodeHash": "0x7f74620fdc6461ff30373ab1cdcb34ce1c4c9330fbb1911fe7b9104dc4421996" }, "src/L1/OptimismPortal2.sol:OptimismPortal2": { "initCodeHash": "0x5bf576ea7f566e402a997204988471fc9b971410aa9dff8fe810b10baf6b7456", diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index b31418574ac39..8dd6de4eed911 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -2157,9 +2157,9 @@ contract OPContractsManager is ISemver { // -------- Constants and Variables -------- - /// @custom:semver 5.0.0 + /// @custom:semver 5.1.0 function version() public pure virtual returns (string memory) { - return "5.0.0"; + return "5.1.0"; } OPContractsManagerGameTypeAdder public immutable opcmGameTypeAdder; diff --git a/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol b/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol index 1700ede1060ef..b05ca3008131b 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol @@ -40,8 +40,8 @@ import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; /// before and after an upgrade. contract OPContractsManagerStandardValidator is ISemver { /// @notice The semantic version of the OPContractsManagerStandardValidator contract. - /// @custom:semver 2.0.0 - string public constant version = "2.0.0"; + /// @custom:semver 2.1.0 + string public constant version = "2.1.0"; /// @notice The SuperchainConfig contract. ISuperchainConfig public superchainConfig; From 985041fa885896e070b3610955dbc6b6e4860a93 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Fri, 24 Oct 2025 14:16:54 +0100 Subject: [PATCH 28/35] fix go test --- .../deployer/integration_test/apply_test.go | 7 +-- .../pkg/deployer/upgrade/v5_0_0/upgrade.go | 56 +++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index 012a636870482..8af28b78f0f28 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -36,7 +36,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/embedded" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v2_0_0" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v5_0_0" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/holiman/uint256" @@ -232,13 +232,12 @@ func TestEndToEndBootstrapApplyWithUpgrade(t *testing.T) { // Then run the OPCM upgrade t.Run("upgrade opcm", func(t *testing.T) { - upgradeConfig := v2_0_0.UpgradeOPChainInput{ + upgradeConfig := v5_0_0.UpgradeOPChainInput{ Prank: superchainProxyAdminOwner, Opcm: impls.Opcm, - EncodedChainConfigs: []v2_0_0.OPChainConfig{ + EncodedChainConfigs: []v5_0_0.OPChainConfig{ { SystemConfigProxy: common.HexToAddress("034edD2A225f7f429A63E0f1D2084B9E0A93b538"), - ProxyAdmin: superchainProxyAdmin, AbsolutePrestate: common.Hash{'A', 'P'}, }, }, diff --git a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go new file mode 100644 index 0000000000000..0ef089451b1b6 --- /dev/null +++ b/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go @@ -0,0 +1,56 @@ +package v5_0_0 + +import ( + "encoding/json" + "fmt" + + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" + "github.com/ethereum/go-ethereum/common" + "github.com/lmittmann/w3" +) + +type UpgradeOPChainInput struct { + Prank common.Address `json:"prank"` + Opcm common.Address `json:"opcm"` + EncodedChainConfigs []OPChainConfig `evm:"-" json:"chainConfigs"` +} + +type OPChainConfig struct { + SystemConfigProxy common.Address `json:"systemConfigProxy"` + AbsolutePrestate common.Hash `json:"absolutePrestate"` +} + +var opChainConfigEncoder = w3.MustNewFunc("dummy((address systemConfigProxy,bytes32 absolutePrestate)[])", "") + +func (u *UpgradeOPChainInput) OpChainConfigs() ([]byte, error) { + data, err := opChainConfigEncoder.EncodeArgs(u.EncodedChainConfigs) + if err != nil { + return nil, fmt.Errorf("failed to encode chain configs: %w", err) + } + return data[4:], nil +} + +type UpgradeOPChain struct { + Run func(input common.Address) +} + +func Upgrade(host *script.Host, input UpgradeOPChainInput) error { + return opcm.RunScriptVoid[UpgradeOPChainInput](host, input, "UpgradeOPChain.s.sol", "UpgradeOPChain") +} + +type Upgrader struct{} + +func (u *Upgrader) Upgrade(host *script.Host, input json.RawMessage) error { + var upgradeInput UpgradeOPChainInput + if err := json.Unmarshal(input, &upgradeInput); err != nil { + return fmt.Errorf("failed to unmarshal input: %w", err) + } + return Upgrade(host, upgradeInput) +} + +func (u *Upgrader) ArtifactsURL() string { + return "tag://" + "op-contracts/v5.0.0" +} + +var DefaultUpgrader = new(Upgrader) From c417dd91f8bf987c9e074bd4e9af73b47f7c6c72 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Fri, 24 Oct 2025 14:44:51 +0100 Subject: [PATCH 29/35] fix go test --- op-deployer/pkg/deployer/upgrade/embedded/upgrade.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go b/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go index eaa7bad52d4b0..49c28f98ce613 100644 --- a/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go +++ b/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go @@ -5,14 +5,14 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/script" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts" - v200 "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v2_0_0" + v500 "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v5_0_0" ) type Upgrader struct { } func (u *Upgrader) Upgrade(host *script.Host, input json.RawMessage) error { - return v200.DefaultUpgrader.Upgrade(host, input) + return v500.DefaultUpgrader.Upgrade(host, input) } func (u *Upgrader) ArtifactsURL() string { From fc7b86f9e9e2728f97be47d1b831c9032e7c8a9c Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Sun, 26 Oct 2025 17:38:21 +0100 Subject: [PATCH 30/35] fix go test --- .../pkg/deployer/integration_test/apply_test.go | 14 ++++---------- .../contracts-bedrock/snapshots/semver-lock.json | 6 +++--- .../src/L1/OPContractsManager.sol | 9 +++------ 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index 13b732589cf38..c17416ab4f027 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -37,7 +37,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/embedded" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v2_0_0" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v5_0_0" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/holiman/uint256" @@ -718,11 +718,6 @@ func TestIntentConfiguration(t *testing.T) { func runEndToEndBootstrapAndApplyUpgradeTest(t *testing.T, afactsFS foundry.StatDirFs, implementationsConfig bootstrap.ImplementationsConfig) { lgr := implementationsConfig.Logger - forkedL1, stopL1, err := devnet.NewForkedSepolia(lgr) - require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, stopL1()) - }) ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second) defer cancel() @@ -734,7 +729,7 @@ func runEndToEndBootstrapAndApplyUpgradeTest(t *testing.T, afactsFS foundry.Stat // Now test the OPCM upgrade using the deployed impls.Opcm t.Run("opcm upgrade test", func(t *testing.T) { // Create script host for the upgrade - rpcClient, err := rpc.Dial(forkedL1.RPCUrl()) + rpcClient, err := rpc.Dial(implementationsConfig.L1RPCUrl) require.NoError(t, err) host, err := env.DefaultForkedScriptHost( @@ -762,13 +757,12 @@ func runEndToEndBootstrapAndApplyUpgradeTest(t *testing.T, afactsFS foundry.Stat // Then run the OPCM upgrade t.Run("upgrade opcm", func(t *testing.T) { - upgradeConfig := v2_0_0.UpgradeOPChainInput{ + upgradeConfig := v5_0_0.UpgradeOPChainInput{ Prank: superchainProxyAdminOwner, Opcm: impls.Opcm, - EncodedChainConfigs: []v2_0_0.OPChainConfig{ + EncodedChainConfigs: []v5_0_0.OPChainConfig{ { SystemConfigProxy: common.HexToAddress("034edD2A225f7f429A63E0f1D2084B9E0A93b538"), - ProxyAdmin: implementationsConfig.SuperchainProxyAdmin, AbsolutePrestate: common.Hash{'A', 'P'}, }, }, diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index 58e8fa6bdc1ee..9901a25116c1e 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -20,8 +20,8 @@ "sourceCodeHash": "0xfca613b5d055ffc4c3cbccb0773ddb9030abedc1aa6508c9e2e7727cc0cd617b" }, "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0x3c4a51c5845588b4d19570cc1bae0099c15f43051d66b41c28d27d3c918a2e72", - "sourceCodeHash": "0x4a011105a9c1019cef7f35aa8f6eef131c29c54078e1df57d2089a43f7d81f3a" + "initCodeHash": "0xd512509995f48682fd953aa5bb95ebc8b9d9c84766eb3e56214a482bbe47bbd1", + "sourceCodeHash": "0x4ff2ae63ef63f8e2104a6008d39fa4093b048fdb70b2a3b4db6cc3db4f9e81d6" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { "initCodeHash": "0xeb881ca04001717234c0cb055d92452b97ccb27b2462d8940c506210ccc93e93", @@ -235,4 +235,4 @@ "initCodeHash": "0x2bfce526f82622288333d53ca3f43a0a94306ba1bab99241daa845f8f4b18bd4", "sourceCodeHash": "0xf49d7b0187912a6bb67926a3222ae51121e9239495213c975b3b4b217ee57a1b" } -} +} \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index 021e4282afc1e..6aac3507143d2 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -1944,7 +1944,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { IDisputeGame(implementations().superPermissionedDisputeGameImpl), gameArgs ); - newDisputeGameFactory.setInitBond(GameTypes.SUPER_PERMISSIONED_CANNON, input.gameParameters.initBond); + newDisputeGameFactory.setInitBond(GameTypes.SUPER_PERMISSIONED_CANNON, _input.gameParameters.initBond); } // If the permissionless game is being used, set that up too. @@ -1969,9 +1969,6 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase { abi.encodeCall(IDelayedWETH.initialize, (portals[0].systemConfig())) ); - // Fix stack too deep - MigrateInput memory input = _input; - // Register the new SuperFaultDisputeGame. bytes memory gameArgs = LibGameArgs.encode( LibGameArgs.GameArgs({ @@ -2119,9 +2116,9 @@ contract OPContractsManager is ISemver { // -------- Constants and Variables -------- - /// @custom:semver 5.1.0 + /// @custom:semver 5.2.0 function version() public pure virtual returns (string memory) { - return "5.1.0"; + return "5.2.0"; } OPContractsManagerGameTypeAdder public immutable opcmGameTypeAdder; From 27235d4798bb4821d1ef5ddb8286c0d42564616e Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Mon, 27 Oct 2025 17:48:15 +0100 Subject: [PATCH 31/35] fixes --- op-deployer/pkg/deployer/integration_test/apply_test.go | 6 +++--- op-deployer/pkg/deployer/upgrade/embedded/upgrade.go | 4 ++-- .../pkg/deployer/upgrade/{v5_0_0 => v6_0_0}/upgrade.go | 2 +- packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename op-deployer/pkg/deployer/upgrade/{v5_0_0 => v6_0_0}/upgrade.go (99%) diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index c17416ab4f027..ba12902311d12 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -37,7 +37,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/embedded" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v5_0_0" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v6_0_0" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/holiman/uint256" @@ -757,10 +757,10 @@ func runEndToEndBootstrapAndApplyUpgradeTest(t *testing.T, afactsFS foundry.Stat // Then run the OPCM upgrade t.Run("upgrade opcm", func(t *testing.T) { - upgradeConfig := v5_0_0.UpgradeOPChainInput{ + upgradeConfig := v6_0_0.UpgradeOPChainInput{ Prank: superchainProxyAdminOwner, Opcm: impls.Opcm, - EncodedChainConfigs: []v5_0_0.OPChainConfig{ + EncodedChainConfigs: []v6_0_0.OPChainConfig{ { SystemConfigProxy: common.HexToAddress("034edD2A225f7f429A63E0f1D2084B9E0A93b538"), AbsolutePrestate: common.Hash{'A', 'P'}, diff --git a/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go b/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go index 49c28f98ce613..ac07c572c4911 100644 --- a/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go +++ b/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go @@ -5,14 +5,14 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/script" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts" - v500 "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v5_0_0" + v600 "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v6_0_0" ) type Upgrader struct { } func (u *Upgrader) Upgrade(host *script.Host, input json.RawMessage) error { - return v500.DefaultUpgrader.Upgrade(host, input) + return v600.DefaultUpgrader.Upgrade(host, input) } func (u *Upgrader) ArtifactsURL() string { diff --git a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go b/op-deployer/pkg/deployer/upgrade/v6_0_0/upgrade.go similarity index 99% rename from op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go rename to op-deployer/pkg/deployer/upgrade/v6_0_0/upgrade.go index 0ef089451b1b6..1858331341067 100644 --- a/op-deployer/pkg/deployer/upgrade/v5_0_0/upgrade.go +++ b/op-deployer/pkg/deployer/upgrade/v6_0_0/upgrade.go @@ -1,4 +1,4 @@ -package v5_0_0 +package v6_0_0 import ( "encoding/json" diff --git a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol index eac9e19f17e4a..437bfe41ba934 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol @@ -203,7 +203,7 @@ contract UpgradeOPChain_Test is Test { upgradeOPChain.run(uoci); } - function test_upgrade_unexpectedEncoding_reverts( + function testFuzz_upgrade_unexpectedEncoding_reverts( IOPContractsManager.OpChainConfig[] memory _opChainConfigs, IOPContractsManagerPre4_1_0.OpChainConfig[] memory _opChainConfigsPre410 ) From 2c6c29c9eceff2b5d400a650565211c1ac403a11 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Thu, 30 Oct 2025 15:10:07 +0100 Subject: [PATCH 32/35] fixes for add game type go test --- .../pkg/deployer/manage/add_game_type_test.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/op-deployer/pkg/deployer/manage/add_game_type_test.go b/op-deployer/pkg/deployer/manage/add_game_type_test.go index 409bad131bc62..0f7aa80435abf 100644 --- a/op-deployer/pkg/deployer/manage/add_game_type_test.go +++ b/op-deployer/pkg/deployer/manage/add_game_type_test.go @@ -19,6 +19,7 @@ import ( "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/superchain" "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" ) @@ -26,7 +27,7 @@ import ( func TestAddGameType(t *testing.T) { // Since the opcm version is not yet on sepolia, we create a fork of sepolia then deploy the opcm via deploy implementations. lgr := testlog.Logger(t, slog.LevelDebug) - forkedL1, stopL1, err := devnet.NewForkedSepoliaFromBlock(lgr, 9366100) + forkedL1, stopL1, err := devnet.NewForkedSepolia(lgr) pkHex, _, _ := shared.DefaultPrivkey(t) require.NoError(t, err) t.Cleanup(func() { @@ -68,14 +69,19 @@ func TestAddGameType(t *testing.T) { }) require.NoError(t, err) + chain, err := superchain.GetChain(11155420) + require.NoError(t, err) + chainConfig, err := chain.Config() + require.NoError(t, err) + cfg := AddGameTypeConfig{ L1RPCUrl: forkedL1.RPCUrl(), Logger: testlog.Logger(t, slog.LevelInfo), ArtifactsLocator: afacts, SaltMixer: "foo", // The values below were pulled from the Superchain Registry for OP Sepolia. - SystemConfigProxy: common.HexToAddress("034edD2A225f7f429A63E0f1D2084B9E0A93b538"), - DelayedWETHProxy: common.HexToAddress("1Bf7Ea64F9339CE5468c2947151c18E2a1229B76"), + SystemConfigProxy: *chainConfig.Addresses.SystemConfigProxy, + DelayedWETHProxy: common.Address{}, // Let the OPCM create a new one. DisputeGameType: 0, DisputeAbsolutePrestate: common.HexToHash("0x1234"), DisputeMaxGameDepth: big.NewInt(73), @@ -98,6 +104,7 @@ func TestAddGameType(t *testing.T) { require.Equal(t, 1, len(broadcasts)) // Selector for addGameType + // Gotten from `cast sig "addGameType((string,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[])"` require.EqualValues(t, []byte{0x60, 0x4a, 0xa6, 0x28}, broadcasts[0].Data[0:4]) require.NotEqual(t, common.Address{}, output.DelayedWETHProxy) From a1dfe9e64e8ce2acc5dceef10d841fa21a234308 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Thu, 30 Oct 2025 15:33:06 +0100 Subject: [PATCH 33/35] fixes --- .../deployer/integration_test/apply_test.go | 5 +- .../pkg/deployer/upgrade/embedded/upgrade.go | 41 ++++- .../pkg/deployer/upgrade/v6_0_0/upgrade.go | 56 ------- .../interfaces/L1/IOPContractsManager.sol | 33 ---- .../scripts/deploy/UpgradeOPChain.s.sol | 116 ++++---------- .../test/opcm/UpgradeOPChain.t.sol | 151 ++++-------------- 6 files changed, 95 insertions(+), 307 deletions(-) delete mode 100644 op-deployer/pkg/deployer/upgrade/v6_0_0/upgrade.go diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index ba12902311d12..5e3aa96b92a11 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -37,7 +37,6 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/embedded" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v6_0_0" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/holiman/uint256" @@ -757,10 +756,10 @@ func runEndToEndBootstrapAndApplyUpgradeTest(t *testing.T, afactsFS foundry.Stat // Then run the OPCM upgrade t.Run("upgrade opcm", func(t *testing.T) { - upgradeConfig := v6_0_0.UpgradeOPChainInput{ + upgradeConfig := embedded.UpgradeOPChainInput{ Prank: superchainProxyAdminOwner, Opcm: impls.Opcm, - EncodedChainConfigs: []v6_0_0.OPChainConfig{ + EncodedChainConfigs: []embedded.OPChainConfig{ { SystemConfigProxy: common.HexToAddress("034edD2A225f7f429A63E0f1D2084B9E0A93b538"), AbsolutePrestate: common.Hash{'A', 'P'}, diff --git a/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go b/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go index ac07c572c4911..93803f5f3540c 100644 --- a/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go +++ b/op-deployer/pkg/deployer/upgrade/embedded/upgrade.go @@ -2,17 +2,52 @@ package embedded import ( "encoding/json" + "fmt" "github.com/ethereum-optimism/optimism/op-chain-ops/script" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts" - v600 "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v6_0_0" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" + "github.com/ethereum/go-ethereum/common" + "github.com/lmittmann/w3" ) -type Upgrader struct { +type UpgradeOPChainInput struct { + Prank common.Address `json:"prank"` + Opcm common.Address `json:"opcm"` + EncodedChainConfigs []OPChainConfig `evm:"-" json:"chainConfigs"` } +type OPChainConfig struct { + SystemConfigProxy common.Address `json:"systemConfigProxy"` + AbsolutePrestate common.Hash `json:"absolutePrestate"` +} + +var opChainConfigEncoder = w3.MustNewFunc("dummy((address systemConfigProxy,bytes32 absolutePrestate)[])", "") + +func (u *UpgradeOPChainInput) OpChainConfigs() ([]byte, error) { + data, err := opChainConfigEncoder.EncodeArgs(u.EncodedChainConfigs) + if err != nil { + return nil, fmt.Errorf("failed to encode chain configs: %w", err) + } + return data[4:], nil +} + +type UpgradeOPChain struct { + Run func(input common.Address) +} + +func Upgrade(host *script.Host, input UpgradeOPChainInput) error { + return opcm.RunScriptVoid[UpgradeOPChainInput](host, input, "UpgradeOPChain.s.sol", "UpgradeOPChain") +} + +type Upgrader struct{} + func (u *Upgrader) Upgrade(host *script.Host, input json.RawMessage) error { - return v600.DefaultUpgrader.Upgrade(host, input) + var upgradeInput UpgradeOPChainInput + if err := json.Unmarshal(input, &upgradeInput); err != nil { + return fmt.Errorf("failed to unmarshal input: %w", err) + } + return Upgrade(host, upgradeInput) } func (u *Upgrader) ArtifactsURL() string { diff --git a/op-deployer/pkg/deployer/upgrade/v6_0_0/upgrade.go b/op-deployer/pkg/deployer/upgrade/v6_0_0/upgrade.go deleted file mode 100644 index 1858331341067..0000000000000 --- a/op-deployer/pkg/deployer/upgrade/v6_0_0/upgrade.go +++ /dev/null @@ -1,56 +0,0 @@ -package v6_0_0 - -import ( - "encoding/json" - "fmt" - - "github.com/ethereum-optimism/optimism/op-chain-ops/script" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" - "github.com/ethereum/go-ethereum/common" - "github.com/lmittmann/w3" -) - -type UpgradeOPChainInput struct { - Prank common.Address `json:"prank"` - Opcm common.Address `json:"opcm"` - EncodedChainConfigs []OPChainConfig `evm:"-" json:"chainConfigs"` -} - -type OPChainConfig struct { - SystemConfigProxy common.Address `json:"systemConfigProxy"` - AbsolutePrestate common.Hash `json:"absolutePrestate"` -} - -var opChainConfigEncoder = w3.MustNewFunc("dummy((address systemConfigProxy,bytes32 absolutePrestate)[])", "") - -func (u *UpgradeOPChainInput) OpChainConfigs() ([]byte, error) { - data, err := opChainConfigEncoder.EncodeArgs(u.EncodedChainConfigs) - if err != nil { - return nil, fmt.Errorf("failed to encode chain configs: %w", err) - } - return data[4:], nil -} - -type UpgradeOPChain struct { - Run func(input common.Address) -} - -func Upgrade(host *script.Host, input UpgradeOPChainInput) error { - return opcm.RunScriptVoid[UpgradeOPChainInput](host, input, "UpgradeOPChain.s.sol", "UpgradeOPChain") -} - -type Upgrader struct{} - -func (u *Upgrader) Upgrade(host *script.Host, input json.RawMessage) error { - var upgradeInput UpgradeOPChainInput - if err := json.Unmarshal(input, &upgradeInput); err != nil { - return fmt.Errorf("failed to unmarshal input: %w", err) - } - return Upgrade(host, upgradeInput) -} - -func (u *Upgrader) ArtifactsURL() string { - return "tag://" + "op-contracts/v5.0.0" -} - -var DefaultUpgrader = new(Upgrader) diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol index 9bac67e1f0278..9ef61d9c397c4 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol @@ -385,36 +385,3 @@ interface IOPContractsManager { /// @notice Returns the implementation contract addresses. function implementations() external view returns (Implementations memory); } - -interface IOPContractsManagerPre4_1_0 { - struct AddGameInput { - string saltMixer; - ISystemConfig systemConfig; - IProxyAdmin proxyAdmin; - IDelayedWETH delayedWETH; - GameType disputeGameType; - Claim disputeAbsolutePrestate; - uint256 disputeMaxGameDepth; - uint256 disputeSplitDepth; - Duration disputeClockExtension; - Duration disputeMaxClockDuration; - uint256 initialBond; - IBigStepper vm; - bool permissioned; - } - - struct AddGameOutput { - IDelayedWETH delayedWETH; - IFaultDisputeGame faultDisputeGame; - } - - struct OpChainConfig { - ISystemConfig systemConfigProxy; - IProxyAdmin proxyAdmin; - Claim absolutePrestate; - } - - function addGameType(AddGameInput[] memory _gameConfigs) external returns (AddGameOutput[] memory); - - function upgrade(OpChainConfig[] memory _opChainConfigs) external; -} diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index 8f177faadaf2b..d238b55edc23c 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -2,137 +2,75 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; -import { IOPContractsManager, IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; contract UpgradeOPChainInput is BaseDeployIO { address internal _prank; - IOPContractsManager internal _opcm; + OPContractsManager internal _opcm; bytes _opChainConfigs; // Setter for OPContractsManager type function set(bytes4 _sel, address _value) public { - require(address(_value) != address(0), "UpgradeOPChainInput: cannot set zero address"); + require(address(_value) != address(0), "UpgradeOPCMInput: cannot set zero address"); if (_sel == this.prank.selector) _prank = _value; - else if (_sel == this.opcm.selector) _opcm = IOPContractsManager(_value); - else revert("UpgradeOPChainInput: unknown selector"); + else if (_sel == this.opcm.selector) _opcm = OPContractsManager(_value); + else revert("UpgradeOPCMInput: unknown selector"); } - function set(bytes4 _sel, bytes memory _value) public { - require(_value.length > 64, "UpgradeOPChainInput: cannot set empty array"); + function set(bytes4 _sel, OPContractsManager.OpChainConfig[] memory _value) public { + require(_value.length > 0, "UpgradeOPCMInput: cannot set empty array"); - if (_sel == this.opChainConfigs.selector) _opChainConfigs = _value; - else revert("UpgradeOPChainInput: unknown selector"); + if (_sel == this.opChainConfigs.selector) _opChainConfigs = abi.encode(_value); + else revert("UpgradeOPCMInput: unknown selector"); } function prank() public view returns (address) { - require(address(_prank) != address(0), "UpgradeOPChainInput: prank not set"); + require(address(_prank) != address(0), "UpgradeOPCMInput: prank not set"); return _prank; } - function opcm() public view returns (IOPContractsManager) { - require(address(_opcm) != address(0), "UpgradeOPChainInput: opcm not set"); + function opcm() public view returns (OPContractsManager) { + require(address(_opcm) != address(0), "UpgradeOPCMInput: not set"); return _opcm; } function opChainConfigs() public view returns (bytes memory) { - require(_opChainConfigs.length > 0, "UpgradeOPChainInput: opChainConfigs not set"); - + require(_opChainConfigs.length > 0, "UpgradeOPCMInput: not set"); return _opChainConfigs; } } contract UpgradeOPChain is Script { function run(UpgradeOPChainInput _uoci) external { - IOPContractsManager opcm = _uoci.opcm(); + OPContractsManager opcm = _uoci.opcm(); + OPContractsManager.OpChainConfig[] memory opChainConfigs = + abi.decode(_uoci.opChainConfigs(), (OPContractsManager.OpChainConfig[])); // Etch DummyCaller contract. This contract is used to mimic the contract that is used // as the source of the delegatecall to the OPCM. In practice this will be the governance // 2/2 or similar. address prank = _uoci.prank(); - - // From OPCM version 4.1.0, the proxyAdmin was removed from the OpChainConfig struct so we do create support for - // both interface variants. - if (SemverComp.lt(opcm.version(), "4.1.0")) { - bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCallerPreOPCM4_1_0"); - vm.etch(prank, code); - - vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); - vm.label(prank, "DummyCaller"); - - bytes memory encoded = _uoci.opChainConfigs(); - IOPContractsManagerPre4_1_0.OpChainConfig[] memory opChainConfigs = - abi.decode(encoded, (IOPContractsManagerPre4_1_0.OpChainConfig[])); - - // apart from the offset and length that take up 64 bytes, the rest should be a multiple of 96 bytes - // (systemConfigProxy, proxyAdmin and absolutePrestate) - require( - (((encoded.length - 64) / 96) == opChainConfigs.length) && (((encoded.length - 64) % 96) == 0), - "UpgradeOPChain: opChainConfigsPre410 Unexpected encoding" - ); - - // Call into the DummyCaller to perform the delegatecall - vm.broadcast(msg.sender); - - (bool success,) = DummyCallerPreOPCM4_1_0(prank).upgrade(opChainConfigs); - require(success, "UpgradeOPChain: Pre4_1_0 upgrade failed"); - } else { - bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCaller"); - vm.etch(prank, code); - - vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); - vm.label(prank, "DummyCaller"); - - bytes memory encoded = _uoci.opChainConfigs(); - IOPContractsManager.OpChainConfig[] memory opChainConfigs = - abi.decode(encoded, (IOPContractsManager.OpChainConfig[])); - - // apart from the offset and length that take up 64 bytes, the rest should be a multiple of 64 bytes - // (systemConfigProxy and absolutePrestate) - require( - ((encoded.length - 64) / 64 == opChainConfigs.length) && (((encoded.length - 64) % 64) == 0), - "UpgradeOPChain: opChainConfigs Unexpected encoding" - ); - - // Call into the DummyCaller to perform the delegatecall - vm.broadcast(msg.sender); - - (bool success,) = DummyCaller(prank).upgrade(opChainConfigs); - require(success, "UpgradeOPChain: upgrade failed"); - } + bytes memory code = vm.getDeployedCode("UpgradeOPChain.s.sol:DummyCaller"); + vm.etch(prank, code); + vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); + vm.label(prank, "DummyCaller"); + + // Call into the DummyCaller. This will perform the delegatecall under the hood and + // return the result. + vm.broadcast(msg.sender); + (bool success,) = DummyCaller(prank).upgrade(opChainConfigs); + require(success, "UpgradeChain: upgrade failed"); } } -/// @title DummyCaller -/// @notice This contract is used to mimic the contract that is used as the source of the delegatecall to the OPCM. -/// @dev This contract is used for OPCM versions 4.1.0 and above. contract DummyCaller { address internal _opcmAddr; - function upgrade(IOPContractsManager.OpChainConfig[] memory _opChainConfigs) - external - returns (bool, bytes memory) - { + function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs) external returns (bool, bytes memory) { bytes memory data = abi.encodeCall(DummyCaller.upgrade, _opChainConfigs); (bool success, bytes memory result) = _opcmAddr.delegatecall(data); return (success, result); } } - -/// @title DummyCallerPreOPCM4_1_0 -/// @notice This contract is used to mimic the contract that is used as the source of the delegatecall to the OPCM. -/// @dev This contract is used for OPCM versions 4.1.0 and below. -contract DummyCallerPreOPCM4_1_0 { - address internal _opcmAddr; - - function upgrade(IOPContractsManagerPre4_1_0.OpChainConfig[] memory _opChainConfigs) - external - returns (bool, bytes memory) - { - bytes memory data = abi.encodeCall(DummyCallerPreOPCM4_1_0.upgrade, _opChainConfigs); - (bool success, bytes memory result) = _opcmAddr.delegatecall(data); - return (success, result); - } -} diff --git a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol index 437bfe41ba934..264aecb0058a3 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol @@ -5,9 +5,8 @@ import { Test } from "forge-std/Test.sol"; import { Claim } from "src/dispute/lib/Types.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { IOPContractsManager, IOPContractsManagerPre4_1_0 } from "interfaces/L1/IOPContractsManager.sol"; +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { UpgradeOPChain, UpgradeOPChainInput } from "scripts/deploy/UpgradeOPChain.s.sol"; contract UpgradeOPChainInput_Test is Test { @@ -18,13 +17,13 @@ contract UpgradeOPChainInput_Test is Test { } function test_getters_whenNotSet_reverts() public { - vm.expectRevert("UpgradeOPChainInput: prank not set"); + vm.expectRevert("UpgradeOPCMInput: prank not set"); input.prank(); - vm.expectRevert("UpgradeOPChainInput: opcm not set"); + vm.expectRevert("UpgradeOPCMInput: not set"); input.opcm(); - vm.expectRevert("UpgradeOPChainInput: opChainConfigs not set"); + vm.expectRevert("UpgradeOPCMInput: not set"); input.opChainConfigs(); } @@ -44,7 +43,7 @@ contract UpgradeOPChainInput_Test is Test { function test_setOpChainConfigs_succeeds() public { // Create sample OpChainConfig array - IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](2); + OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](2); // Setup mock addresses and contracts for first config address systemConfig1 = makeAddr("systemConfig1"); @@ -52,7 +51,7 @@ contract UpgradeOPChainInput_Test is Test { vm.etch(systemConfig1, hex"01"); vm.etch(proxyAdmin1, hex"01"); - configs[0] = IOPContractsManager.OpChainConfig({ + configs[0] = OPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(systemConfig1), absolutePrestate: Claim.wrap(bytes32(uint256(1))) }); @@ -63,192 +62,98 @@ contract UpgradeOPChainInput_Test is Test { vm.etch(systemConfig2, hex"01"); vm.etch(proxyAdmin2, hex"01"); - configs[1] = IOPContractsManager.OpChainConfig({ + configs[1] = OPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(systemConfig2), absolutePrestate: Claim.wrap(bytes32(uint256(2))) }); - input.set(input.opChainConfigs.selector, abi.encode(configs)); + input.set(input.opChainConfigs.selector, configs); bytes memory storedConfigs = input.opChainConfigs(); assertEq(storedConfigs, abi.encode(configs)); // Additional verification of stored claims if needed - IOPContractsManager.OpChainConfig[] memory decodedConfigs = - abi.decode(storedConfigs, (IOPContractsManager.OpChainConfig[])); + OPContractsManager.OpChainConfig[] memory decodedConfigs = + abi.decode(storedConfigs, (OPContractsManager.OpChainConfig[])); assertEq(Claim.unwrap(decodedConfigs[0].absolutePrestate), bytes32(uint256(1))); assertEq(Claim.unwrap(decodedConfigs[1].absolutePrestate), bytes32(uint256(2))); } function test_setAddress_withZeroAddress_reverts() public { - vm.expectRevert("UpgradeOPChainInput: cannot set zero address"); + vm.expectRevert("UpgradeOPCMInput: cannot set zero address"); input.set(input.prank.selector, address(0)); - vm.expectRevert("UpgradeOPChainInput: cannot set zero address"); + vm.expectRevert("UpgradeOPCMInput: cannot set zero address"); input.set(input.opcm.selector, address(0)); } function test_setOpChainConfigs_withEmptyArray_reverts() public { - IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](0); - vm.expectRevert("UpgradeOPChainInput: cannot set empty array"); - input.set(input.opChainConfigs.selector, abi.encode(configs)); + OPContractsManager.OpChainConfig[] memory emptyConfigs = new OPContractsManager.OpChainConfig[](0); - vm.expectRevert("UpgradeOPChainInput: cannot set empty array"); - input.set(input.opChainConfigs.selector, new bytes(0)); + vm.expectRevert("UpgradeOPCMInput: cannot set empty array"); + input.set(input.opChainConfigs.selector, emptyConfigs); } function test_set_withInvalidSelector_reverts() public { - vm.expectRevert("UpgradeOPChainInput: unknown selector"); + vm.expectRevert("UpgradeOPCMInput: unknown selector"); input.set(bytes4(0xdeadbeef), makeAddr("test")); // Create a single config for testing invalid selector - IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](1); + OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](1); address mockSystemConfig = makeAddr("systemConfig"); address mockProxyAdmin = makeAddr("proxyAdmin"); vm.etch(mockSystemConfig, hex"01"); vm.etch(mockProxyAdmin, hex"01"); - configs[0] = IOPContractsManager.OpChainConfig({ + configs[0] = OPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(mockSystemConfig), absolutePrestate: Claim.wrap(bytes32(uint256(1))) }); - vm.expectRevert("UpgradeOPChainInput: unknown selector"); - input.set(bytes4(0xdeadbeef), abi.encode(configs)); + vm.expectRevert("UpgradeOPCMInput: unknown selector"); + input.set(bytes4(0xdeadbeef), configs); } } contract MockOPCM { event UpgradeCalled(address indexed sysCfgProxy, bytes32 indexed absolutePrestate); - function upgrade(IOPContractsManager.OpChainConfig[] memory _opChainConfigs) public { + function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs) public { emit UpgradeCalled( address(_opChainConfigs[0].systemConfigProxy), Claim.unwrap(_opChainConfigs[0].absolutePrestate) ); } - - function version() public pure returns (string memory) { - return "4.1.0"; - } -} - -contract MockOPCMPre410 { - event UpgradeCalled(address indexed sysCfgProxy, address indexed proxyAdmin, bytes32 indexed absolutePrestate); - - function upgrade(IOPContractsManagerPre4_1_0.OpChainConfig[] memory _opChainConfigs) public { - emit UpgradeCalled( - address(_opChainConfigs[0].systemConfigProxy), - address(_opChainConfigs[0].proxyAdmin), - Claim.unwrap(_opChainConfigs[0].absolutePrestate) - ); - } - - function version() public pure returns (string memory) { - return "4.0.0"; - } } contract UpgradeOPChain_Test is Test { - address mockOPCM; + MockOPCM mockOPCM; UpgradeOPChainInput uoci; - IOPContractsManager.OpChainConfig config; + OPContractsManager.OpChainConfig config; UpgradeOPChain upgradeOPChain; address prank; event UpgradeCalled(address indexed sysCfgProxy, bytes32 indexed absolutePrestate); - event UpgradeCalled(address indexed sysCfgProxy, address indexed proxyAdmin, bytes32 indexed absolutePrestate); function setUp() public virtual { - mockOPCM = address(new MockOPCM()); + mockOPCM = new MockOPCM(); uoci = new UpgradeOPChainInput(); - uoci.set(uoci.opcm.selector, mockOPCM); - config = IOPContractsManager.OpChainConfig({ + uoci.set(uoci.opcm.selector, address(mockOPCM)); + config = OPContractsManager.OpChainConfig({ systemConfigProxy: ISystemConfig(makeAddr("systemConfigProxy")), absolutePrestate: Claim.wrap(keccak256("absolutePrestate")) }); - IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](1); + OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](1); configs[0] = config; - uoci.set(uoci.opChainConfigs.selector, abi.encode(configs)); + uoci.set(uoci.opChainConfigs.selector, configs); prank = makeAddr("prank"); uoci.set(uoci.prank.selector, prank); upgradeOPChain = new UpgradeOPChain(); } function test_upgrade_succeeds() public { - // For opcm >= 4.1.0 // UpgradeCalled should be emitted by the prank since it's a delegate call. vm.expectEmit(address(prank)); emit UpgradeCalled(address(config.systemConfigProxy), Claim.unwrap(config.absolutePrestate)); upgradeOPChain.run(uoci); - - // For opcm < 4.1.0 - IOPContractsManagerPre4_1_0.OpChainConfig memory configPre410 = IOPContractsManagerPre4_1_0.OpChainConfig({ - systemConfigProxy: ISystemConfig(makeAddr("systemConfigProxy")), - proxyAdmin: IProxyAdmin(makeAddr("proxyAdmin")), - absolutePrestate: Claim.wrap(keccak256("absolutePrestate")) - }); - IOPContractsManagerPre4_1_0.OpChainConfig[] memory configsPre410 = - new IOPContractsManagerPre4_1_0.OpChainConfig[](1); - configsPre410[0] = configPre410; - uoci.set(uoci.opChainConfigs.selector, abi.encode(configsPre410)); - mockOPCM = address(new MockOPCMPre410()); - uoci.set(uoci.opcm.selector, mockOPCM); - // UpgradeCalled should be emitted by the prank since it's a delegate call. - vm.expectEmit(address(prank)); - emit UpgradeCalled( - address(configPre410.systemConfigProxy), - address(configPre410.proxyAdmin), - Claim.unwrap(configPre410.absolutePrestate) - ); - upgradeOPChain.run(uoci); - } - - function testFuzz_upgrade_unexpectedEncoding_reverts( - IOPContractsManager.OpChainConfig[] memory _opChainConfigs, - IOPContractsManagerPre4_1_0.OpChainConfig[] memory _opChainConfigsPre410 - ) - public - { - vm.assume(_opChainConfigsPre410.length > 0); - vm.assume(_opChainConfigs.length > 0); - - // Currently the mockOPCM set in the input contract is that of a version >= 4.1.0 - // So lets try to set opChainConfigs to be one of < 4.1.0 and expect a revert. - uoci.set(uoci.opChainConfigs.selector, abi.encode(_opChainConfigsPre410)); - // It can revert because it could not decode the opChainConfigs (this happens if it expects an address but sees - // a value with upper 12 bits dirty). If it does not see this it will still revert with a custom string error - // because it decoded into the wrong type. - (bool success, bytes memory result) = address(upgradeOPChain).call(abi.encodeCall(upgradeOPChain.run, (uoci))); - assertFalse(success, "UpgradeOPChain_Test: call should revert"); - assertTrue( - keccak256(result) - == keccak256( - bytes.concat( - bytes4(keccak256("Error(string)")), abi.encode("UpgradeOPChain: opChainConfigs Unexpected encoding") - ) - ) || keccak256(result) == keccak256(""), - "UpgradeOPChain_Test: result should be the expected error" - ); - - // Now lets set the mockOPCM to be a version < 4.1.0 and expect a revert when we set the opChainConfigs to be - // that of version >= 4.1.0 and calling run. - mockOPCM = address(new MockOPCMPre410()); - uoci.set(uoci.opcm.selector, mockOPCM); - uoci.set(uoci.opChainConfigs.selector, abi.encode(_opChainConfigs)); - // It can revert because it could not decode the opChainConfigs (this happens if it expects an address but sees - // a value with upper 12 bits dirty). If it does not see this it will still revert with a custom string error - // because it decoded into the wrong type. - (success, result) = address(upgradeOPChain).call(abi.encodeCall(upgradeOPChain.run, (uoci))); - assertFalse(success, "UpgradeOPChain_Test: opChainConfigsPre410 call should revert"); - assertTrue( - keccak256(result) - == keccak256( - bytes.concat( - bytes4(keccak256("Error(string)")), - abi.encode("UpgradeOPChain: opChainConfigsPre410 Unexpected encoding") - ) - ) || keccak256(result) == keccak256(""), - "UpgradeOPChain_Test: opChainConfigsPre410 result should be the expected error" - ); } } From f4b990e75178f36998f86015624fe61af3483115 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Thu, 30 Oct 2025 16:04:28 +0100 Subject: [PATCH 34/35] remove outdated test --- .../deployer/upgrade/v2_0_0/upgrade_test.go | 80 ------------------- 1 file changed, 80 deletions(-) diff --git a/op-deployer/pkg/deployer/upgrade/v2_0_0/upgrade_test.go b/op-deployer/pkg/deployer/upgrade/v2_0_0/upgrade_test.go index 95585401b1182..f4127089dd725 100644 --- a/op-deployer/pkg/deployer/upgrade/v2_0_0/upgrade_test.go +++ b/op-deployer/pkg/deployer/upgrade/v2_0_0/upgrade_test.go @@ -1,22 +1,10 @@ package v2_0_0 import ( - "context" "encoding/hex" - "log/slog" - "os" "testing" - "time" - "github.com/ethereum-optimism/optimism/op-service/testutils/devnet" - - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/env" - "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/require" ) @@ -52,71 +40,3 @@ func TestUpgradeOPChainInput_OpChainConfigs(t *testing.T) { hex.EncodeToString(data), ) } - -func TestUpgrader_Upgrade(t *testing.T) { - lgr := testlog.Logger(t, slog.LevelDebug) - - forkedL1, stopL1, err := devnet.NewForkedSepolia(lgr) - require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, stopL1()) - }) - l1RPC := forkedL1.RPCUrl() - - _, afactsFS := testutil.LocalArtifacts(t) - - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) - defer cancel() - - rpcClient, err := rpc.Dial(l1RPC) - require.NoError(t, err) - - bcast := new(broadcaster.CalldataBroadcaster) - host, err := env.DefaultForkedScriptHost( - ctx, - bcast, - lgr, - common.Address{'D'}, - afactsFS, - rpcClient, - ) - require.NoError(t, err) - - configFile, err := os.ReadFile("testdata/config.json") - require.NoError(t, err) - - upgrader := DefaultUpgrader - require.NoError(t, upgrader.Upgrade(host, configFile)) - - dump, err := bcast.Dump() - require.NoError(t, err) - - addr := common.HexToAddress("0x1Eb2fFc903729a0F03966B917003800b145F56E2") - require.True(t, dump[0].Value.ToInt().Cmp(common.Big0) == 0) - // Have to do this to normalize zero values which can either set nat to nil - // or to a zero value. They mean the same thing, but aren't equal according to - // EqualValues. - dump[0].Value = (*hexutil.Big)(common.Big0) - - require.EqualValues(t, []broadcaster.CalldataDump{ - { - To: &addr, - Data: []byte{ - 0xff, 0x2d, 0xd5, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0x4e, 0xdd, 0x2a, 0x22, 0x5f, 0x7f, 0x42, 0x9a, 0x63, 0xe0, - 0xf1, 0xd2, 0x08, 0x4b, 0x9e, 0x0a, 0x93, 0xb5, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x9a, 0xba, 0xaa, 0xa8, - 0x2d, 0xfc, 0x01, 0x5a, 0x58, 0x8a, 0x7d, 0xba, 0xd6, 0xf1, 0x3b, 0x1d, 0x34, - 0x85, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa, 0xbc, - }, - Value: (*hexutil.Big)(common.Big0), - }, - }, dump) -} From 6e13817fc2cc5fb01d5c4085645aae0c5dac1829 Mon Sep 17 00:00:00 2001 From: Michael Amadi Date: Thu, 30 Oct 2025 16:52:12 +0100 Subject: [PATCH 35/35] pull and fix --- packages/contracts-bedrock/snapshots/semver-lock.json | 4 ++-- packages/contracts-bedrock/src/L1/OPContractsManager.sol | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index c0dd650e0c211..0ad3d66132443 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -20,8 +20,8 @@ "sourceCodeHash": "0xfca613b5d055ffc4c3cbccb0773ddb9030abedc1aa6508c9e2e7727cc0cd617b" }, "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0xda0ac6ccdcd9d7a2dc8d1577301957bf127ad1c3c5dfa7f8c83e2bc4bd377903", - "sourceCodeHash": "0x3762e4d49d75e17ff15ab5aff1908c69803c85fac5cfea8a234a92e20b6eb77b" + "initCodeHash": "0xe264ff78622d5baea636012c17562a4f105182626c3a3841cc65912cb20dff9f", + "sourceCodeHash": "0x7e4a03b442d7b9bcd43cedabc15f98740345fb3d3224cbba3b4eedc6f2fcc65d" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { "initCodeHash": "0x0c8b15453d0f0bc5d9af07f104505e0bbb2b358f0df418289822fb73a8652b30", diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index be54447898550..6afcd986a6f5c 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -2116,9 +2116,9 @@ contract OPContractsManager is ISemver { // -------- Constants and Variables -------- - /// @custom:semver 5.2.0 + /// @custom:semver 5.3.0 function version() public pure virtual returns (string memory) { - return "5.2.0"; + return "5.3.0"; } OPContractsManagerGameTypeAdder public immutable opcmGameTypeAdder;