From fd99761e9af0cbe9e64b693db88538808dcda49c Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Jul 2026 12:21:23 +0000 Subject: [PATCH 1/3] contracts-bedrock: remove ReinitializableBase ReinitializableBase existed so that contracts could force re-initialization during upgrades by bumping an INIT_VERSION constant passed to the reinitializer() modifier. Since OPCM v2 (#18079), upgrades reset the initialized slot via StorageSetter before calling initialize(), so the version value no longer gates anything and the plain initializer modifier is sufficient. - Delete ReinitializableBase, IReinitializableBase, and their tests. - Replace reinitializer(initVersion()) with initializer in the 10 inheriting contracts and drop the initVersion() getter from their interfaces (minor semver bumps). - Simplify DeployUtils.assertInitialized to expect an initialized value of exactly 1 for proxies. - Drop the initVersion() special case from scripts/checks/reinitializer. - Remove the semgrep immutables exclusion for ReinitializableBase. - Update contract-dev and OPCM contributing docs accordingly. - Regenerate ABI snapshots and semver-lock. Co-Authored-By: Claude Co-authored-by: John Mardlin --- .semgrep/rules/sol-rules.yaml | 1 - docs/ai/contract-dev.md | 7 +- .../book/src/contributing/opcm.md | 14 ++-- .../interfaces/L1/IETHLockbox.sol | 3 +- .../interfaces/L1/IL1CrossDomainMessenger.sol | 2 - .../interfaces/L1/IL1ERC721Bridge.sol | 2 - .../interfaces/L1/IL1StandardBridge.sol | 2 - .../interfaces/L1/IOptimismPortal2.sol | 2 - .../interfaces/L1/ISuperchainConfig.sol | 2 - .../interfaces/L1/ISystemConfig.sol | 2 - .../dispute/IAnchorStateRegistry.sol | 2 - .../interfaces/dispute/IDelayedWETH.sol | 2 - .../dispute/IDisputeGameFactory.sol | 3 +- .../universal/IReinitializableBase.sol | 11 ---- .../scripts/checks/reinitializer/main.go | 26 +++----- .../scripts/checks/reinitializer/main_test.go | 64 +------------------ .../scripts/libraries/DeployUtils.sol | 15 +---- .../snapshots/abi/AnchorStateRegistry.json | 18 ------ .../snapshots/abi/DelayedWETH.json | 18 ------ .../snapshots/abi/DisputeGameFactory.json | 18 ------ .../snapshots/abi/ETHLockbox.json | 18 ------ .../snapshots/abi/L1CrossDomainMessenger.json | 18 ------ .../snapshots/abi/L1ERC721Bridge.json | 18 ------ .../snapshots/abi/L1StandardBridge.json | 18 ------ .../snapshots/abi/OptimismPortal2.json | 18 ------ .../snapshots/abi/SuperchainConfig.json | 18 ------ .../snapshots/abi/SystemConfig.json | 18 ------ .../snapshots/semver-lock.json | 40 ++++++------ .../contracts-bedrock/src/L1/ETHLockbox.sol | 11 ++-- .../src/L1/L1CrossDomainMessenger.sol | 11 ++-- .../src/L1/L1ERC721Bridge.sol | 11 ++-- .../src/L1/L1StandardBridge.sol | 11 ++-- .../src/L1/OptimismPortal2.sol | 11 ++-- .../src/L1/SuperchainConfig.sol | 11 ++-- .../contracts-bedrock/src/L1/SystemConfig.sol | 11 ++-- .../src/dispute/AnchorStateRegistry.sol | 11 ++-- .../src/dispute/DelayedWETH.sol | 11 ++-- .../src/dispute/DisputeGameFactory.sol | 11 ++-- .../src/universal/ReinitializableBase.sol | 25 -------- .../test/L1/ETHLockbox.t.sol | 2 +- .../test/L1/L1CrossDomainMessenger.t.sol | 2 +- .../test/L1/L1ERC721Bridge.t.sol | 2 +- .../test/L1/L1StandardBridge.t.sol | 2 +- .../test/L1/OptimismPortal2.t.sol | 4 +- .../test/L1/SuperchainConfig.t.sol | 2 +- .../test/L1/SystemConfig.t.sol | 2 +- .../test/dispute/AnchorStateRegistry.t.sol | 2 +- .../test/dispute/DelayedWETH.t.sol | 2 +- .../test/dispute/DisputeGameFactory.t.sol | 2 +- .../test/universal/ReinitializableBase.t.sol | 33 ---------- 50 files changed, 106 insertions(+), 464 deletions(-) delete mode 100644 packages/contracts-bedrock/interfaces/universal/IReinitializableBase.sol delete mode 100644 packages/contracts-bedrock/src/universal/ReinitializableBase.sol delete mode 100644 packages/contracts-bedrock/test/universal/ReinitializableBase.t.sol diff --git a/.semgrep/rules/sol-rules.yaml b/.semgrep/rules/sol-rules.yaml index b68c5168962..0b1876351c1 100644 --- a/.semgrep/rules/sol-rules.yaml +++ b/.semgrep/rules/sol-rules.yaml @@ -343,7 +343,6 @@ rules: - /packages/contracts-bedrock/src/safe/LivenessGuard.sol - /packages/contracts-bedrock/src/safe/LivenessModule.sol - /packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol - - /packages/contracts-bedrock/src/universal/ReinitializableBase.sol - id: sol-style-use-process-run languages: [solidity] diff --git a/docs/ai/contract-dev.md b/docs/ai/contract-dev.md index 6df435a3c49..185a8206b9c 100644 --- a/docs/ai/contract-dev.md +++ b/docs/ai/contract-dev.md @@ -143,8 +143,9 @@ Every new implementation contract must follow this pattern: 1. Extend OpenZeppelin's `Initializable`. 2. Include `initialize()` with the `initializer` modifier. 3. In the constructor: call `_disableInitializers()` and set immutables only. -4. Extend `ReinitializableBase(N)` with the current init version. -5. Never use `reinitializer(uint64 version)` — this codebase does not use it. +4. Never use `reinitializer(uint64 version)` — this codebase does not use it. Upgrades + re-initialize by zeroing the initialized slot first (see below), so plain + `initializer` is sufficient. ### Upgrade Process (Atomic 3-Step) @@ -207,7 +208,7 @@ import { ISemver } from "interfaces/universal/ISemver.sol"; /// @custom:proxied true /// @title ContractName /// @notice Description -contract ContractName is Initializable, ProxyAdminOwnedBase, ReinitializableBase, ISemver { +contract ContractName is Initializable, ProxyAdminOwnedBase, ISemver { // Constants and immutables // Custom errors // Events diff --git a/packages/contracts-bedrock/book/src/contributing/opcm.md b/packages/contracts-bedrock/book/src/contributing/opcm.md index 20baeab097e..3c0aaa6d7b2 100644 --- a/packages/contracts-bedrock/book/src/contributing/opcm.md +++ b/packages/contracts-bedrock/book/src/contributing/opcm.md @@ -100,15 +100,11 @@ Typically a contract's `initializer()` will be modified when a new storage varia needs to be set. This may either be done by adding a new argument to the `initializer()`, by reading a value from the environment, or by reading a value from another contract. -Whatever the case, a new `upgrade()` method should also be added which uses the same logic to set -the new storage variable. - -In addition, the contract should inherit from `ReinitializableBase` and the `initializer()` and `upgrade()` -methods should have the `reinitializer(reinitVersion())` modifier. - -The OPCM must then use `ProxyAdmin.upgradeAndCall()` to call the `upgrade()` method. Additionally, if the -input value is not read from the chain, then it will need to be passed in as input. This will -require a new field to be added to the `OpChainConfig` struct. +No special handling is required in the contract itself: the OPCM upgrade flow resets the +initialized slot (via `StorageSetter`) and then calls `initialize()` again with the full set of +inputs, so the plain `initializer` modifier is sufficient. If the new input value is not read from +the chain, then it will need to be passed in as input to the upgrade. This will require a new +field to be added to the `OpChainConfig` struct. ### New derivation path events are being added diff --git a/packages/contracts-bedrock/interfaces/L1/IETHLockbox.sol b/packages/contracts-bedrock/interfaces/L1/IETHLockbox.sol index 1af369b7d85..4b74f767e95 100644 --- a/packages/contracts-bedrock/interfaces/L1/IETHLockbox.sol +++ b/packages/contracts-bedrock/interfaces/L1/IETHLockbox.sol @@ -6,9 +6,8 @@ import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { IProxyAdminOwnedBase } from "interfaces/universal/IProxyAdminOwnedBase.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; -import { IReinitializableBase } from "interfaces/universal/IReinitializableBase.sol"; -interface IETHLockbox is IProxyAdminOwnedBase, ISemver, IReinitializableBase { +interface IETHLockbox is IProxyAdminOwnedBase, ISemver { error ETHLockbox_Unauthorized(); error ETHLockbox_Paused(); error ETHLockbox_InsufficientBalance(); diff --git a/packages/contracts-bedrock/interfaces/L1/IL1CrossDomainMessenger.sol b/packages/contracts-bedrock/interfaces/L1/IL1CrossDomainMessenger.sol index beb419f3c24..b81b724068b 100644 --- a/packages/contracts-bedrock/interfaces/L1/IL1CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/interfaces/L1/IL1CrossDomainMessenger.sol @@ -8,11 +8,9 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IProxyAdminOwnedBase } from "interfaces/universal/IProxyAdminOwnedBase.sol"; interface IL1CrossDomainMessenger is ICrossDomainMessenger, IProxyAdminOwnedBase { - error ReinitializableBase_ZeroInitVersion(); function PORTAL() external view returns (IOptimismPortal); function initialize(ISystemConfig _systemConfig, IOptimismPortal _portal) external; - function initVersion() external view returns (uint8); function portal() external view returns (IOptimismPortal); function systemConfig() external view returns (ISystemConfig); function version() external view returns (string memory); diff --git a/packages/contracts-bedrock/interfaces/L1/IL1ERC721Bridge.sol b/packages/contracts-bedrock/interfaces/L1/IL1ERC721Bridge.sol index c69327163cc..a4212af3642 100644 --- a/packages/contracts-bedrock/interfaces/L1/IL1ERC721Bridge.sol +++ b/packages/contracts-bedrock/interfaces/L1/IL1ERC721Bridge.sol @@ -8,9 +8,7 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IProxyAdminOwnedBase } from "interfaces/universal/IProxyAdminOwnedBase.sol"; interface IL1ERC721Bridge is IERC721Bridge, IProxyAdminOwnedBase { - error ReinitializableBase_ZeroInitVersion(); - function initVersion() external view returns (uint8); function bridgeERC721( address _localToken, address _remoteToken, diff --git a/packages/contracts-bedrock/interfaces/L1/IL1StandardBridge.sol b/packages/contracts-bedrock/interfaces/L1/IL1StandardBridge.sol index 4206d272cdf..542fe2f5efa 100644 --- a/packages/contracts-bedrock/interfaces/L1/IL1StandardBridge.sol +++ b/packages/contracts-bedrock/interfaces/L1/IL1StandardBridge.sol @@ -8,7 +8,6 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IProxyAdminOwnedBase } from "interfaces/universal/IProxyAdminOwnedBase.sol"; interface IL1StandardBridge is IStandardBridge, IProxyAdminOwnedBase { - error ReinitializableBase_ZeroInitVersion(); event ERC20DepositInitiated( address indexed l1Token, @@ -29,7 +28,6 @@ interface IL1StandardBridge is IStandardBridge, IProxyAdminOwnedBase { event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData); event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData); - function initVersion() external view returns (uint8); function depositERC20( address _l1Token, address _l2Token, diff --git a/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol b/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol index 5d8b38844df..eb0d587bcef 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol @@ -16,7 +16,6 @@ interface IOptimismPortal2 is IProxyAdminOwnedBase { error EmptyItem(); error InvalidDataRemainder(); error InvalidHeader(); - error ReinitializableBase_ZeroInitVersion(); error OptimismPortal_AlreadyFinalized(); error OptimismPortal_BadTarget(); error OptimismPortal_CallPaused(); @@ -84,7 +83,6 @@ interface IOptimismPortal2 is IProxyAdminOwnedBase { function finalizedWithdrawals(bytes32) external view returns (bool); function guardian() external view returns (address); function initialize(ISystemConfig _systemConfig, IAnchorStateRegistry _anchorStateRegistry, IETHLockbox _ethLockbox) external; - function initVersion() external view returns (uint8); function l2Sender() external view returns (address); function migrateLiquidity() external; function migrateToSharedDisputeGame(IETHLockbox _newLockbox, IAnchorStateRegistry _newAnchorStateRegistry) external; diff --git a/packages/contracts-bedrock/interfaces/L1/ISuperchainConfig.sol b/packages/contracts-bedrock/interfaces/L1/ISuperchainConfig.sol index 42a07fa6f85..8e9575b5014 100644 --- a/packages/contracts-bedrock/interfaces/L1/ISuperchainConfig.sol +++ b/packages/contracts-bedrock/interfaces/L1/ISuperchainConfig.sol @@ -16,7 +16,6 @@ interface ISuperchainConfig is IProxyAdminOwnedBase { error SuperchainConfig_OnlyGuardian(); error SuperchainConfig_AlreadyPaused(address identifier); error SuperchainConfig_NotAlreadyPaused(address identifier); - error ReinitializableBase_ZeroInitVersion(); function guardian() external view returns (address); function initialize(address _guardian) external; @@ -30,7 +29,6 @@ interface ISuperchainConfig is IProxyAdminOwnedBase { function version() external view returns (string memory); function pauseTimestamps(address) external view returns (uint256); function pauseExpiry() external view returns (uint256); - function initVersion() external view returns (uint8); function __constructor__() external; } diff --git a/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol b/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol index a49e2dc4d1a..e5ee937e12e 100644 --- a/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol +++ b/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol @@ -27,7 +27,6 @@ interface ISystemConfig is IProxyAdminOwnedBase { address opcm; } - error ReinitializableBase_ZeroInitVersion(); error SystemConfig_InvalidFeatureState(); event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); @@ -69,7 +68,6 @@ interface ISystemConfig is IProxyAdminOwnedBase { ISuperchainConfig _superchainConfig ) external; - function initVersion() external view returns (uint8); function l1CrossDomainMessenger() external view returns (address addr_); function l1ERC721Bridge() external view returns (address addr_); function l1StandardBridge() external view returns (address addr_); diff --git a/packages/contracts-bedrock/interfaces/dispute/IAnchorStateRegistry.sol b/packages/contracts-bedrock/interfaces/dispute/IAnchorStateRegistry.sol index 8a02143abf2..06248a00bff 100644 --- a/packages/contracts-bedrock/interfaces/dispute/IAnchorStateRegistry.sol +++ b/packages/contracts-bedrock/interfaces/dispute/IAnchorStateRegistry.sol @@ -11,7 +11,6 @@ import { IProxyAdminOwnedBase } from "interfaces/universal/IProxyAdminOwnedBase. interface IAnchorStateRegistry is IProxyAdminOwnedBase { error AnchorStateRegistry_InvalidAnchorGame(); error AnchorStateRegistry_Unauthorized(); - error ReinitializableBase_ZeroInitVersion(); event AnchorUpdated(IDisputeGame indexed game); event DisputeGameBlacklisted(IDisputeGame indexed disputeGame); @@ -19,7 +18,6 @@ interface IAnchorStateRegistry is IProxyAdminOwnedBase { event RespectedGameTypeSet(GameType gameType); event RetirementTimestampSet(uint256 timestamp); - function initVersion() external view returns (uint8); function anchorGame() external view returns (IDisputeGame); function anchors(GameType) external view returns (Hash, uint256); function blacklistDisputeGame(IDisputeGame _disputeGame) external; diff --git a/packages/contracts-bedrock/interfaces/dispute/IDelayedWETH.sol b/packages/contracts-bedrock/interfaces/dispute/IDelayedWETH.sol index 0e3c623d81e..e05f026f165 100644 --- a/packages/contracts-bedrock/interfaces/dispute/IDelayedWETH.sol +++ b/packages/contracts-bedrock/interfaces/dispute/IDelayedWETH.sol @@ -6,7 +6,6 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IProxyAdminOwnedBase } from "interfaces/universal/IProxyAdminOwnedBase.sol"; interface IDelayedWETH is IProxyAdminOwnedBase { - error ReinitializableBase_ZeroInitVersion(); struct WithdrawalRequest { uint256 amount; @@ -18,7 +17,6 @@ interface IDelayedWETH is IProxyAdminOwnedBase { fallback() external payable; receive() external payable; - function initVersion() external view returns (uint8); function systemConfig() external view returns (ISystemConfig); function delay() external view returns (uint256); function hold(address _guy) external; diff --git a/packages/contracts-bedrock/interfaces/dispute/IDisputeGameFactory.sol b/packages/contracts-bedrock/interfaces/dispute/IDisputeGameFactory.sol index 22926448341..56e6217aa56 100644 --- a/packages/contracts-bedrock/interfaces/dispute/IDisputeGameFactory.sol +++ b/packages/contracts-bedrock/interfaces/dispute/IDisputeGameFactory.sol @@ -4,9 +4,8 @@ pragma solidity ^0.8.0; import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; import { GameId, Timestamp, Claim, Hash, GameType } from "src/dispute/lib/Types.sol"; import { IProxyAdminOwnedBase } from "interfaces/universal/IProxyAdminOwnedBase.sol"; -import { IReinitializableBase } from "interfaces/universal/IReinitializableBase.sol"; -interface IDisputeGameFactory is IProxyAdminOwnedBase, IReinitializableBase { +interface IDisputeGameFactory is IProxyAdminOwnedBase { struct GameSearchResult { uint256 index; GameId metadata; diff --git a/packages/contracts-bedrock/interfaces/universal/IReinitializableBase.sol b/packages/contracts-bedrock/interfaces/universal/IReinitializableBase.sol deleted file mode 100644 index d6d096a743b..00000000000 --- a/packages/contracts-bedrock/interfaces/universal/IReinitializableBase.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -interface IReinitializableBase { - error ReinitializableBase_ZeroInitVersion(); - - function initVersion() external view returns (uint8); - - // ReinitializerBase is abstract, so it has no constructor in its interface. - function __constructor__() external; -} diff --git a/packages/contracts-bedrock/scripts/checks/reinitializer/main.go b/packages/contracts-bedrock/scripts/checks/reinitializer/main.go index e44c955d038..7d2a1ae952d 100644 --- a/packages/contracts-bedrock/scripts/checks/reinitializer/main.go +++ b/packages/contracts-bedrock/scripts/checks/reinitializer/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "math" "os" "strconv" "strings" @@ -105,22 +104,17 @@ func getReinitializerValue(node *solc.AstNode) (uint64, error) { for _, modifier := range node.Modifiers { if modifier.ModifierName.Name == "reinitializer" { if modifier.Arguments[0].Kind == "functionCall" { - if modifier.Arguments[0].Expression.Name == "initVersion" { - return math.MaxUint64, nil // uint64 max representing initVersion call - } else { - return 0, fmt.Errorf("reinitializer value is not a call to initVersion") - } - } else { - valStr, ok := modifier.Arguments[0].Value.(string) - if !ok { - return 0, fmt.Errorf("reinitializer value is not a string") - } - val, err := strconv.Atoi(valStr) - if err != nil { - return 0, fmt.Errorf("reinitializer value is not an integer") - } - return uint64(val), nil + return 0, fmt.Errorf("reinitializer value must be a literal integer") } + valStr, ok := modifier.Arguments[0].Value.(string) + if !ok { + return 0, fmt.Errorf("reinitializer value is not a string") + } + val, err := strconv.Atoi(valStr) + if err != nil { + return 0, fmt.Errorf("reinitializer value is not an integer") + } + return uint64(val), nil } } diff --git a/packages/contracts-bedrock/scripts/checks/reinitializer/main_test.go b/packages/contracts-bedrock/scripts/checks/reinitializer/main_test.go index 0f9fc382e2d..520263b7545 100644 --- a/packages/contracts-bedrock/scripts/checks/reinitializer/main_test.go +++ b/packages/contracts-bedrock/scripts/checks/reinitializer/main_test.go @@ -1,7 +1,6 @@ package main import ( - "math" "testing" "github.com/ethereum-optimism/optimism/op-chain-ops/solc" @@ -157,23 +156,7 @@ func TestGetReinitializerValue(t *testing.T) { wantErr: true, }, { - name: "Valid reinitializer with initVersion call", - node: &solc.AstNode{ - Modifiers: []solc.AstNode{ - { - ModifierName: &solc.Expression{Name: "reinitializer"}, - Arguments: []solc.Expression{{ - Kind: "functionCall", - Expression: &solc.Expression{Name: "initVersion"}, - }}, - }, - }, - }, - want: math.MaxUint64, - wantErr: false, - }, - { - name: "Invalid function call - not initVersion", + name: "Invalid function call argument", node: &solc.AstNode{ Modifiers: []solc.AstNode{ { @@ -518,48 +501,7 @@ func TestCheckArtifact(t *testing.T) { wantErr: false, // Should return nil without error }, { - name: "Matching reinitializer values with initVersion", - artifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{ - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "initialize", - Modifiers: []solc.AstNode{ - { - ModifierName: &solc.Expression{Name: "reinitializer"}, - Arguments: []solc.Expression{{ - Kind: "functionCall", - Expression: &solc.Expression{Name: "initVersion"}, - }}, - }, - }, - }, - { - NodeType: "FunctionDefinition", - Name: "upgrade", - Modifiers: []solc.AstNode{ - { - ModifierName: &solc.Expression{Name: "reinitializer"}, - Arguments: []solc.Expression{{ - Kind: "functionCall", - Expression: &solc.Expression{Name: "initVersion"}, - }}, - }, - }, - }, - }, - }, - }, - }, - }, - wantErr: false, - }, - { - name: "Mismatched reinitializer values - one with initVersion, one with constant", + name: "Invalid reinitializer value - function call argument", artifact: &solc.ForgeArtifact{ Ast: solc.Ast{ Nodes: []solc.AstNode{ @@ -574,7 +516,7 @@ func TestCheckArtifact(t *testing.T) { ModifierName: &solc.Expression{Name: "reinitializer"}, Arguments: []solc.Expression{{ Kind: "functionCall", - Expression: &solc.Expression{Name: "initVersion"}, + Expression: &solc.Expression{Name: "someFunction"}, }}, }, }, diff --git a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol index 114a7911e30..4afccc1e7ff 100644 --- a/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol +++ b/packages/contracts-bedrock/scripts/libraries/DeployUtils.sol @@ -17,7 +17,6 @@ import { IProxy } from "interfaces/universal/IProxy.sol"; import { IAddressManager } from "interfaces/legacy/IAddressManager.sol"; import { IL1ChugSplashProxy, IStaticL1ChugSplashProxy } from "interfaces/legacy/IL1ChugSplashProxy.sol"; import { IResolvedDelegateProxy } from "interfaces/legacy/IResolvedDelegateProxy.sol"; -import { IReinitializableBase } from "interfaces/universal/IReinitializableBase.sol"; library DeployUtils { Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); @@ -455,19 +454,7 @@ library DeployUtils { bytes32 slotVal = vm.load(_contractAddress, bytes32(_slot)); uint8 val = uint8((uint256(slotVal) >> (_offset * 8)) & 0xFF); if (_isProxy) { - // Using a try/catch here to check if the contract has an initVersion() defined. - // EIP-150 safe because we require that we have at least 200k gas before the call which - // is more than enough to avoid running out of gas when 63/64 of the gas is provided to - // the initVersion() call (which simply reads an immutable variable). Since this is - // only ever triggered as part of a script, we can safely assume we'll have the gas. - require(gasleft() > 200_000, "DeployUtils: insufficient gas for initVersion() call"); - - // eip150-safe - try IReinitializableBase(_contractAddress).initVersion() returns (uint8 initVersion_) { - require(val == initVersion_, "DeployUtils: storage value is incorrect at the given slot and offset"); - } catch { - require(val == 1, "DeployUtils: storage value is not set at the given slot and offset"); - } + require(val == 1, "DeployUtils: storage value is not set at the given slot and offset"); } else { require(val == type(uint8).max, "DeployUtils: storage value is not 0xff at the given slot and offset"); } diff --git a/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json b/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json index 8957b66aff6..0b093a0e8d1 100644 --- a/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json +++ b/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json @@ -148,19 +148,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -594,10 +581,5 @@ "inputs": [], "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" - }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json b/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json index 54b9f7f9932..bc4d45173ca 100644 --- a/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json +++ b/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json @@ -162,19 +162,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -553,10 +540,5 @@ "inputs": [], "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" - }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json b/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json index 016224be139..86e4cc0b06f 100644 --- a/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json +++ b/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json @@ -251,19 +251,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -578,10 +565,5 @@ "inputs": [], "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" - }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/ETHLockbox.json b/packages/contracts-bedrock/snapshots/abi/ETHLockbox.json index 2f09a99da64..81113e34b23 100644 --- a/packages/contracts-bedrock/snapshots/abi/ETHLockbox.json +++ b/packages/contracts-bedrock/snapshots/abi/ETHLockbox.json @@ -68,19 +68,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -386,10 +373,5 @@ "inputs": [], "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" - }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json b/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json index bc0174b42fa..96795cb3ff7 100644 --- a/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json +++ b/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json @@ -216,19 +216,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -581,10 +568,5 @@ "inputs": [], "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" - }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json b/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json index 7b83c924650..4b51745fa84 100644 --- a/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json +++ b/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json @@ -168,19 +168,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -431,10 +418,5 @@ "inputs": [], "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" - }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json b/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json index 78752f602e8..b90ae61d5d2 100644 --- a/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json +++ b/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json @@ -414,19 +414,6 @@ "stateMutability": "payable", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -900,10 +887,5 @@ "inputs": [], "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" - }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json index 35c8cc9c899..e7c9db06e9d 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json @@ -270,19 +270,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -979,11 +966,6 @@ "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" - }, { "inputs": [], "name": "UnexpectedList", diff --git a/packages/contracts-bedrock/snapshots/abi/SuperchainConfig.json b/packages/contracts-bedrock/snapshots/abi/SuperchainConfig.json index e430da3ccca..6c00b746072 100644 --- a/packages/contracts-bedrock/snapshots/abi/SuperchainConfig.json +++ b/packages/contracts-bedrock/snapshots/abi/SuperchainConfig.json @@ -49,19 +49,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -311,11 +298,6 @@ "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" - }, { "inputs": [ { diff --git a/packages/contracts-bedrock/snapshots/abi/SystemConfig.json b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json index 3eb8330144d..8623c22b516 100644 --- a/packages/contracts-bedrock/snapshots/abi/SystemConfig.json +++ b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json @@ -340,19 +340,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "initVersion", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -1155,11 +1142,6 @@ "name": "ProxyAdminOwnedBase_ProxyAdminNotFound", "type": "error" }, - { - "inputs": [], - "name": "ReinitializableBase_ZeroInitVersion", - "type": "error" - }, { "inputs": [], "name": "SystemConfig_InvalidFeatureState", diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index aed34a69a69..84a96dd5599 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -4,36 +4,36 @@ "sourceCodeHash": "0x97888fc27c562c1ee77050e76c81249f4dc41c519c0a7f663740ff582df09045" }, "src/L1/ETHLockbox.sol:ETHLockbox": { - "initCodeHash": "0xb2ff8426ab2eb36352f790748963c8e1f7a91caf16bee6a035c2c41bac532836", - "sourceCodeHash": "0x870004d5acc24a704277680f09ccca51a020a512e6c6d48cca583a23a0de43a2" + "initCodeHash": "0x2e27811e636a43260d36d05335d486a24ad5b1d1c8dc225b3dcc85cf0f537645", + "sourceCodeHash": "0x4ac0467eace49f20284828dce5f9bdd6404f000d48e6badb69b09ebffbea9f50" }, "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger": { - "initCodeHash": "0xc1ec4cfb082f933ed4a705a6d6de874c0fe167683e1f8fcf792fdcfeb767ea0d", - "sourceCodeHash": "0x7ebe9fe238b59fcabdc9feaff9a1302314071eab01d425d0a44365ff3d48f394" + "initCodeHash": "0x6ab988d0c6720f2785e8e101e9cccad508f13e52e371b5d3158950e6d5646851", + "sourceCodeHash": "0x2bfa3cb942409d3e2e93a56b2d22645b897fc2da04a274bf4b391729f515aadb" }, "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge": { - "initCodeHash": "0x8754f400a5110749e26f9820e0532b86f0122a6b8ceb10028fd997d39b023ff7", - "sourceCodeHash": "0xfd4d13c09f30072475e2286457a35abaa122223c26ae40398524ad77d5dbb9e1" + "initCodeHash": "0xb2d78db0aa6bad0383a80a469449a0650151887758c2bcb0e837c995a1bd53ee", + "sourceCodeHash": "0xf0ab2240c3103bade4c3e5a82d061361b8f0d5238f5e574c8738b24cdda5a6cb" }, "src/L1/L1StandardBridge.sol:L1StandardBridge": { - "initCodeHash": "0x75b07cd638ef34349da3478aeab051472c1cba8c8074d3df48af3d7fbd97fd49", - "sourceCodeHash": "0x0ef8461e8bc55314e61e60924465574db17bdf30bbbfe9739b52cac623bba2db" + "initCodeHash": "0x5d676212fd2dcb2f52edb3586490ebb741a85a740569fa8b260c07908c66b012", + "sourceCodeHash": "0xf028c069c2923dca2b6e0872a8ddbc0af1875256a27524b946a9ca73e7ddc9b3" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { "initCodeHash": "0xa0fdd2178ed863e256f6c70dea683ccea945eeeb21d8e516e47fda9b46f37b8d", "sourceCodeHash": "0xf54d8879da1dd257d73c71ee80b9cc9e5e8a753300ae60a74f3059506bc3d5f4" }, "src/L1/OptimismPortal2.sol:OptimismPortal2": { - "initCodeHash": "0x67bbf6c9b344870cdbd7b041ddad6fb69057a4b48ec6dd96876af55d14fc1943", - "sourceCodeHash": "0x6f754eee67b9e8b9a8a46db304f695d381b63fdf2c48b540fd0cb39aed9daaa9" + "initCodeHash": "0x4146bfb98d49c2cce05a744f47d7ce4fc2bb31c5369e34a1d231066bb3b87c52", + "sourceCodeHash": "0xdc59a3ee5ea0d50daf109c7d5fe2be49daa2a889685c2a5277ab486096256a1a" }, "src/L1/SuperchainConfig.sol:SuperchainConfig": { - "initCodeHash": "0x68f3fa110e1509bd841932feab438df5b5995ee222fc69a4dd6fcd48428e06f5", - "sourceCodeHash": "0x97e17703a4843694a3bc71be2adcd753a0755db34d1fafc674e2b9586435dc76" + "initCodeHash": "0xce660f1d432a4a7f8ba8e20a84fce30f74f110bc784c7df6fefca8d730246caa", + "sourceCodeHash": "0x5f8fd5a452e222b78fe9202210154f2b637e2fb5d49f63e29d39283394af9a6b" }, "src/L1/SystemConfig.sol:SystemConfig": { - "initCodeHash": "0x1701f191d49ba9c27d6ebee63eec095c97c20b66648c01b41aa2ad7b5808861c", - "sourceCodeHash": "0x2650f2af1df017387e1f1aa6273decc4c46dd4f3ac7f0910c6f0edc92aef4747" + "initCodeHash": "0xb021c40df21ad055a8fcc3e08f4a5bd37d0ba87d42f80f3409f04ade150d5992", + "sourceCodeHash": "0x2346e655818ee8b43198fdcddf561215aa98a64fd46f36ac70f8395cec20df6a" }, "src/L1/opcm/OPContractsManagerV2.sol:OPContractsManagerV2": { "initCodeHash": "0x0a6a9baa9913e6feb0c0d1606f037c22205cbe83e709de3c9ca0ba03a0301037", @@ -148,16 +148,16 @@ "sourceCodeHash": "0xd4f03f13a42027a51be6f6837ba0c12b9991a294777aed918550ec9d2f7c1759" }, "src/dispute/AnchorStateRegistry.sol:AnchorStateRegistry": { - "initCodeHash": "0x26126073f886d463e4ddea8aa87b0a693e8a208d4be4d2a5a19208a82eea6c19", - "sourceCodeHash": "0xd5323044373e8b70b52b26591d5e7c75c0e1b6613365f1b87fd208c1fb312dc2" + "initCodeHash": "0xdb1ec7a7376e7c92165c7dfe058d014e1c6202f834959470d174ee980818d7b8", + "sourceCodeHash": "0x6d70a1db5350bd82278a8e73d3be7097e58d80d8615c7f8c67200d9d538ca9b7" }, "src/dispute/DelayedWETH.sol:DelayedWETH": { - "initCodeHash": "0xe695ef6bc4edce86e3f9325ef016dc121a882e5ab2b7792aec1ba0b1d098b7f9", - "sourceCodeHash": "0xf0a45f727742c86f938345a7c124a73869baa32bffb068573bf0003d17ea7117" + "initCodeHash": "0x0260f79a4bb4859d9bd14d9d6f7e336ea35821502be9901873571faa6a18d98d", + "sourceCodeHash": "0x66f12d4893111b213377c3021376b1d48c9459cab46538a6e5b4eca391906271" }, "src/dispute/DisputeGameFactory.sol:DisputeGameFactory": { - "initCodeHash": "0x080ffb82a16452a42d6e2a78817f60ae2987197b39d3f10f08739d76b70c7435", - "sourceCodeHash": "0x98d6a94d38c2f4120d5b695ef4c479825e2ff12785ad93e2f65a11c2e8611a60" + "initCodeHash": "0x6e3283b8c890a9600010bd91db3459227bbd249f89d8b4654c1406918447a6f0", + "sourceCodeHash": "0xc8fe83b48139bbf192f3ed3a32ed99086a34047009b08c1aab61e5163d69b11f" }, "src/dispute/FaultDisputeGame.sol:FaultDisputeGame": { "initCodeHash": "0xb1f5751c6bd16ce44f8fb9dade40895f45777cb0595e607b6625a88b9e7cd71c", diff --git a/packages/contracts-bedrock/src/L1/ETHLockbox.sol b/packages/contracts-bedrock/src/L1/ETHLockbox.sol index 63c470a2ca6..60b5704f4d9 100644 --- a/packages/contracts-bedrock/src/L1/ETHLockbox.sol +++ b/packages/contracts-bedrock/src/L1/ETHLockbox.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.15; // Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; @@ -20,7 +19,7 @@ import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; /// @title ETHLockbox /// @notice Manages ETH liquidity locking and unlocking for authorized OptimismPortals, enabling unified ETH liquidity /// management across chains in the superchain cluster. -contract ETHLockbox is ProxyAdminOwnedBase, Initializable, ReinitializableBase, ISemver { +contract ETHLockbox is ProxyAdminOwnedBase, Initializable, ISemver { /// @notice Thrown when the lockbox is paused. error ETHLockbox_Paused(); @@ -73,13 +72,13 @@ contract ETHLockbox is ProxyAdminOwnedBase, Initializable, ReinitializableBase, mapping(IETHLockbox => bool) public authorizedLockboxes; /// @notice Semantic version. - /// @custom:semver 1.3.1 + /// @custom:semver 1.4.0 function version() public view virtual returns (string memory) { - return "1.3.1"; + return "1.4.0"; } /// @notice Constructs the ETHLockbox contract. - constructor() ReinitializableBase(1) { + constructor() { _disableInitializers(); } @@ -95,7 +94,7 @@ contract ETHLockbox is ProxyAdminOwnedBase, Initializable, ReinitializableBase, IOptimismPortal[] calldata _portals ) external - reinitializer(initVersion()) + initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol index cfd91d1a0a7..e4e80c059d8 100644 --- a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Contracts import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; // Libraries @@ -20,7 +19,7 @@ import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPort /// @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible /// for sending and receiving data on the L1 side. Users are encouraged to use this /// interface instead of interacting with lower-level contracts directly. -contract L1CrossDomainMessenger is CrossDomainMessenger, ProxyAdminOwnedBase, ReinitializableBase, ISemver { +contract L1CrossDomainMessenger is CrossDomainMessenger, ProxyAdminOwnedBase, ISemver { /// @custom:legacy /// @custom:spacer superchainConfig /// @notice Spacer taking up the legacy `superchainConfig` slot. @@ -36,21 +35,21 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ProxyAdminOwnedBase, Re address private spacer_253_0_20; /// @notice Semantic version. - /// @custom:semver 2.11.1 - string public constant version = "2.11.1"; + /// @custom:semver 2.12.0 + string public constant version = "2.12.0"; /// @notice Contract of the SystemConfig. ISystemConfig public systemConfig; /// @notice Constructs the L1CrossDomainMessenger contract. - constructor() ReinitializableBase(3) { + constructor() { _disableInitializers(); } /// @notice Initializes the contract. /// @param _systemConfig Contract of the SystemConfig contract on this network. /// @param _portal Contract of the OptimismPortal contract on this network. - function initialize(ISystemConfig _systemConfig, IOptimismPortal _portal) external reinitializer(initVersion()) { + function initialize(ISystemConfig _systemConfig, IOptimismPortal _portal) external initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol index 8753b1fbf2f..062dd5b53d8 100644 --- a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Contracts import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; // Libraries @@ -22,7 +21,7 @@ import { IL2ERC721Bridge } from "interfaces/L2/IL2ERC721Bridge.sol"; /// @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to /// make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract /// acts as an escrow for ERC721 tokens deposited into L2. -contract L1ERC721Bridge is ERC721Bridge, ProxyAdminOwnedBase, ReinitializableBase, ISemver { +contract L1ERC721Bridge is ERC721Bridge, ProxyAdminOwnedBase, ISemver { /// @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token /// by ID was deposited for a given L2 token. mapping(address => mapping(address => mapping(uint256 => bool))) public deposits; @@ -33,14 +32,14 @@ contract L1ERC721Bridge is ERC721Bridge, ProxyAdminOwnedBase, ReinitializableBas address private spacer_50_0_20; /// @notice Semantic version. - /// @custom:semver 2.9.1 - string public constant version = "2.9.1"; + /// @custom:semver 2.10.0 + string public constant version = "2.10.0"; /// @notice Address of the SystemConfig contract. ISystemConfig public systemConfig; /// @notice Constructs the L1ERC721Bridge contract. - constructor() ERC721Bridge() ReinitializableBase(3) { + constructor() ERC721Bridge() { _disableInitializers(); } @@ -52,7 +51,7 @@ contract L1ERC721Bridge is ERC721Bridge, ProxyAdminOwnedBase, ReinitializableBas ISystemConfig _systemConfig ) external - reinitializer(initVersion()) + initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol index b8943aacebd..e70d8ce5db9 100644 --- a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol +++ b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Contracts import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; // Libraries @@ -25,7 +24,7 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; /// NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples /// of some token types that may not be properly supported by this contract include, but are /// not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists. -contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, ReinitializableBase, ISemver { +contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, ISemver { /// @custom:legacy /// @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated. /// @param from Address of the depositor. @@ -77,8 +76,8 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl ); /// @notice Semantic version. - /// @custom:semver 2.8.2 - string public constant version = "2.8.2"; + /// @custom:semver 2.9.0 + string public constant version = "2.9.0"; /// @custom:legacy /// @custom:spacer superchainConfig @@ -94,7 +93,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl ISystemConfig public systemConfig; /// @notice Constructs the L1StandardBridge contract. - constructor() StandardBridge() ReinitializableBase(3) { + constructor() StandardBridge() { _disableInitializers(); } @@ -106,7 +105,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl ISystemConfig _systemConfig ) external - reinitializer(initVersion()) + initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index 7714b67f058..4c767213db6 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -5,7 +5,6 @@ pragma solidity 0.8.15; import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; // Libraries import { EOA } from "src/libraries/EOA.sol"; @@ -34,7 +33,7 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; /// @notice The OptimismPortal is a low-level contract responsible for passing messages between L1 /// and L2. Messages sent directly to the OptimismPortal have no form of replayability. /// Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface. -contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase, ProxyAdminOwnedBase, ISemver { +contract OptimismPortal2 is Initializable, ResourceMetering, ProxyAdminOwnedBase, ISemver { /// @notice Represents a proven withdrawal. /// @custom:field disputeGameProxy Game that the withdrawal was proven against. /// @custom:field timestamp Timestamp at which the withdrawal was proven. @@ -241,13 +240,13 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase error OptimismPortal_LockboxNotAuthorizedForPortal(); /// @notice Semantic version. - /// @custom:semver 5.8.0 + /// @custom:semver 5.9.0 function version() public pure virtual returns (string memory) { - return "5.8.0"; + return "5.9.0"; } /// @param _proofMaturityDelaySeconds The proof maturity delay in seconds. - constructor(uint256 _proofMaturityDelaySeconds) ReinitializableBase(3) { + constructor(uint256 _proofMaturityDelaySeconds) { PROOF_MATURITY_DELAY_SECONDS = _proofMaturityDelaySeconds; _disableInitializers(); } @@ -261,7 +260,7 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase IETHLockbox _ethLockbox ) external - reinitializer(initVersion()) + initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/L1/SuperchainConfig.sol b/packages/contracts-bedrock/src/L1/SuperchainConfig.sol index cf87c13f4b6..a070efb9ee1 100644 --- a/packages/contracts-bedrock/src/L1/SuperchainConfig.sol +++ b/packages/contracts-bedrock/src/L1/SuperchainConfig.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.15; // Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; // Interfaces import { ISemver } from "interfaces/universal/ISemver.sol"; @@ -12,7 +11,7 @@ import { ISemver } from "interfaces/universal/ISemver.sol"; /// @custom:proxied true /// @title SuperchainConfig /// @notice The SuperchainConfig contract is used to manage configuration of global superchain values. -contract SuperchainConfig is ProxyAdminOwnedBase, Initializable, ReinitializableBase, ISemver { +contract SuperchainConfig is ProxyAdminOwnedBase, Initializable, ISemver { /// @notice Thrown when a caller is not the guardian but tries to call a guardian-only function error SuperchainConfig_OnlyGuardian(); @@ -52,17 +51,17 @@ contract SuperchainConfig is ProxyAdminOwnedBase, Initializable, Reinitializable event ConfigUpdate(UpdateType indexed updateType, bytes data); /// @notice Semantic version. - /// @custom:semver 2.4.3 - string public constant version = "2.4.3"; + /// @custom:semver 2.5.0 + string public constant version = "2.5.0"; /// @notice Constructs the SuperchainConfig contract. - constructor() ReinitializableBase(2) { + constructor() { _disableInitializers(); } /// @notice Initializer. /// @param _guardian Address of the guardian, can pause the OptimismPortal. - function initialize(address _guardian) external reinitializer(initVersion()) { + function initialize(address _guardian) external initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index f5472e51433..1e148105438 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Contracts import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; // Libraries @@ -21,7 +20,7 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; /// @notice The SystemConfig contract is used to manage configuration of an Optimism network. /// All configuration is stored on L1 and picked up by L2 as part of the derivation of /// the L2 chain. -contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, ReinitializableBase, ISemver { +contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, ISemver { /// @notice Enum representing different types of updates. /// @custom:value BATCHER Represents an update to the batcher hash. /// @custom:value FEE_SCALARS Represents an update to l1 data fee scalars. @@ -174,15 +173,15 @@ contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitializabl error SystemConfig_InvalidFeatureState(); /// @notice Semantic version. - /// @custom:semver 3.14.2 + /// @custom:semver 3.15.0 function version() public pure virtual returns (string memory) { - return "3.14.2"; + return "3.15.0"; } /// @notice Constructs the SystemConfig contract. /// @dev START_BLOCK_SLOT is set to type(uint256).max here so that it will be a dead value /// in the singleton. - constructor() ReinitializableBase(3) { + constructor() { Storage.setUint(START_BLOCK_SLOT, type(uint256).max); _disableInitializers(); } @@ -215,7 +214,7 @@ contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitializabl ISuperchainConfig _superchainConfig ) public - reinitializer(initVersion()) + initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol index 7f62e3b4ded..7da2b4f04f4 100644 --- a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.15; // Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; // Libraries import { GameType, Proposal, Claim, GameStatus, Hash } from "src/dispute/lib/Types.sol"; @@ -22,10 +21,10 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; /// FaultDisputeGame type. The anchor state is the latest state that has been proposed on L1 and was not /// challenged within the challenge period. By using stored anchor states, new FaultDisputeGame instances can /// be initialized with a more recent starting state which reduces the amount of required offchain computation. -contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, ReinitializableBase, ISemver { +contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, ISemver { /// @notice Semantic version. - /// @custom:semver 3.9.0 - string public constant version = "3.9.0"; + /// @custom:semver 3.10.0 + string public constant version = "3.10.0"; /// @notice The dispute game finality delay in seconds. uint256 internal immutable DISPUTE_GAME_FINALITY_DELAY_SECONDS; @@ -76,7 +75,7 @@ contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, Reinitializa error AnchorStateRegistry_Unauthorized(); /// @param _disputeGameFinalityDelaySeconds The dispute game finality delay in seconds. - constructor(uint256 _disputeGameFinalityDelaySeconds) ReinitializableBase(1) { + constructor(uint256 _disputeGameFinalityDelaySeconds) { DISPUTE_GAME_FINALITY_DELAY_SECONDS = _disputeGameFinalityDelaySeconds; _disableInitializers(); } @@ -93,7 +92,7 @@ contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, Reinitializa GameType _startingRespectedGameType ) external - reinitializer(initVersion()) + initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/dispute/DelayedWETH.sol b/packages/contracts-bedrock/src/dispute/DelayedWETH.sol index 0f20b22e0d6..4f77bc5d758 100644 --- a/packages/contracts-bedrock/src/dispute/DelayedWETH.sol +++ b/packages/contracts-bedrock/src/dispute/DelayedWETH.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.15; // Contracts import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { WETH98 } from "src/universal/WETH98.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; // Interfaces @@ -22,7 +21,7 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; /// is meant to sit behind a proxy contract and has an owner address that can pull WETH from any account and /// can recover ETH from the contract itself. Variable and function naming vaguely follows the vibe of WETH9. /// Not the prettiest contract in the world, but it gets the job done. -contract DelayedWETH is Initializable, ProxyAdminOwnedBase, ReinitializableBase, WETH98, ISemver { +contract DelayedWETH is Initializable, ProxyAdminOwnedBase, WETH98, ISemver { /// @notice Represents a withdrawal request. struct WithdrawalRequest { uint256 amount; @@ -30,8 +29,8 @@ contract DelayedWETH is Initializable, ProxyAdminOwnedBase, ReinitializableBase, } /// @notice Semantic version. - /// @custom:semver 1.5.1 - string public constant version = "1.5.1"; + /// @custom:semver 1.6.0 + string public constant version = "1.6.0"; /// @notice Returns a withdrawal request for the given address. mapping(address => mapping(address => WithdrawalRequest)) public withdrawals; @@ -43,14 +42,14 @@ contract DelayedWETH is Initializable, ProxyAdminOwnedBase, ReinitializableBase, ISystemConfig public systemConfig; /// @param _delay The delay for withdrawals in seconds. - constructor(uint256 _delay) ReinitializableBase(1) { + constructor(uint256 _delay) { DELAY_SECONDS = _delay; _disableInitializers(); } /// @notice Initializes the contract. /// @param _systemConfig Address of the SystemConfig contract. - function initialize(ISystemConfig _systemConfig) external reinitializer(initVersion()) { + function initialize(ISystemConfig _systemConfig) external initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol index a0a7c365f23..4aff7d2d301 100644 --- a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol +++ b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Contracts import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; import { ProxyAdminOwnedBase } from "src/universal/ProxyAdminOwnedBase.sol"; // Libraries @@ -21,7 +20,7 @@ import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; /// mapping and an append only array. The timestamp of the creation time of the dispute game is packed tightly /// into the storage slot with the address of the dispute game to make offchain discoverability of playable /// dispute games easier. -contract DisputeGameFactory is ProxyAdminOwnedBase, ReinitializableBase, OwnableUpgradeable, ISemver { +contract DisputeGameFactory is ProxyAdminOwnedBase, OwnableUpgradeable, ISemver { /// @dev Allows for the creation of clone proxies with immutable arguments. using LibClone for address; @@ -56,8 +55,8 @@ contract DisputeGameFactory is ProxyAdminOwnedBase, ReinitializableBase, Ownable } /// @notice Semantic version. - /// @custom:semver 1.6.1 - string public constant version = "1.6.1"; + /// @custom:semver 1.7.0 + string public constant version = "1.7.0"; /// @notice `gameImpls` is a mapping that maps `GameType`s to their respective /// `IDisputeGame` implementations. @@ -79,13 +78,13 @@ contract DisputeGameFactory is ProxyAdminOwnedBase, ReinitializableBase, Ownable mapping(GameType => bytes) public gameArgs; /// @notice Constructs a new DisputeGameFactory contract. - constructor() OwnableUpgradeable() ReinitializableBase(1) { + constructor() OwnableUpgradeable() { _disableInitializers(); } /// @notice Initializes the contract. /// @param _owner The owner of the contract. - function initialize(address _owner) external reinitializer(initVersion()) { + function initialize(address _owner) external initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/universal/ReinitializableBase.sol b/packages/contracts-bedrock/src/universal/ReinitializableBase.sol deleted file mode 100644 index 056a15986e0..00000000000 --- a/packages/contracts-bedrock/src/universal/ReinitializableBase.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -/// @title ReinitializableBase -/// @notice A base contract for reinitializable contracts that exposes a version number. -abstract contract ReinitializableBase { - /// @notice Thrown when the initialization version is zero. - error ReinitializableBase_ZeroInitVersion(); - - /// @notice Current initialization version. - uint8 internal immutable INIT_VERSION; - - /// @param _initVersion Current initialization version. - constructor(uint8 _initVersion) { - // Sanity check, we should never have a zero init version. - if (_initVersion == 0) revert ReinitializableBase_ZeroInitVersion(); - INIT_VERSION = _initVersion; - } - - /// @notice Getter for the current initialization version. - /// @return The current initialization version. - function initVersion() public view returns (uint8) { - return INIT_VERSION; - } -} diff --git a/packages/contracts-bedrock/test/L1/ETHLockbox.t.sol b/packages/contracts-bedrock/test/L1/ETHLockbox.t.sol index a26b9508a6a..9b2a3444bef 100644 --- a/packages/contracts-bedrock/test/L1/ETHLockbox.t.sol +++ b/packages/contracts-bedrock/test/L1/ETHLockbox.t.sol @@ -70,7 +70,7 @@ contract ETHLockbox_Initialize_Test is ETHLockbox_TestInit { uint8 val = uint8(uint256(slotVal) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, ethLockbox.initVersion()); + assertEq(val, 1); } /// @notice Tests that the `initialize` function reverts if called by a non-proxy admin or diff --git a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol index feeffc6ca7c..683722926e8 100644 --- a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol @@ -106,7 +106,7 @@ contract L1CrossDomainMessenger_Initialize_Test is L1CrossDomainMessenger_TestIn uint8 val = uint8((uint256(slotVal) >> 20 * 8) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, l1CrossDomainMessenger.initVersion()); + assertEq(val, 1); } /// @notice Tests that the initialize function reverts if called by a non-proxy admin or owner. diff --git a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol index 676b1888df7..dd41cf19caf 100644 --- a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol @@ -115,7 +115,7 @@ contract L1ERC721Bridge_Initialize_Test is L1ERC721Bridge_TestInit { uint8 val = uint8(uint256(slotVal) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, l1ERC721Bridge.initVersion()); + assertEq(val, 1); } /// @notice Tests that the initialize function reverts if called by a non-proxy admin or owner. diff --git a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol index 9ac45becef8..dc563c89f66 100644 --- a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol @@ -214,7 +214,7 @@ contract L1StandardBridge_Initialize_Test is CommonTest { uint8 val = uint8(uint256(slotVal) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, l1StandardBridge.initVersion()); + assertEq(val, 1); } } diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol index 0bfbe40b200..1d45c481760 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol @@ -286,7 +286,7 @@ contract OptimismPortal2_Initialize_Test is OptimismPortal2_TestInit { uint8 val = uint8(uint256(slotVal) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, optimismPortal2.initVersion()); + assertEq(val, 1); } /// @notice Tests that the initialize function reverts if called by a non-proxy admin or owner. /// @param _sender The address of the sender to test. @@ -2773,7 +2773,7 @@ contract OptimismPortal2_Params_Test is CommonTest { // The value passed to the initialize must be larger than the last value // that initialize was called with. IProxy(payable(address(optimismPortal2))).upgradeToAndCall( - address(nextImpl), abi.encodeCall(NextImpl.initialize, (optimismPortal2.initVersion() + 1)) + address(nextImpl), abi.encodeCall(NextImpl.initialize, (2)) ); assertEq(IProxy(payable(address(optimismPortal2))).implementation(), address(nextImpl)); diff --git a/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol b/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol index 2b07e7235d0..7539e5fdef9 100644 --- a/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol +++ b/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol @@ -68,7 +68,7 @@ contract SuperchainConfig_Initialize_Test is SuperchainConfig_TestInit { uint8 val = uint8(uint256(slotVal) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, superchainConfig.initVersion()); + assertEq(val, 1); } /// @notice Tests that the `initialize` function reverts if called by a non-proxy admin or diff --git a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol index c805c2d78b6..1eed066d6f4 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol @@ -191,7 +191,7 @@ contract SystemConfig_Initialize_Test is SystemConfig_TestInit { uint8 val = uint8(uint256(slotVal) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, systemConfig.initVersion()); + assertEq(val, 1); } /// @notice Tests that `initialize` reverts if called by a non-proxy admin or owner. diff --git a/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol index 98bf600fbf8..5ff67928567 100644 --- a/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol +++ b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol @@ -80,7 +80,7 @@ contract AnchorStateRegistry_Initialize_Test is AnchorStateRegistry_TestInit { uint8 val = uint8(uint256(slotVal) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, anchorStateRegistry.initVersion()); + assertEq(val, 1); } /// @notice Tests that the retirement timestamp is set on the first initialization. diff --git a/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol b/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol index 79341b7f440..7bb3a9ed590 100644 --- a/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol +++ b/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol @@ -88,7 +88,7 @@ contract DelayedWETH_Initialize_Test is DelayedWETH_TestInit { uint8 val = uint8(uint256(slotVal) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, delayedWeth.initVersion()); + assertEq(val, 1); } /// @notice Tests that initialization reverts if called by a non-proxy admin or proxy admin diff --git a/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol b/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol index 24858996afb..8ee229f621c 100644 --- a/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol +++ b/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol @@ -423,7 +423,7 @@ contract DisputeGameFactory_Initialize_Test is DisputeGameFactory_TestInit { uint8 val = uint8(uint256(slotVal) & 0xFF); // Assert that the initializer value matches the expected value. - assertEq(val, disputeGameFactory.initVersion()); + assertEq(val, 1); } } diff --git a/packages/contracts-bedrock/test/universal/ReinitializableBase.t.sol b/packages/contracts-bedrock/test/universal/ReinitializableBase.t.sol deleted file mode 100644 index a6d61ec6a32..00000000000 --- a/packages/contracts-bedrock/test/universal/ReinitializableBase.t.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing -import { Test } from "test/setup/Test.sol"; - -// Contracts -import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; - -/// @title ReinitializableBase_Harness -/// @notice Harness contract to allow direct instantiation and testing of `ReinitializableBase` -/// logic. -contract ReinitializableBase_Harness is ReinitializableBase { - constructor(uint8 _initVersion) ReinitializableBase(_initVersion) { } -} - -/// @title ReinitializableBase_Constructor_Test -/// @notice Tests the constructor of the `ReinitializableBase` contract. -contract ReinitializableBase_Constructor_Test is Test { - /// @notice Tests that the contract creation reverts when init version is zero. - function test_constructor_zeroVersion_reverts() public { - vm.expectRevert(ReinitializableBase.ReinitializableBase_ZeroInitVersion.selector); - new ReinitializableBase_Harness(0); - } - - /// @notice Tests that constructor succeeds with valid non-zero init versions. - /// @param _initVersion Init version to use when creating the contract. - function testFuzz_constructor_validVersion_succeeds(uint8 _initVersion) public { - _initVersion = uint8(bound(_initVersion, 1, type(uint8).max)); - ReinitializableBase_Harness harness = new ReinitializableBase_Harness(_initVersion); - assertEq(harness.initVersion(), _initVersion); - } -} From cbfcc62feea6c6024f7151c603bd6cad98eedba8 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Jul 2026 14:04:55 +0000 Subject: [PATCH 2/3] contracts-bedrock: fix forge fmt for shortened initialize signatures Collapse the initialize() signatures of ETHLockbox, L1ERC721Bridge, and L1StandardBridge onto a single line now that dropping the reinitializer(initVersion()) modifier makes them fit, matching forge fmt. Whitespace-only: initCodeHash values are unchanged, only sourceCodeHash entries in the semver lock move. Co-Authored-By: Claude Co-authored-by: John Mardlin --- packages/contracts-bedrock/snapshots/semver-lock.json | 6 +++--- packages/contracts-bedrock/src/L1/ETHLockbox.sol | 8 +------- packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol | 8 +------- packages/contracts-bedrock/src/L1/L1StandardBridge.sol | 8 +------- 4 files changed, 6 insertions(+), 24 deletions(-) diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index 84a96dd5599..b4cdacff009 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -5,7 +5,7 @@ }, "src/L1/ETHLockbox.sol:ETHLockbox": { "initCodeHash": "0x2e27811e636a43260d36d05335d486a24ad5b1d1c8dc225b3dcc85cf0f537645", - "sourceCodeHash": "0x4ac0467eace49f20284828dce5f9bdd6404f000d48e6badb69b09ebffbea9f50" + "sourceCodeHash": "0xbad33d44e4cb48a2e00c8859aa5073466bebdf8dd4d421bfd44615a502c35824" }, "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger": { "initCodeHash": "0x6ab988d0c6720f2785e8e101e9cccad508f13e52e371b5d3158950e6d5646851", @@ -13,11 +13,11 @@ }, "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge": { "initCodeHash": "0xb2d78db0aa6bad0383a80a469449a0650151887758c2bcb0e837c995a1bd53ee", - "sourceCodeHash": "0xf0ab2240c3103bade4c3e5a82d061361b8f0d5238f5e574c8738b24cdda5a6cb" + "sourceCodeHash": "0xdcdaf488aae5ded04f7d36a8b83ce191d3d8b6ca0cc83148ed1e88ceaa4addde" }, "src/L1/L1StandardBridge.sol:L1StandardBridge": { "initCodeHash": "0x5d676212fd2dcb2f52edb3586490ebb741a85a740569fa8b260c07908c66b012", - "sourceCodeHash": "0xf028c069c2923dca2b6e0872a8ddbc0af1875256a27524b946a9ca73e7ddc9b3" + "sourceCodeHash": "0x7a5e59f377b0cfcdefaca7c9a2d2f059eb25113c16039e1405cf5946ac2b7c98" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { "initCodeHash": "0xa0fdd2178ed863e256f6c70dea683ccea945eeeb21d8e516e47fda9b46f37b8d", diff --git a/packages/contracts-bedrock/src/L1/ETHLockbox.sol b/packages/contracts-bedrock/src/L1/ETHLockbox.sol index 60b5704f4d9..7c7c2f76407 100644 --- a/packages/contracts-bedrock/src/L1/ETHLockbox.sol +++ b/packages/contracts-bedrock/src/L1/ETHLockbox.sol @@ -89,13 +89,7 @@ contract ETHLockbox is ProxyAdminOwnedBase, Initializable, ISemver { /// contracts will point to the same pause identifier (the lockbox itself). Therefore, it /// doesn't matter which SystemConfig is used here as long as it belongs to one of the /// chains that share the lockbox. - function initialize( - ISystemConfig _systemConfig, - IOptimismPortal[] calldata _portals - ) - external - initializer - { + function initialize(ISystemConfig _systemConfig, IOptimismPortal[] calldata _portals) external initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol index 062dd5b53d8..28ace934cf6 100644 --- a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol @@ -46,13 +46,7 @@ contract L1ERC721Bridge is ERC721Bridge, ProxyAdminOwnedBase, ISemver { /// @notice Initializes the contract. /// @param _messenger Contract of the CrossDomainMessenger on this network. /// @param _systemConfig Contract of the SystemConfig contract on this network. - function initialize( - ICrossDomainMessenger _messenger, - ISystemConfig _systemConfig - ) - external - initializer - { + function initialize(ICrossDomainMessenger _messenger, ISystemConfig _systemConfig) external initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); diff --git a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol index e70d8ce5db9..d569d11623a 100644 --- a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol +++ b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol @@ -100,13 +100,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, ISemver { /// @notice Initializer. /// @param _messenger Contract for the CrossDomainMessenger on this network. /// @param _systemConfig Contract for the SystemConfig on this network. - function initialize( - ICrossDomainMessenger _messenger, - ISystemConfig _systemConfig - ) - external - initializer - { + function initialize(ICrossDomainMessenger _messenger, ISystemConfig _systemConfig) external initializer { // Initialization transactions must come from the ProxyAdmin or its owner. _assertOnlyProxyAdminOrProxyAdminOwner(); From 343f9b6508479ad82257c6596d768a05625ab018 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 31 Jul 2026 01:09:43 +0000 Subject: [PATCH 3/3] contracts-bedrock: bump SystemConfig to 4.1.0 The merge from develop brought in #21641, which had already taken 4.0.0, so this branch's SystemConfig changes (initVersion removal) need their own version bump for the semver-diff check to pass. Co-Authored-By: Claude Co-authored-by: John Mardlin --- packages/contracts-bedrock/snapshots/semver-lock.json | 4 ++-- packages/contracts-bedrock/src/L1/SystemConfig.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 0eeafdde097..0ba4791333d 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -32,8 +32,8 @@ "sourceCodeHash": "0x5f8fd5a452e222b78fe9202210154f2b637e2fb5d49f63e29d39283394af9a6b" }, "src/L1/SystemConfig.sol:SystemConfig": { - "initCodeHash": "0xf4ac1154aeca8c40920b6008756825a264078ae906618400100c5e53d20ef795", - "sourceCodeHash": "0x0a636bc509e697f895f2c2b6ce2ced422d31d18336ad57241ef5ea6e87c6c3b9" + "initCodeHash": "0xa36662db47e1ab928214d2aa1d9e9e06501cce8af94968909a41963fa3b49a62", + "sourceCodeHash": "0xfebb01aa1adbc0a0f040138747f29eb688ebc1d0c98045e838e23580bc616e29" }, "src/L1/opcm/OPContractsManagerV2.sol:OPContractsManagerV2": { "initCodeHash": "0x5cf001b0bc8758c996db25ebdfe181516bfeb0697d066bbde2e907e76aaefd03", diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index 398c03d35d5..90ef5efacf9 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -174,9 +174,9 @@ contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, ISemver { error SystemConfig_InvalidFeatureState(); /// @notice Semantic version. - /// @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"; } /// @notice Constructs the SystemConfig contract.