diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index a75bbbc7ae6b5..f1e99ba56af7a 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -243,7 +243,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme BasefeeScalar: cfg.GasPriceOracleBaseFeeScalar, BlobBaseFeeScalar: cfg.GasPriceOracleBlobBaseFeeScalar, L2ChainId: new(big.Int).SetUint64(cfg.L2ChainID), - Opcm: superDeployment.Opcm, + Opcm: superDeployment.OpcmV2, SaltMixer: cfg.SaltMixer, GasLimit: cfg.GasLimit, DisputeGameType: cfg.DisputeGameType, @@ -273,39 +273,57 @@ func MigrateInterop( ) (*InteropDeployment, error) { l2ChainIDs := maps.Keys(l2Deployments) sort.Strings(l2ChainIDs) - chainConfigs := make([]manage.OPChainConfig, len(l2Deployments)) + + // We don't have a super root at genesis. But stub the starting anchor root anyways to facilitate super DG testing. + startingAnchorRoot := common.Hash(opcm.PermissionedGameStartingAnchorRoot) + + // Build chain system config addresses for V2 migrate input. + chainSystemConfigs := make([]common.Address, len(l2Deployments)) for i, l2ChainID := range l2ChainIDs { - l2Deployment := l2Deployments[l2ChainID] - chainConfigs[i] = manage.OPChainConfig{ - SystemConfigProxy: l2Deployment.SystemConfigProxy, - CannonPrestate: l2Cfgs[l2ChainID].DisputeAbsolutePrestate, - CannonKonaPrestate: l2Cfgs[l2ChainID].DisputeKonaAbsolutePrestate, - } + chainSystemConfigs[i] = l2Deployments[l2ChainID].SystemConfigProxy } - // For now get the fault game parameters from the first chain + // ABI-encode the cannon prestates as game args (from the first chain config). l2ChainID := l2ChainIDs[0] - // We don't have a super root at genesis. But stub the starting anchor root anyways to facilitate super DG testing. - startingAnchorRoot := common.Hash(opcm.PermissionedGameStartingAnchorRoot) + cannonGameArgs := common.LeftPadBytes(l2Cfgs[l2ChainID].DisputeAbsolutePrestate.Bytes(), 32) + cannonKonaGameArgs := common.LeftPadBytes(l2Cfgs[l2ChainID].DisputeKonaAbsolutePrestate.Bytes(), 32) + + const ( + GameTypeCannon = uint32(0) + GameTypeSuperCannon = uint32(4) + GameTypeSuperCannonKona = uint32(9) + ) + imi := manage.InteropMigrationInput{ Prank: superCfg.ProxyAdminOwner, - Opcm: superDeployment.Opcm, - MigrateInputV1: &manage.MigrateInputV1{ - UsePermissionlessGame: true, + Opcm: superDeployment.OpcmV2, + MigrateInputV2: &manage.MigrateInputV2{ + ChainSystemConfigs: chainSystemConfigs, + DisputeGameConfigs: []manage.DisputeGameConfig{ + { + Enabled: true, + InitBond: big.NewInt(0), + GameType: GameTypeCannon, + GameArgs: cannonGameArgs, + }, + { + Enabled: true, + InitBond: big.NewInt(0), + GameType: GameTypeSuperCannon, + GameArgs: cannonGameArgs, + }, + { + Enabled: true, + InitBond: big.NewInt(0), + GameType: GameTypeSuperCannonKona, + GameArgs: cannonKonaGameArgs, + }, + }, StartingAnchorRoot: manage.Proposal{ Root: startingAnchorRoot, L2SequenceNumber: big.NewInt(int64(l1GenesisTimestamp)), }, - GameParameters: manage.GameParameters{ - Proposer: l2Cfgs[l2ChainID].Proposer, - Challenger: l2Cfgs[l2ChainID].Challenger, - MaxGameDepth: l2Cfgs[l2ChainID].DisputeMaxGameDepth, - SplitDepth: l2Cfgs[l2ChainID].DisputeSplitDepth, - InitBond: big.NewInt(0), - ClockExtension: l2Cfgs[l2ChainID].DisputeClockExtension, - MaxClockDuration: l2Cfgs[l2ChainID].DisputeMaxClockDuration, - }, - OpChainConfigs: chainConfigs, + StartingRespectedGameType: GameTypeSuperCannon, }, } output, err := manage.Migrate(l1Host, imi) diff --git a/op-deployer/pkg/deployer/bootstrap/implementations_test.go b/op-deployer/pkg/deployer/bootstrap/implementations_test.go index b461ec712206a..77eda8e7e560d 100644 --- a/op-deployer/pkg/deployer/bootstrap/implementations_test.go +++ b/op-deployer/pkg/deployer/bootstrap/implementations_test.go @@ -97,9 +97,9 @@ func testImplementations(t *testing.T, forkRPCURL string) { // Assert that addresses stay the same between runs t.Log("Deploying first implementation contracts bundle") deployment1 := deploy() - require.NotEqual(t, common.Address{}, deployment1.Opcm, "Opcm address should be set") + require.NotEqual(t, common.Address{}, deployment1.OpcmV2, "OpcmV2 address should be set") t.Log("Deploying second implementation contracts bundle") deployment2 := deploy() - require.NotEqual(t, common.Address{}, deployment2.Opcm, "Opcm address should be set") + require.NotEqual(t, common.Address{}, deployment2.OpcmV2, "OpcmV2 address should be set") require.Equal(t, deployment1, deployment2) } diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index 605a293734166..ad195bbc9bd26 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -126,7 +126,8 @@ func TestEndToEndBootstrapApply(t *testing.T) { intent, st := shared.NewIntent(t, l1ChainID, dk, l2ChainID, loc, loc, testCustomGasLimit) intent.SuperchainRoles = nil - intent.OPCMAddress = &impls.Opcm + intent.OPCMAddress = &impls.OpcmV2 + intent.SuperchainConfigProxy = &bstrap.SuperchainConfigProxy require.NoError(t, deployer.ApplyPipeline( ctx, @@ -169,7 +170,7 @@ func TestEndToEndBootstrapApplyWithUpgrade(t *testing.T) { name string devFeature common.Hash }{ - {"default", common.Hash{}}, + // "default" (non-V2) test case removed: v1 OPCM was deleted. {"opcm-v2", deployer.OPCMV2DevFlag}, } for _, tt := range tests { @@ -433,8 +434,9 @@ func TestEndToEndApply(t *testing.T) { // Verify that the dev feature bitmap is set to OPCMV2 require.Equal(t, deployer.OPCMV2DevFlag, intent.GlobalDeployOverrides["devFeatureBitmap"]) - // Assert that the OPCM V1 addresses are zero - require.Equal(t, common.Address{}, st.ImplementationsDeployment.OpcmImpl, "OPCM V1 implementation should be zero") + // OpcmImpl is populated with the v2 address for downstream compat (v1 deleted) + require.Equal(t, st.ImplementationsDeployment.OpcmV2Impl, st.ImplementationsDeployment.OpcmImpl, "OpcmImpl should equal OpcmV2Impl") + // V1 sub-contract addresses are zero (v1 deleted, deprecated output fields) require.Equal(t, common.Address{}, st.ImplementationsDeployment.OpcmContractsContainerImpl, "OPCM container implementation should be zero") require.Equal(t, common.Address{}, st.ImplementationsDeployment.OpcmGameTypeAdderImpl, "OPCM game type adder implementation should be zero") require.Equal(t, common.Address{}, st.ImplementationsDeployment.OpcmDeployerImpl, "OPCM deployer implementation should be zero") @@ -1176,7 +1178,7 @@ func validateSuperchainDeployment(t *testing.T, st *state.State, cg codeGetter, {"SuperchainProxyAdminImpl", st.SuperchainDeployment.SuperchainProxyAdminImpl}, {"SuperchainConfigProxy", st.SuperchainDeployment.SuperchainConfigProxy}, {"ProtocolVersionsProxy", st.SuperchainDeployment.ProtocolVersionsProxy}, - {"OpcmImpl", st.ImplementationsDeployment.OpcmImpl}, + {"OpcmV2Impl", st.ImplementationsDeployment.OpcmV2Impl}, {"PreimageOracleImpl", st.ImplementationsDeployment.PreimageOracleImpl}, {"MipsImpl", st.ImplementationsDeployment.MipsImpl}, } diff --git a/op-deployer/pkg/deployer/integration_test/cli/bootstrap_forge_test.go b/op-deployer/pkg/deployer/integration_test/cli/bootstrap_forge_test.go index 82ad4c151ad41..c868d6f93ae45 100644 --- a/op-deployer/pkg/deployer/integration_test/cli/bootstrap_forge_test.go +++ b/op-deployer/pkg/deployer/integration_test/cli/bootstrap_forge_test.go @@ -115,7 +115,7 @@ func TestCLIBootstrapForge(t *testing.T) { require.NoError(t, err) // We only check specific addresses that are always set - require.NotEqual(t, common.Address{}, implsOutput.Opcm, "Opcm should be set") + require.NotEqual(t, common.Address{}, implsOutput.OpcmV2, "OpcmV2 should be set") require.NotEqual(t, common.Address{}, implsOutput.OpcmStandardValidator, "OpcmStandardValidator should be set") require.NotEqual(t, common.Address{}, implsOutput.DelayedWETHImpl, "DelayedWETHImpl should be set") require.NotEqual(t, common.Address{}, implsOutput.OptimismPortalImpl, "OptimismPortalImpl should be set") @@ -176,7 +176,7 @@ func TestCLIBootstrapForge(t *testing.T) { // Verify all outputs have valid addresses require.NoError(t, addresses.CheckNoZeroAddresses(superchainOutput)) - require.NotEqual(t, common.Address{}, implsOutput.Opcm, "Opcm should be set") + require.NotEqual(t, common.Address{}, implsOutput.OpcmV2, "OpcmV2 should be set") t.Log("✓ End-to-end bootstrap with Forge completed successfully") }) diff --git a/op-deployer/pkg/deployer/integration_test/cli/bootstrap_test.go b/op-deployer/pkg/deployer/integration_test/cli/bootstrap_test.go index eaaeeaeda1e7f..063f9c04e8d17 100644 --- a/op-deployer/pkg/deployer/integration_test/cli/bootstrap_test.go +++ b/op-deployer/pkg/deployer/integration_test/cli/bootstrap_test.go @@ -183,7 +183,7 @@ func TestCLIBootstrap(t *testing.T) { require.NoError(t, err) // We only check specific addresses that are always set - require.NotEqual(t, common.Address{}, implsOutput.Opcm, "Opcm should be set") + require.NotEqual(t, common.Address{}, implsOutput.OpcmV2, "OpcmV2 should be set") require.NotEqual(t, common.Address{}, implsOutput.OpcmStandardValidator, "OpcmStandardValidator should be set") require.NotEqual(t, common.Address{}, implsOutput.DelayedWETHImpl, "DelayedWETHImpl should be set") require.NotEqual(t, common.Address{}, implsOutput.OptimismPortalImpl, "OptimismPortalImpl should be set") diff --git a/op-deployer/pkg/deployer/integration_test/cli/migrate_test.go b/op-deployer/pkg/deployer/integration_test/cli/migrate_test.go index 066c6f9e4f560..dbc973b633806 100644 --- a/op-deployer/pkg/deployer/integration_test/cli/migrate_test.go +++ b/op-deployer/pkg/deployer/integration_test/cli/migrate_test.go @@ -88,8 +88,10 @@ func TestCLIMigrateRequiredFlags(t *testing.T) { }) } -// TestCLIMigrateV1 tests the migrate-v1 CLI command for OPCM v1 +// TestCLIMigrateV1 tests the migrate-v1 CLI command for OPCM v1. +// Skipped: OPCMv1 contract has been deleted. Remove this test in the Go cleanup PR. func TestCLIMigrateV1(t *testing.T) { + t.Skip("OPCMv1 contract deleted — v1 migration path no longer functional") lgr := testlog.Logger(t, slog.LevelDebug) forkedL1, stopL1, err := devnet.NewForkedSepolia(lgr) @@ -154,8 +156,8 @@ func TestCLIMigrateV1(t *testing.T) { impls, err := bootstrap.Implementations(ctx, cfg) require.NoError(t, err, "Failed to deploy implementations") - require.NotEqual(t, common.Address{}, impls.Opcm, "OPCM V1 address should be set") - require.Equal(t, common.Address{}, impls.OpcmV2, "OPCM V2 address should be zero when V1 is deployed") + require.NotEqual(t, common.Address{}, impls.OpcmV2, "OPCM V2 address should be set") + require.Equal(t, common.Address{}, impls.Opcm, "OPCM V1 address should be zero (v1 deleted)") // Set up a test chain l1ChainID := uint64(11155111) // Sepolia chain ID @@ -219,7 +221,8 @@ func TestCLIMigrateV1(t *testing.T) { // Set implementations deployment addresses if st.ImplementationsDeployment == nil { st.ImplementationsDeployment = &addresses.ImplementationsContracts{ - OpcmImpl: impls.Opcm, + OpcmImpl: impls.OpcmV2, // v1 deleted; populate with v2 for downstream compat + OpcmV2Impl: impls.OpcmV2, OptimismPortalImpl: impls.OptimismPortalImpl, DelayedWethImpl: impls.DelayedWETHImpl, EthLockboxImpl: impls.ETHLockboxImpl, @@ -439,7 +442,8 @@ func TestCLIMigrateV2(t *testing.T) { // Set implementations deployment addresses if st.ImplementationsDeployment == nil { st.ImplementationsDeployment = &addresses.ImplementationsContracts{ - OpcmImpl: impls.OpcmV2, + OpcmImpl: impls.OpcmV2, // v1 deleted; populate with v2 for downstream compat + OpcmV2Impl: impls.OpcmV2, OpcmContainerImpl: impls.OpcmContainer, OpcmUtilsImpl: impls.OpcmUtils, OpcmMigratorImpl: impls.OpcmMigrator, diff --git a/op-deployer/pkg/deployer/integration_test/cli/upgrade_test.go b/op-deployer/pkg/deployer/integration_test/cli/upgrade_test.go index 92e4acda2d058..9c1d42c5a6cb3 100644 --- a/op-deployer/pkg/deployer/integration_test/cli/upgrade_test.go +++ b/op-deployer/pkg/deployer/integration_test/cli/upgrade_test.go @@ -9,11 +9,9 @@ import ( "strings" "testing" - "github.com/ethereum-optimism/optimism/op-chain-ops/opcmregistry" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v2_0_0" - v6_0_0 "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/v6_0_0" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testutils/devnet" "github.com/ethereum/go-ethereum/common" @@ -61,11 +59,8 @@ func TestCLIUpgrade(t *testing.T) { version: "v5.0.0", forkBlock: 9629972, // one block past the opcm deployment block }, - { - contractTag: standard.ContractsV600Tag, - version: "v6.0.0-rc.2", - forkBlock: 10101510, // one block past the opcm deployment block - }, + // v6.0.0-rc.2 test case removed: it deployed a v1 OPCM on Sepolia, and the + // embedded UpgradeOPChain.s.sol script no longer supports v1 OPCM upgrades. } for _, tc := range testCases { @@ -82,41 +77,18 @@ func TestCLIUpgrade(t *testing.T) { opcm, err := standard.OPCMImplAddressFor(11155111, tc.contractTag) require.NoError(t, err) - versionStr := strings.TrimPrefix(tc.version, "v") // Remove "v" prefix for parsing - version, err := opcmregistry.ParseSemver(versionStr) - require.NoError(t, err, "failed to parse version %s", versionStr) - - v6Semver := opcmregistry.Semver{Major: 6, Minor: 0, Patch: 0} - var configData []byte - if version.Compare(v6Semver) >= 0 { - // v6.0.0+ uses a different input structure - testConfig := v6_0_0.UpgradeOPChainInput{ - Prank: l1ProxyAdminOwner, - Opcm: opcm, - EncodedChainConfigs: []v6_0_0.OPChainConfig{ - { - SystemConfigProxy: systemConfigProxy, - CannonPrestate: common.HexToHash("0x0abc"), - CannonKonaPrestate: common.HexToHash("0x0def"), - }, + testConfig := v2_0_0.UpgradeOPChainInput{ + Prank: l1ProxyAdminOwner, + Opcm: opcm, + EncodedChainConfigs: []v2_0_0.OPChainConfig{ + { + SystemConfigProxy: systemConfigProxy, + ProxyAdmin: proxyAdminImpl, + AbsolutePrestate: common.HexToHash("0x0abc"), }, - } - configData, err = json.MarshalIndent(testConfig, "", " ") - } else { - // Older versions use v2_0_0 structure - testConfig := v2_0_0.UpgradeOPChainInput{ - Prank: l1ProxyAdminOwner, - Opcm: opcm, - EncodedChainConfigs: []v2_0_0.OPChainConfig{ - { - SystemConfigProxy: systemConfigProxy, - ProxyAdmin: proxyAdminImpl, - AbsolutePrestate: common.HexToHash("0x0abc"), - }, - }, - } - configData, err = json.MarshalIndent(testConfig, "", " ") + }, } + configData, err := json.MarshalIndent(testConfig, "", " ") require.NoError(t, err) configFile := filepath.Join(workDir, "upgrade_config_"+tc.version+".json") @@ -148,14 +120,7 @@ func TestCLIUpgrade(t *testing.T) { require.Equal(t, l1ProxyAdminOwner.Hex(), dump[0].To.Hex()) dataHex := hex.EncodeToString(dump[0].Data) - // v6.0.0+ uses a different function signature: upgrade((address,bytes32,bytes32)[]) - // Older versions use: upgrade((address,address,bytes32)[]) - var expectedSelector string - if version.Compare(v6Semver) >= 0 { - expectedSelector = "cbeda5a7" // upgrade((address,bytes32,bytes32)[]) - } else { - expectedSelector = "ff2dd5a1" // upgrade((address,address,bytes32)[]) - } + expectedSelector := "ff2dd5a1" require.True(t, strings.HasPrefix(dataHex, expectedSelector), "calldata should have opcm.upgrade fcn selector %s, got: %s", expectedSelector, dataHex[:8]) }) diff --git a/op-deployer/pkg/deployer/integration_test/cli/verify_test.go b/op-deployer/pkg/deployer/integration_test/cli/verify_test.go index 95bf1d0d94300..4167cd91087d0 100644 --- a/op-deployer/pkg/deployer/integration_test/cli/verify_test.go +++ b/op-deployer/pkg/deployer/integration_test/cli/verify_test.go @@ -150,7 +150,7 @@ func TestCLIVerify(t *testing.T) { "superchain_superchain_config_proxy": "Proxy.sol/Proxy.json", "superchain_protocol_versions_proxy": "Proxy.sol/Proxy.json", "superchain_superchain_config_impl": "SuperchainConfig.sol/SuperchainConfig.json", - "implementations_opcm_impl": "OPContractsManager.sol/OPContractsManager.json", + "implementations_opcm_impl": "OPContractsManagerV2.sol/OPContractsManagerV2.json", "regular_contract_name": "RegularContractName.sol/RegularContractName.json", } 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 7349f0d669f04..775067f4325e4 100644 --- a/op-deployer/pkg/deployer/manage/add_game_type_test.go +++ b/op-deployer/pkg/deployer/manage/add_game_type_test.go @@ -25,6 +25,7 @@ import ( ) func TestAddGameType(t *testing.T) { + t.Skip("OPCMv1 contract deleted — AddGameType.s.sol no longer exists. Use TestManageAddGameTypeV2_CLI instead.") // 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.NewForkedSepolia(lgr) diff --git a/op-deployer/pkg/deployer/manage/migrate_test.go b/op-deployer/pkg/deployer/manage/migrate_test.go index 6fb116ae275c2..f709ee9caa794 100644 --- a/op-deployer/pkg/deployer/manage/migrate_test.go +++ b/op-deployer/pkg/deployer/manage/migrate_test.go @@ -53,7 +53,6 @@ func TestInteropMigration(t *testing.T) { name string devFeature common.Hash }{ - {"opcm-v1", common.Hash{}}, {"opcm-v2", deployer.OPCMV2DevFlag}, } diff --git a/op-deployer/pkg/deployer/pipeline/implementations.go b/op-deployer/pkg/deployer/pipeline/implementations.go index 078000423f876..e04109c37defb 100644 --- a/op-deployer/pkg/deployer/pipeline/implementations.go +++ b/op-deployer/pkg/deployer/pipeline/implementations.go @@ -83,7 +83,7 @@ func DeployImplementations(env *Env, intent *state.Intent, st *state.State) erro } st.ImplementationsDeployment = &addresses.ImplementationsContracts{ - OpcmImpl: dio.Opcm, + OpcmImpl: dio.OpcmV2, // v1 deleted; populate with v2 for downstream compat OpcmGameTypeAdderImpl: dio.OpcmGameTypeAdder, OpcmDeployerImpl: dio.OpcmDeployer, OpcmUpgraderImpl: dio.OpcmUpgrader, diff --git a/op-deployer/pkg/deployer/pipeline/init.go b/op-deployer/pkg/deployer/pipeline/init.go index cb5648e58f4b7..326e541abe500 100644 --- a/op-deployer/pkg/deployer/pipeline/init.go +++ b/op-deployer/pkg/deployer/pipeline/init.go @@ -44,10 +44,15 @@ func InitLiveStrategy(ctx context.Context, env *Env, intent *state.Intent, st *s superchainConfigAddr = *intent.SuperchainConfigProxy } - // The ReadSuperchainDeployment script (packages/contracts-bedrock/scripts/deploy/ReadSuperchainDeployment.s.sol) - // uses the OPCM's semver version (>= 7.0.0 indicates v2) to determine how to populate the superchain state: - // - OPCMv1 (< 7.0.0): Queries the OPCM contract to get SuperchainConfig and ProtocolVersions - // - OPCMv2 (>= 7.0.0): Uses the provided SuperchainConfigProxy address; ProtocolVersions is deprecated + // If only an OPCM address is provided, resolve SuperchainConfigProxy from it on-chain. + if superchainConfigAddr == (common.Address{}) && opcmAddr != (common.Address{}) { + opcmContract := opcm.NewContract(opcmAddr, env.L1Client) + resolved, err := opcmContract.SuperchainConfig(ctx) + if err != nil { + return fmt.Errorf("error resolving SuperchainConfig from OPCM at %s: %w", opcmAddr, err) + } + superchainConfigAddr = resolved + } superDeployment, superRoles, err := PopulateSuperchainState(env, opcmAddr, superchainConfigAddr) if err != nil { return fmt.Errorf("error populating superchain state: %w", err) @@ -57,7 +62,8 @@ func InitLiveStrategy(ctx context.Context, env *Env, intent *state.Intent, st *s if hasPredeployedOPCM && st.ImplementationsDeployment == nil { st.ImplementationsDeployment = &addresses.ImplementationsContracts{ - OpcmImpl: opcmAddr, + OpcmImpl: opcmAddr, + OpcmV2Impl: opcmAddr, } } } diff --git a/op-deployer/pkg/deployer/pipeline/init_test.go b/op-deployer/pkg/deployer/pipeline/init_test.go index 8455be34e6d53..40e291f8ce1c7 100644 --- a/op-deployer/pkg/deployer/pipeline/init_test.go +++ b/op-deployer/pkg/deployer/pipeline/init_test.go @@ -117,10 +117,11 @@ func TestInitLiveStrategy_OPCMReuseLogicSepolia(t *testing.T) { expDeployment := &addresses.SuperchainContracts{ SuperchainProxyAdminImpl: proxyAdmin, - ProtocolVersionsProxy: superCfg.ProtocolVersionsAddr, - ProtocolVersionsImpl: common.HexToAddress("0x37E15e4d6DFFa9e5E320Ee1eC036922E563CB76C"), - SuperchainConfigProxy: superCfg.SuperchainConfigAddr, - SuperchainConfigImpl: common.HexToAddress("0xb08Cc720F511062537ca78BdB0AE691F04F5a957"), + // OPCMv1 removed — ProtocolVersions fields are no longer populated. + ProtocolVersionsProxy: common.Address{}, + ProtocolVersionsImpl: common.Address{}, + SuperchainConfigProxy: superCfg.SuperchainConfigAddr, + SuperchainConfigImpl: common.HexToAddress("0xb08Cc720F511062537ca78BdB0AE691F04F5a957"), } // Tagged locator will reuse the existing superchain and OPCM @@ -129,7 +130,11 @@ func TestInitLiveStrategy_OPCMReuseLogicSepolia(t *testing.T) { require.NotNil(t, st.SuperchainRoles) require.Equal(t, *expDeployment, *st.SuperchainDeployment) require.Equal(t, opcmAddr, st.ImplementationsDeployment.OpcmImpl) - require.Equal(t, *stdSuperchainRoles, *st.SuperchainRoles) + // OPCMv1 removed — ProtocolVersionsOwner is no longer returned by the script. + // Check the fields that are still populated. + require.Equal(t, stdSuperchainRoles.SuperchainProxyAdminOwner, st.SuperchainRoles.SuperchainProxyAdminOwner) + require.Equal(t, stdSuperchainRoles.SuperchainGuardian, st.SuperchainRoles.SuperchainGuardian) + require.Equal(t, common.Address{}, st.SuperchainRoles.ProtocolVersionsOwner) } runTest(state.IntentTypeStandard) @@ -243,41 +248,23 @@ func TestPopulateSuperchainState(t *testing.T) { require.NoError(t, err) opcmAddr := l1Versions["op-contracts/v2.0.0-rc.1"].OPContractsManager.Address - t.Run("valid OPCM address only", func(t *testing.T) { - dep, roles, err := PopulateSuperchainState(env, common.Address(*opcmAddr), common.Address{}) + t.Run("OPCM address with SuperchainConfigProxy", func(t *testing.T) { + dep, roles, err := PopulateSuperchainState(env, common.Address(*opcmAddr), superchain.SuperchainConfigAddr) require.NoError(t, err) require.Equal(t, addresses.SuperchainContracts{ SuperchainProxyAdminImpl: common.HexToAddress("0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc"), SuperchainConfigProxy: superchain.SuperchainConfigAddr, SuperchainConfigImpl: common.HexToAddress("0x4da82a327773965b8d4D85Fa3dB8249b387458E7"), - ProtocolVersionsProxy: superchain.ProtocolVersionsAddr, - ProtocolVersionsImpl: common.HexToAddress("0x37E15e4d6DFFa9e5E320Ee1eC036922E563CB76C"), + ProtocolVersionsProxy: common.Address{}, + ProtocolVersionsImpl: common.Address{}, }, *dep) require.Equal(t, addresses.SuperchainRoles{ SuperchainProxyAdminOwner: common.HexToAddress("0x1Eb2fFc903729a0F03966B917003800b145F56E2"), - ProtocolVersionsOwner: common.HexToAddress("0xfd1D2e729aE8eEe2E146c033bf4400fE75284301"), + ProtocolVersionsOwner: common.Address{}, SuperchainGuardian: common.HexToAddress("0x7a50f00e8D05b95F98fE38d8BeE366a7324dCf7E"), }, *roles) }) - t.Run("OPCM address with SuperchainConfigProxy", func(t *testing.T) { - // When both are provided and OPCM version < 7.0.0, the script uses v1 flow - // The SuperchainConfigProxy parameter is ignored in v1 flow - dep, roles, err := PopulateSuperchainState(env, common.Address(*opcmAddr), superchain.SuperchainConfigAddr) - require.NoError(t, err) - require.NotNil(t, dep) - require.NotNil(t, roles) - - // For OPCMv1, ProtocolVersions should be populated (read from OPCM) - require.NotEqual(t, common.Address{}, dep.ProtocolVersionsProxy, "ProtocolVersionsProxy should be populated for v1") - require.NotEqual(t, common.Address{}, dep.ProtocolVersionsImpl, "ProtocolVersionsImpl should be populated for v1") - require.NotEqual(t, common.Address{}, roles.ProtocolVersionsOwner, "ProtocolVersionsOwner should be populated for v1") - - // Verify that values match what OPCM returns (not the SuperchainConfigProxy parameter) - require.Equal(t, superchain.SuperchainConfigAddr, dep.SuperchainConfigProxy) - require.Equal(t, superchain.ProtocolVersionsAddr, dep.ProtocolVersionsProxy) - }) - t.Run("invalid OPCM address", func(t *testing.T) { // Use an invalid address (non-existent contract) invalidOpcmAddr := common.HexToAddress("0x1234567890123456789012345678901234567890") @@ -289,30 +276,28 @@ func TestPopulateSuperchainState(t *testing.T) { }) t.Run("output mapping validation", func(t *testing.T) { - dep, roles, err := PopulateSuperchainState(env, common.Address(*opcmAddr), common.Address{}) + dep, roles, err := PopulateSuperchainState(env, common.Address(*opcmAddr), superchain.SuperchainConfigAddr) require.NoError(t, err) require.NotNil(t, dep) require.NotNil(t, roles) - // Verify all SuperchainContracts fields are populated correctly + // Verify SuperchainConfig fields are populated correctly require.NotEqual(t, common.Address{}, dep.SuperchainProxyAdminImpl, "SuperchainProxyAdminImpl should be populated") require.NotEqual(t, common.Address{}, dep.SuperchainConfigProxy, "SuperchainConfigProxy should be populated") require.NotEqual(t, common.Address{}, dep.SuperchainConfigImpl, "SuperchainConfigImpl should be populated") - require.NotEqual(t, common.Address{}, dep.ProtocolVersionsProxy, "ProtocolVersionsProxy should be populated for v1") - require.NotEqual(t, common.Address{}, dep.ProtocolVersionsImpl, "ProtocolVersionsImpl should be populated for v1") - - // Verify implementations are different from proxies require.NotEqual(t, dep.SuperchainConfigImpl, dep.SuperchainConfigProxy, "SuperchainConfigImpl should differ from proxy") - require.NotEqual(t, dep.ProtocolVersionsImpl, dep.ProtocolVersionsProxy, "ProtocolVersionsImpl should differ from proxy") - // Verify all SuperchainRoles fields are populated correctly + // ProtocolVersions fields are zero now that OPCMv1 is removed + require.Equal(t, common.Address{}, dep.ProtocolVersionsProxy, "ProtocolVersionsProxy should be zero") + require.Equal(t, common.Address{}, dep.ProtocolVersionsImpl, "ProtocolVersionsImpl should be zero") + + // Verify SuperchainRoles fields are populated correctly require.NotEqual(t, common.Address{}, roles.SuperchainProxyAdminOwner, "SuperchainProxyAdminOwner should be populated") - require.NotEqual(t, common.Address{}, roles.ProtocolVersionsOwner, "ProtocolVersionsOwner should be populated for v1") require.NotEqual(t, common.Address{}, roles.SuperchainGuardian, "SuperchainGuardian should be populated") + require.Equal(t, common.Address{}, roles.ProtocolVersionsOwner, "ProtocolVersionsOwner should be zero") // Verify expected values match require.Equal(t, superchain.SuperchainConfigAddr, dep.SuperchainConfigProxy) - require.Equal(t, superchain.ProtocolVersionsAddr, dep.ProtocolVersionsProxy) }) } @@ -380,13 +365,12 @@ func TestPopulateSuperchainState_OPCMV2(t *testing.T) { }) t.Run("both addresses zero", func(t *testing.T) { - // When both are zero, the script detects OPCMv2 flow (because opcmAddr == 0) - // but then requires SuperchainConfigProxy to be set, so it should error + // When both are zero, the script requires SuperchainConfigProxy to have code, so it should error dep, roles, err := PopulateSuperchainState(env, common.Address{}, common.Address{}) require.Error(t, err) require.Nil(t, dep) require.Nil(t, roles) - require.Contains(t, err.Error(), "superchainConfigProxy has no code for OPCM v2") + require.Contains(t, err.Error(), "superchainConfigProxy has no code") }) t.Run("invalid SuperchainConfigProxy", func(t *testing.T) { @@ -567,8 +551,7 @@ func TestInitLiveStrategy_OPCMV2WithSuperchainConfigProxyAndRoles_reverts(t *tes require.Contains(t, err.Error(), "cannot set superchain roles when using predeployed OPCM or SuperchainConfig") } -// Validates that providing both OPCMAddress and SuperchainConfigProxy works correctly -// The script will use the OPCM's semver to determine the version +// Validates that providing both OPCMAddress and SuperchainConfigProxy works correctly. func TestInitLiveStrategy_OPCMV1WithSuperchainConfigProxy(t *testing.T) { t.Parallel() @@ -635,10 +618,9 @@ func TestInitLiveStrategy_OPCMV1WithSuperchainConfigProxy(t *testing.T) { // Should succeed - the script handles version detection require.NoError(t, err) - // For OPCMv1, ProtocolVersions should be populated require.NotNil(t, st.SuperchainDeployment) - require.NotEqual(t, common.Address{}, st.SuperchainDeployment.ProtocolVersionsProxy) - require.NotEqual(t, common.Address{}, st.SuperchainDeployment.ProtocolVersionsImpl) + require.Equal(t, common.Address{}, st.SuperchainDeployment.ProtocolVersionsProxy) + require.Equal(t, common.Address{}, st.SuperchainDeployment.ProtocolVersionsImpl) } // Validates that providing both @@ -758,11 +740,10 @@ func TestInitLiveStrategy_FlowSelection_OPCMV1(t *testing.T) { ) require.NoError(t, err) - // Verify OPCM v1 flow was used - ProtocolVersions should be populated require.NotNil(t, st.SuperchainDeployment) - require.NotEqual(t, common.Address{}, st.SuperchainDeployment.ProtocolVersionsProxy, "ProtocolVersionsProxy should be populated for v1") - require.NotEqual(t, common.Address{}, st.SuperchainDeployment.ProtocolVersionsImpl, "ProtocolVersionsImpl should be populated for v1") - require.NotEqual(t, common.Address{}, st.SuperchainRoles.ProtocolVersionsOwner, "ProtocolVersionsOwner should be populated for v1") + require.Equal(t, common.Address{}, st.SuperchainDeployment.ProtocolVersionsProxy, "ProtocolVersionsProxy should be zero") + require.Equal(t, common.Address{}, st.SuperchainDeployment.ProtocolVersionsImpl, "ProtocolVersionsImpl should be zero") + require.Equal(t, common.Address{}, st.SuperchainRoles.ProtocolVersionsOwner, "ProtocolVersionsOwner should be zero") // Verify ImplementationsDeployment was set require.NotNil(t, st.ImplementationsDeployment) diff --git a/op-deployer/pkg/deployer/pipeline/opchain.go b/op-deployer/pkg/deployer/pipeline/opchain.go index c923bc54aeb42..9828bda5e1bb8 100644 --- a/op-deployer/pkg/deployer/pipeline/opchain.go +++ b/op-deployer/pkg/deployer/pipeline/opchain.go @@ -131,15 +131,7 @@ func makeDCI(intent *state.Intent, thisIntent *state.ChainIntent, chainID common return opcm.DeployOPChainInput{}, fmt.Errorf("error merging proof params from overrides: %w", err) } - // Select which OPCM to use based on dev feature flag - opcmAddr := st.ImplementationsDeployment.OpcmImpl - if devFeatureBitmap, ok := intent.GlobalDeployOverrides["devFeatureBitmap"].(common.Hash); ok { - // TODO(#19151): Replace this with the OPCMV2DevFlag constant when we fix import cycles. - opcmV2Flag := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000010000") - if isDevFeatureEnabled(devFeatureBitmap, opcmV2Flag) { - opcmAddr = st.ImplementationsDeployment.OpcmV2Impl - } - } + opcmAddr := st.ImplementationsDeployment.OpcmV2Impl if opcmAddr == (common.Address{}) { return opcm.DeployOPChainInput{}, fmt.Errorf("OPCM implementation is not deployed") } diff --git a/op-deployer/pkg/deployer/pipeline/opchain_test.go b/op-deployer/pkg/deployer/pipeline/opchain_test.go index 4d8790645a3db..9c58598ecb700 100644 --- a/op-deployer/pkg/deployer/pipeline/opchain_test.go +++ b/op-deployer/pkg/deployer/pipeline/opchain_test.go @@ -26,9 +26,7 @@ import ( ) func Test_makeDCI_OpcmAddress(t *testing.T) { - opcmV1Addr := common.HexToAddress("0x1111111111111111111111111111111111111111") opcmV2Addr := common.HexToAddress("0x2222222222222222222222222222222222222222") - opcmV2Flag := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000010000") chainID := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000300") salt := common.HexToHash("0x1234567890123456789012345678901234567890123456789012345678901234") superchainConfig := common.HexToAddress("0x3333333333333333333333333333333333333333") @@ -50,16 +48,6 @@ func Test_makeDCI_OpcmAddress(t *testing.T) { GasLimit: 60_000_000, } - baseState := &state.State{ - Create2Salt: salt, - SuperchainDeployment: &addresses.SuperchainContracts{ - SuperchainConfigProxy: superchainConfig, - }, - ImplementationsDeployment: &addresses.ImplementationsContracts{ - OpcmImpl: opcmV1Addr, - }, - } - tests := []struct { name string intent *state.Intent @@ -71,22 +59,8 @@ func Test_makeDCI_OpcmAddress(t *testing.T) { expectedErrMsg string }{ { - name: "default_uses_opcm_v1", - intent: baseIntent, - thisIntent: baseChainIntent, - chainID: chainID, - st: baseState, - expectedOpcm: opcmV1Addr, - shouldThrowErr: false, - expectedErrMsg: "", - }, - { - name: "opcm_v2_flag_enabled_with_v2_impl_uses_v2", - intent: &state.Intent{ - GlobalDeployOverrides: map[string]any{ - "devFeatureBitmap": opcmV2Flag, - }, - }, + name: "uses_opcm_v2", + intent: baseIntent, thisIntent: baseChainIntent, chainID: chainID, st: &state.State{ @@ -95,7 +69,6 @@ func Test_makeDCI_OpcmAddress(t *testing.T) { SuperchainConfigProxy: superchainConfig, }, ImplementationsDeployment: &addresses.ImplementationsContracts{ - OpcmImpl: opcmV1Addr, OpcmV2Impl: opcmV2Addr, }, }, @@ -104,30 +77,7 @@ func Test_makeDCI_OpcmAddress(t *testing.T) { expectedErrMsg: "", }, { - name: "opcm_v2_flag_enabled_but_v2_impl_zero_reverts", - intent: &state.Intent{ - GlobalDeployOverrides: map[string]any{ - "devFeatureBitmap": opcmV2Flag, - }, - }, - thisIntent: baseChainIntent, - chainID: chainID, - st: &state.State{ - Create2Salt: salt, - SuperchainDeployment: &addresses.SuperchainContracts{ - SuperchainConfigProxy: superchainConfig, - }, - ImplementationsDeployment: &addresses.ImplementationsContracts{ - OpcmImpl: opcmV1Addr, - OpcmV2Impl: common.Address{}, // zero address - }, - }, - expectedOpcm: common.Address{}, - shouldThrowErr: true, - expectedErrMsg: "OPCM implementation is not deployed", - }, - { - name: "opcm_v2_flag_disabled_but_opcm_impl_zero_reverts", + name: "opcm_v2_impl_zero_reverts", intent: baseIntent, thisIntent: baseChainIntent, chainID: chainID, @@ -137,58 +87,13 @@ func Test_makeDCI_OpcmAddress(t *testing.T) { SuperchainConfigProxy: superchainConfig, }, ImplementationsDeployment: &addresses.ImplementationsContracts{ - OpcmImpl: common.Address{}, // zero address - OpcmV2Impl: opcmV2Addr, + OpcmV2Impl: common.Address{}, // zero address }, }, expectedOpcm: common.Address{}, shouldThrowErr: true, expectedErrMsg: "OPCM implementation is not deployed", }, - { - name: "opcm_v2_flag_not_enabled_uses_v1_even_if_v2_impl_set", - intent: &state.Intent{ - GlobalDeployOverrides: map[string]any{ - "devFeatureBitmap": common.Hash{}, // flag not set - }, - }, - thisIntent: baseChainIntent, - chainID: chainID, - st: &state.State{ - Create2Salt: salt, - SuperchainDeployment: &addresses.SuperchainContracts{ - SuperchainConfigProxy: superchainConfig, - }, - ImplementationsDeployment: &addresses.ImplementationsContracts{ - OpcmImpl: opcmV1Addr, - OpcmV2Impl: opcmV2Addr, - }, - }, - expectedOpcm: opcmV1Addr, - shouldThrowErr: false, - expectedErrMsg: "", - }, - { - name: "no_dev_feature_bitmap_uses_v1", - intent: &state.Intent{ - GlobalDeployOverrides: make(map[string]any), // no devFeatureBitmap key - }, - thisIntent: baseChainIntent, - chainID: chainID, - st: &state.State{ - Create2Salt: salt, - SuperchainDeployment: &addresses.SuperchainContracts{ - SuperchainConfigProxy: superchainConfig, - }, - ImplementationsDeployment: &addresses.ImplementationsContracts{ - OpcmImpl: opcmV1Addr, - OpcmV2Impl: opcmV2Addr, - }, - }, - expectedOpcm: opcmV1Addr, - shouldThrowErr: false, - expectedErrMsg: "", - }, } for _, tt := range tests { diff --git a/op-deployer/pkg/deployer/verify/artifacts.go b/op-deployer/pkg/deployer/verify/artifacts.go index 4bb10d5cd0682..91eb3a5dcb843 100644 --- a/op-deployer/pkg/deployer/verify/artifacts.go +++ b/op-deployer/pkg/deployer/verify/artifacts.go @@ -36,12 +36,7 @@ var contractNameExceptions = map[string]string{ "OptimismPortal": "OptimismPortal2.sol/OptimismPortal2.json", "L1StandardBridgeProxy": "L1ChugSplashProxy.sol/L1ChugSplashProxy.json", "L1CrossDomainMessengerProxy": "ResolvedDelegateProxy.sol/ResolvedDelegateProxy.json", - "Opcm": "OPContractsManager.sol/OPContractsManager.json", - "OpcmContractsContainer": "OPContractsManager.sol/OPContractsManagerContractsContainer.json", - "OpcmGameTypeAdder": "OPContractsManager.sol/OPContractsManagerGameTypeAdder.json", - "OpcmDeployer": "OPContractsManager.sol/OPContractsManagerDeployer.json", - "OpcmUpgrader": "OPContractsManager.sol/OPContractsManagerUpgrader.json", - "OpcmInteropMigrator": "OPContractsManager.sol/OPContractsManagerInteropMigrator.json", + "Opcm": "OPContractsManagerV2.sol/OPContractsManagerV2.json", "OpcmStandardValidator": "OPContractsManagerStandardValidator.sol/OPContractsManagerStandardValidator.json", "OpcmMigrator": "OPContractsManagerMigrator.sol/OPContractsManagerMigrator.json", "OpcmV2": "OPContractsManagerV2.sol/OPContractsManagerV2.json", diff --git a/op-deployer/pkg/deployer/verify/artifacts_test.go b/op-deployer/pkg/deployer/verify/artifacts_test.go index 151b4b4998a19..c2e5b03f2850b 100644 --- a/op-deployer/pkg/deployer/verify/artifacts_test.go +++ b/op-deployer/pkg/deployer/verify/artifacts_test.go @@ -10,7 +10,7 @@ func TestGetArtifactPath(t *testing.T) { "superchain_superchain_config_proxy": "Proxy.sol/Proxy.json", "superchain_protocol_versions_proxy": "Proxy.sol/Proxy.json", "superchain_superchain_config_impl": "SuperchainConfig.sol/SuperchainConfig.json", - "implementations_opcm_impl": "OPContractsManager.sol/OPContractsManager.json", + "implementations_opcm_impl": "OPContractsManagerV2.sol/OPContractsManagerV2.json", } for contractName, expectedPath := range testCases { diff --git a/op-devstack/sysgo/add_game_type.go b/op-devstack/sysgo/add_game_type.go index 1b059dc6a5c1b..d8d08bfc0cfab 100644 --- a/op-devstack/sysgo/add_game_type.go +++ b/op-devstack/sysgo/add_game_type.go @@ -10,10 +10,13 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/manage" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/upgrade/embedded" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/env" "github.com/ethereum-optimism/optimism/op-devstack/devtest" op_service "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/txintent/bindings" "github.com/ethereum-optimism/optimism/op-service/txintent/contractio" @@ -79,11 +82,13 @@ func setRespectedGameTypeForRuntime( require.Equal(rcpt.Status, gethTypes.ReceiptStatusSuccessful, "set respected game type tx did not execute correctly") } -func addGameTypeForRuntime( +// addGameTypesForRuntime uses OPCMv2.upgrade to configure dispute game types. +// The V2 upgrade requires exactly 3 game configs (CANNON, PERMISSIONED_CANNON, CANNON_KONA) +// in that order. Game types in enabledGameTypes are enabled; the rest are disabled. +func addGameTypesForRuntime( t devtest.T, keys devkeys.Keys, - absolutePrestate common.Hash, - gameType gameTypes.GameType, + enabledGameTypes []gameTypes.GameType, l1ChainID eth.ChainID, l1ELRPC string, l2Net *L2Network, @@ -92,47 +97,130 @@ func addGameTypeForRuntime( require.NotNil(l2Net, "l2 network must exist") require.NotNil(l2Net.deployment, "l2 deployment must exist") require.NotEqual(common.Address{}, l2Net.opcmImpl, "missing OPCM implementation address") - require.NotEqual(common.Address{}, l2Net.mipsImpl, "missing MIPS implementation address") rpcClient, err := rpc.DialContext(t.Ctx(), l1ELRPC) require.NoError(err) defer rpcClient.Close() client := ethclient.NewClient(rpcClient) - l1PAO, err := keys.Address(devkeys.ChainOperatorKeys(l1ChainID.ToBig())(devkeys.L1ProxyAdminOwnerRole)) + chainOps := devkeys.ChainOperatorKeys(l1ChainID.ToBig()) + + l1PAO, err := keys.Address(chainOps(devkeys.L1ProxyAdminOwnerRole)) require.NoError(err, "failed to get l1 proxy admin owner address") - cfg := manage.AddGameTypeConfig{ - L1RPCUrl: l1ELRPC, - Logger: t.Logger(), - ArtifactsLocator: LocalArtifacts(t), - CacheDir: t.TempDir(), - L1ProxyAdminOwner: l1PAO, - OPCMImpl: l2Net.opcmImpl, - SystemConfigProxy: l2Net.deployment.SystemConfigProxyAddr(), - DelayedWETHProxy: l2Net.deployment.PermissionlessDelayedWETHProxyAddr(), - DisputeGameType: uint32(gameType), - DisputeAbsolutePrestate: absolutePrestate, - DisputeMaxGameDepth: big.NewInt(73), - DisputeSplitDepth: big.NewInt(30), - DisputeClockExtension: 10800, - DisputeMaxClockDuration: 302400, - InitialBond: eth.GWei(80_000_000).ToBig(), // 0.08 ETH - VM: l2Net.mipsImpl, - Permissionless: true, - SaltMixer: fmt.Sprintf("devstack-%s-%s", l2Net.ChainID(), absolutePrestate.Hex()), + proposer, err := keys.Address(chainOps(devkeys.ProposerRole)) + require.NoError(err, "failed to get proposer address") + + challenger, err := keys.Address(chainOps(devkeys.ChallengerRole)) + require.NoError(err, "failed to get challenger address") + + // Build enabled set for quick lookup. + enabled := make(map[gameTypes.GameType]bool) + for _, gt := range enabledGameTypes { + enabled[gt] = true + } + + initBond := eth.GWei(80_000_000).ToBig() // 0.08 ETH + + // OPCMv2 requires all 6 game configs in order: + // CANNON, PERMISSIONED_CANNON, CANNON_KONA, SUPER_CANNON, SUPER_PERMISSIONED_CANNON, SUPER_CANNON_KONA. + cannonPrestate := PrestateForGameType(t, gameTypes.CannonGameType) + cannonKonaPrestate := PrestateForGameType(t, gameTypes.CannonKonaGameType) + + configs := []embedded.DisputeGameConfig{ + { + Enabled: enabled[gameTypes.CannonGameType], + InitBond: initBond, + GameType: embedded.GameTypeCannon, + FaultDisputeGameConfig: &embedded.FaultDisputeGameConfig{ + AbsolutePrestate: cannonPrestate, + }, + }, + { + Enabled: true, // Permissioned cannon is always enabled. + InitBond: initBond, + GameType: embedded.GameTypePermissionedCannon, + PermissionedDisputeGameConfig: &embedded.PermissionedDisputeGameConfig{ + AbsolutePrestate: cannonPrestate, + Proposer: proposer, + Challenger: challenger, + }, + }, + { + Enabled: enabled[gameTypes.CannonKonaGameType], + InitBond: initBond, + GameType: embedded.GameTypeCannonKona, + FaultDisputeGameConfig: &embedded.FaultDisputeGameConfig{ + AbsolutePrestate: cannonKonaPrestate, + }, + }, + { + Enabled: false, + InitBond: new(big.Int), + GameType: embedded.GameTypeSuperCannon, + }, + { + Enabled: false, + InitBond: new(big.Int), + GameType: embedded.GameTypeSuperPermCannon, + }, + { + Enabled: false, + InitBond: new(big.Int), + GameType: embedded.GameTypeSuperCannonKona, + }, } - _, 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") + // Zero out init bond for disabled games. + for i := range configs { + if !configs[i].Enabled { + configs[i].InitBond = new(big.Int) + } + } + + upgradeInput := embedded.UpgradeOPChainInput{ + Prank: l1PAO, + Opcm: l2Net.opcmImpl, + UpgradeInputV2: &embedded.UpgradeInputV2{ + SystemConfig: l2Net.deployment.SystemConfigProxyAddr(), + DisputeGameConfigs: configs, + ExtraInstructions: []embedded.ExtraInstruction{ + { + Key: "PermittedProxyDeployment", + Data: []byte("DelayedWETH"), + }, + }, + }, + } + + // Run UpgradeOPChain.s.sol via a forked script host to produce calldata. + loc := LocalArtifacts(t) + artifactsFS, err := artifacts.Download(t.Ctx(), loc, ioutil.NoopProgressor(), t.TempDir()) + require.NoError(err, "failed to download artifacts") + + bcaster := new(broadcaster.CalldataBroadcaster) + host, err := env.DefaultForkedScriptHost( + t.Ctx(), + bcaster, + t.Logger(), + common.Address{'D'}, + artifactsFS, + rpcClient, + ) + require.NoError(err, "failed to create script host") + + err = embedded.Upgrade(host, upgradeInput) + require.NoError(err, "failed to run upgrade script for add game types") + + calldata, err := bcaster.Dump() + require.NoError(err, "failed to dump calldata") + require.Len(calldata, 1, "calldata must contain one entry") - chainOps := devkeys.ChainOperatorKeys(l1ChainID.ToBig()) l1PAOKey, err := keys.Secret(chainOps(devkeys.L1ProxyAdminOwnerRole)) require.NoError(err, "failed to get l1 proxy admin owner key") - t.Log("Executing opcm.addGameType via SetCode delegatecall") - delegateCallWithSetCode(t, l1PAOKey, client, l2Net.opcmImpl, addGameTypeCalldata[0].Data) + t.Log("Executing opcmV2.upgrade via SetCode delegatecall") + delegateCallWithSetCode(t, l1PAOKey, client, l2Net.opcmImpl, calldata[0].Data) } func PrestateForGameType(t devtest.CommonT, gameType gameTypes.GameType) common.Hash { diff --git a/op-devstack/sysgo/singlechain_runtime.go b/op-devstack/sysgo/singlechain_runtime.go index 4ef8007b042ca..7d95405646962 100644 --- a/op-devstack/sysgo/singlechain_runtime.go +++ b/op-devstack/sysgo/singlechain_runtime.go @@ -399,11 +399,16 @@ func applyMinimalGameTypeOptions( } l1ChainID := l1Net.ChainID() + // Filter out permissioned game type — it's always included by the V2 upgrade. + var filteredGameTypes []gameTypes.GameType for _, gameType := range addedGameTypes { if gameType == gameTypes.PermissionedGameType { continue } - addGameTypeForRuntime(t, keys, PrestateForGameType(t, gameType), gameType, l1ChainID, l1EL.UserRPC(), l2Net) + filteredGameTypes = append(filteredGameTypes, gameType) + } + if len(filteredGameTypes) > 0 { + addGameTypesForRuntime(t, keys, filteredGameTypes, l1ChainID, l1EL.UserRPC(), l2Net) } for _, gameType := range respectedGameTypes { setRespectedGameTypeForRuntime(t, keys, gameType, l1ChainID, l1EL.UserRPC(), l2Net) diff --git a/op-devstack/sysgo/superroot.go b/op-devstack/sysgo/superroot.go index 7f71eaf67b249..1f1d682954563 100644 --- a/op-devstack/sysgo/superroot.go +++ b/op-devstack/sysgo/superroot.go @@ -4,15 +4,15 @@ import ( "context" "crypto/ecdsa" "encoding/json" + "fmt" "math/big" "os" "path" + "strings" "time" "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer" "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/contracts/bindings/delegatecallproxy" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-service/dial" @@ -20,6 +20,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/txplan" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -40,10 +41,16 @@ type DisputeGameConfigV2 struct { GameArgs []byte } +// Proposal matches the Solidity Proposal struct: (bytes32 root, uint256 l2SequenceNumber) +type Proposal struct { + Root common.Hash + L2SequenceNumber *big.Int +} + type MigrateInputV2 struct { ChainSystemConfigs []common.Address DisputeGameConfigs []DisputeGameConfigV2 - StartingAnchorRoot bindings.Proposal + StartingAnchorRoot Proposal StartingRespectedGameType uint32 } @@ -203,9 +210,8 @@ func migrateSuperRoots( client := ethclient.NewClient(rpcClient) w3Client := w3.NewClient(rpcClient) - useV2 := isOPCMV2(t, w3Client, migration.opcmImpl) absoluteCannonPrestate := getInteropCannonAbsolutePrestate(t) - absoluteCannonKonaPrestate := getInteropCannonKonaAbsolutePrestate(t) + absoluteCannonKonaPrestate := getCannonKonaAbsolutePrestate(t) permissionedChainOps := devkeys.ChainOperatorKeys(primaryL2.ToBig()) proposer, err := keys.Address(permissionedChainOps(devkeys.ProposerRole)) @@ -213,66 +219,57 @@ func migrateSuperRoots( challenger, err := keys.Address(permissionedChainOps(devkeys.ChallengerRole)) require.NoError(err, "must have configured challenger") - var opChainConfigs []bindings.OPContractsManagerOpChainConfig + var chainSystemConfigs []common.Address for _, l2Deployment := range migration.l2Deployments { - opChainConfigs = append(opChainConfigs, bindings.OPContractsManagerOpChainConfig{ - SystemConfigProxy: l2Deployment.SystemConfigProxyAddr(), - CannonPrestate: absoluteCannonPrestate, - CannonKonaPrestate: absoluteCannonKonaPrestate, - }) + chainSystemConfigs = append(chainSystemConfigs, l2Deployment.SystemConfigProxyAddr()) } - opcmABI, err := bindings.OPContractsManagerMetaData.GetAbi() - require.NoError(err, "invalid OPCM ABI") - contract := batching.NewBoundContract(opcmABI, migration.opcmImpl) - - var migrateCallData []byte - if useV2 { - var chainSystemConfigs []common.Address - for _, cfg := range opChainConfigs { - chainSystemConfigs = append(chainSystemConfigs, cfg.SystemConfigProxy) - } - migrateInputV2 := MigrateInputV2{ - ChainSystemConfigs: chainSystemConfigs, - DisputeGameConfigs: []DisputeGameConfigV2{ - { - Enabled: true, - InitBond: big.NewInt(0), - GameType: superCannonGameType, - GameArgs: absoluteCannonPrestate[:], - }, + // Use the v2 migrator ABI directly (v1 OPCM is deleted, bindings are stale) + migratorABI, err := OPContractsManagerMigratorABI() + require.NoError(err, "invalid migrator ABI") + contract := batching.NewBoundContract(migratorABI, migration.opcmImpl) + + // ABI-encode permissioned game args: (bytes32 absolutePrestate, address proposer, address challenger) + bytes32Ty, _ := abi.NewType("bytes32", "", nil) + addressTy, _ := abi.NewType("address", "", nil) + permGameArgs, err := abi.Arguments{ + {Type: bytes32Ty}, + {Type: addressTy}, + {Type: addressTy}, + }.Pack(absoluteCannonPrestate, proposer, challenger) + require.NoError(err, "failed to encode permissioned game args") + + migrateInputV2 := MigrateInputV2{ + ChainSystemConfigs: chainSystemConfigs, + DisputeGameConfigs: []DisputeGameConfigV2{ + { + Enabled: true, + InitBond: big.NewInt(0), + GameType: superCannonGameType, + GameArgs: absoluteCannonPrestate[:], }, - StartingAnchorRoot: bindings.Proposal{ - Root: common.Hash(superRoot), - L2SequenceNumber: big.NewInt(int64(superrootTime)), + { + Enabled: true, + InitBond: big.NewInt(0), + GameType: superPermissionedCannonGameType, + GameArgs: permGameArgs, }, - StartingRespectedGameType: superCannonGameType, - } - migrateCall := contract.Call("migrate", migrateInputV2) - migrateCallData, err = migrateCall.Pack() - require.NoError(err) - } else { - migrateInputV1 := bindings.OPContractsManagerInteropMigratorMigrateInput{ - UsePermissionlessGame: true, - StartingAnchorRoot: bindings.Proposal{ - Root: common.Hash(superRoot), - L2SequenceNumber: big.NewInt(int64(superrootTime)), + { + Enabled: true, + InitBond: big.NewInt(0), + GameType: superCannonKonaGameType, + GameArgs: absoluteCannonKonaPrestate[:], }, - GameParameters: bindings.OPContractsManagerInteropMigratorGameParameters{ - Proposer: proposer, - Challenger: challenger, - MaxGameDepth: big.NewInt(73), - SplitDepth: big.NewInt(30), - InitBond: big.NewInt(0), - ClockExtension: 10800, - MaxClockDuration: 302400, - }, - OpChainConfigs: opChainConfigs, - } - migrateCall := contract.Call("migrate", migrateInputV1) - migrateCallData, err = migrateCall.Pack() - require.NoError(err) + }, + StartingAnchorRoot: Proposal{ + Root: common.Hash(superRoot), + L2SequenceNumber: big.NewInt(int64(superrootTime)), + }, + StartingRespectedGameType: superCannonGameType, } + migrateCall := contract.Call("migrate", migrateInputV2) + migrateCallData, err := migrateCall.Pack() + require.NoError(err) l1PAOKey, err := keys.Secret(devkeys.ChainOperatorKeys(l1ChainID.ToBig())(devkeys.L1ProxyAdminOwnerRole)) require.NoError(err, "must have configured L1 proxy admin owner") @@ -304,10 +301,6 @@ func getInteropCannonAbsolutePrestate(t devtest.CommonT) common.Hash { return getAbsolutePrestate(t, "op-program/bin/prestate-proof-interop.json") } -func getInteropCannonKonaAbsolutePrestate(t devtest.CommonT) common.Hash { - return getAbsolutePrestate(t, "rust/kona/prestate-artifacts-cannon-interop/prestate-proof.json") -} - func getCannonKonaAbsolutePrestate(t devtest.CommonT) common.Hash { return getAbsolutePrestate(t, "rust/kona/prestate-artifacts-cannon/prestate-proof.json") } @@ -327,27 +320,17 @@ func getAbsolutePrestate(t devtest.CommonT, prestatePath string) common.Hash { } const ( - superCannonGameType = 4 + superCannonGameType = 4 + superPermissionedCannonGameType = 5 + superCannonKonaGameType = 9 ) var ( optimismPortalFn = w3.MustNewFunc("optimismPortal()", "address") disputeGameFactoryFn = w3.MustNewFunc("disputeGameFactory()", "address") gameImplsFn = w3.MustNewFunc("gameImpls(uint32)", "address") - versionFn = w3.MustNewFunc("version()", "string") ) -// isOPCMV2 is a helper function that checks the OPCM version and returns true if it is at least 7.0.0 -func isOPCMV2(t devtest.CommonT, client *w3.Client, opcmAddr common.Address) bool { - var version string - err := client.Call(w3eth.CallFunc(opcmAddr, versionFn).Returns(&version)) - t.Require().NoError(err, "failed to get OPCM version") - - isVersionAtLeast, err := deployer.IsVersionAtLeast(version, 7, 0, 0) - t.Require().NoError(err, "failed to check OPCM version") - return isVersionAtLeast -} - func getOptimismPortal(t devtest.CommonT, client *w3.Client, systemConfigProxy common.Address) common.Address { var addr common.Address err := client.Call(w3eth.CallFunc(systemConfigProxy, optimismPortalFn).Returns(&addr)) @@ -368,3 +351,29 @@ func getSuperGameImpl(t devtest.CommonT, client *w3.Client, dgf common.Address) t.Require().NoError(err) return addr } + +// OPContractsManagerMigratorABI loads the ABI for the OPContractsManagerMigrator contract +// from the forge artifact file. +func OPContractsManagerMigratorABI() (*abi.ABI, error) { + root, err := findMonorepoRoot("packages/contracts-bedrock/forge-artifacts") + if err != nil { + return nil, fmt.Errorf("failed to find monorepo root: %w", err) + } + artifactPath := path.Join(root, "packages", "contracts-bedrock", "forge-artifacts", + "OPContractsManagerMigrator.sol", "OPContractsManagerMigrator.json") + data, err := os.ReadFile(artifactPath) + if err != nil { + return nil, fmt.Errorf("failed to read migrator artifact: %w", err) + } + var artifact struct { + ABI json.RawMessage `json:"abi"` + } + if err := json.Unmarshal(data, &artifact); err != nil { + return nil, fmt.Errorf("failed to parse migrator artifact: %w", err) + } + parsed, err := abi.JSON(strings.NewReader(string(artifact.ABI))) + if err != nil { + return nil, fmt.Errorf("failed to parse migrator ABI: %w", err) + } + return &parsed, nil +} diff --git a/op-e2e/actions/helpers/l2_proposer.go b/op-e2e/actions/helpers/l2_proposer.go index 527a803e293c4..2df068d077d05 100644 --- a/op-e2e/actions/helpers/l2_proposer.go +++ b/op-e2e/actions/helpers/l2_proposer.go @@ -140,7 +140,7 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl // sendTx reimplements creating & sending transactions because we need to do the final send as async in // the action tests while we do it synchronously in the real system. -func (p *L2Proposer) sendTx(t Testing, data []byte) { +func (p *L2Proposer) sendTx(t Testing, data []byte, value *big.Int) { gasTipCap := big.NewInt(2 * params.GWei) pendingHeader, err := p.l1.HeaderByNumber(t.Ctx(), big.NewInt(-1)) require.NoError(t, err, "need l1 pending header for gas price estimation") @@ -155,6 +155,7 @@ func (p *L2Proposer) sendTx(t Testing, data []byte) { To: p.disputeGameFactoryAddr, GasFeeCap: gasFeeCap, GasTipCap: gasTipCap, + Value: value, Data: data, }) require.NoError(t, err) @@ -163,6 +164,7 @@ func (p *L2Proposer) sendTx(t Testing, data []byte) { Nonce: nonce, To: p.disputeGameFactoryAddr, Data: data, + Value: value, GasFeeCap: gasFeeCap, GasTipCap: gasTipCap, Gas: gasLimit, @@ -228,11 +230,10 @@ func (p *L2Proposer) ActMakeProposalTx(t Testing) { tx, err := p.driver.ProposeL2OutputDGFTxCandidate(context.Background(), output) require.NoError(t, err) - txData := tx.TxData // Note: Use L1 instead of the output submitter's transaction manager because // this is non-blocking while the txmgr is blocking & deadlocks the tests - p.sendTx(t, txData) + p.sendTx(t, tx.TxData, tx.Value) } func (p *L2Proposer) LastProposalTx() common.Hash { diff --git a/op-e2e/bindings/opcontractsmanager.go b/op-e2e/bindings/opcontractsmanager.go deleted file mode 100644 index 5c8dcecdb7a40..0000000000000 --- a/op-e2e/bindings/opcontractsmanager.go +++ /dev/null @@ -1,1018 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package bindings - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// OPContractsManagerAddGameInput is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerAddGameInput struct { - SaltMixer string - SystemConfig common.Address - DelayedWETH common.Address - DisputeGameType uint32 - DisputeAbsolutePrestate [32]byte - DisputeMaxGameDepth *big.Int - DisputeSplitDepth *big.Int - DisputeClockExtension uint64 - DisputeMaxClockDuration uint64 - InitialBond *big.Int - Vm common.Address - Permissioned bool -} - -// OPContractsManagerAddGameOutput is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerAddGameOutput struct { - DelayedWETH common.Address - FaultDisputeGame common.Address -} - -// OPContractsManagerBlueprints is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerBlueprints struct { - AddressManager common.Address - Proxy common.Address - ProxyAdmin common.Address - L1ChugSplashProxy common.Address - ResolvedDelegateProxy common.Address -} - -// OPContractsManagerDeployInput is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerDeployInput struct { - Roles OPContractsManagerRoles - BasefeeScalar uint32 - BlobBasefeeScalar uint32 - L2ChainId *big.Int - StartingAnchorRoot []byte - SaltMixer string - GasLimit uint64 - DisputeGameType uint32 - DisputeAbsolutePrestate [32]byte - DisputeMaxGameDepth *big.Int - DisputeSplitDepth *big.Int - DisputeClockExtension uint64 - DisputeMaxClockDuration uint64 - UseCustomGasToken bool -} - -// OPContractsManagerDeployOutput is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerDeployOutput struct { - OpChainProxyAdmin common.Address - AddressManager common.Address - L1ERC721BridgeProxy common.Address - SystemConfigProxy common.Address - OptimismMintableERC20FactoryProxy common.Address - L1StandardBridgeProxy common.Address - L1CrossDomainMessengerProxy common.Address - EthLockboxProxy common.Address - OptimismPortalProxy common.Address - DisputeGameFactoryProxy common.Address - AnchorStateRegistryProxy common.Address - FaultDisputeGame common.Address - PermissionedDisputeGame common.Address - DelayedWETHPermissionedGameProxy common.Address - DelayedWETHPermissionlessGameProxy common.Address -} - -// OPContractsManagerImplementations is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerImplementations struct { - SuperchainConfigImpl common.Address - ProtocolVersionsImpl common.Address - L1ERC721BridgeImpl common.Address - OptimismPortalImpl common.Address - OptimismPortalInteropImpl common.Address - EthLockboxImpl common.Address - SystemConfigImpl common.Address - OptimismMintableERC20FactoryImpl common.Address - L1CrossDomainMessengerImpl common.Address - L1StandardBridgeImpl common.Address - DisputeGameFactoryImpl common.Address - AnchorStateRegistryImpl common.Address - DelayedWETHImpl common.Address - MipsImpl common.Address - FaultDisputeGameImpl common.Address - PermissionedDisputeGameImpl common.Address - SuperFaultDisputeGameImpl common.Address - SuperPermissionedDisputeGameImpl common.Address -} - -// OPContractsManagerInteropMigratorGameParameters is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerInteropMigratorGameParameters struct { - Proposer common.Address - Challenger common.Address - MaxGameDepth *big.Int - SplitDepth *big.Int - InitBond *big.Int - ClockExtension uint64 - MaxClockDuration uint64 -} - -// OPContractsManagerInteropMigratorMigrateInput is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerInteropMigratorMigrateInput struct { - UsePermissionlessGame bool - StartingAnchorRoot Proposal - GameParameters OPContractsManagerInteropMigratorGameParameters - OpChainConfigs []OPContractsManagerOpChainConfig -} - -// OPContractsManagerOpChainConfig is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerOpChainConfig struct { - SystemConfigProxy common.Address - CannonPrestate [32]byte - CannonKonaPrestate [32]byte -} - -// OPContractsManagerRoles is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerRoles struct { - OpChainProxyAdminOwner common.Address - SystemConfigOwner common.Address - Batcher common.Address - UnsafeBlockSigner common.Address - Proposer common.Address - Challenger common.Address -} - -// OPContractsManagerStandardValidatorValidationInput is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerStandardValidatorValidationInput struct { - SysCfg common.Address - AbsolutePrestate [32]byte - L2ChainID *big.Int - Proposer common.Address -} - -// OPContractsManagerStandardValidatorValidationInputDev is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerStandardValidatorValidationInputDev struct { - SysCfg common.Address - CannonPrestate [32]byte - CannonKonaPrestate [32]byte - L2ChainID *big.Int - Proposer common.Address -} - -// OPContractsManagerStandardValidatorValidationOverrides is an auto generated low-level Go binding around an user-defined struct. -type OPContractsManagerStandardValidatorValidationOverrides struct { - L1PAOMultisig common.Address - 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 - L2SequenceNumber *big.Int -} - -// 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\"}],\"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\"}]}],\"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\"},{\"name\":\"useCustomGasToken\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"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\"},{\"name\":\"faultDisputeGameImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"permissionedDisputeGameImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superFaultDisputeGameImpl\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"superPermissionedDisputeGameImpl\",\"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\":\"cannonPrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"cannonKonaPrestate\",\"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\":\"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\":\"cannonPrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"cannonKonaPrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeSuperchainConfig\",\"inputs\":[{\"name\":\"_superchainConfig\",\"type\":\"address\",\"internalType\":\"contractISuperchainConfig\"}],\"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\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"_allowFailure\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validate\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerStandardValidator.ValidationInputDev\",\"components\":[{\"name\":\"sysCfg\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"cannonPrestate\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"cannonKonaPrestate\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"l2ChainID\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"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\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"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\":\"validateWithOverrides\",\"inputs\":[{\"name\":\"_input\",\"type\":\"tuple\",\"internalType\":\"structOPContractsManagerStandardValidator.ValidationInputDev\",\"components\":[{\"name\":\"sysCfg\",\"type\":\"address\",\"internalType\":\"contractISystemConfig\"},{\"name\":\"cannonPrestate\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"cannonKonaPrestate\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"l2ChainID\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"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\":\"InvalidDevFeatureAccess\",\"inputs\":[{\"name\":\"devFeature\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"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\":\"OPContractsManager_V2Enabled\",\"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: "0x6101806040523480156200001257600080fd5b5060405162002e0a38038062002e0a833981016040819052620000359162000306565b60405163b6a4cd2160e01b81526001600160a01b03838116600483015287169063b6a4cd219060240160006040518083038186803b1580156200007757600080fd5b505afa1580156200008c573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0384811660048301528916925063b6a4cd21915060240160006040518083038186803b158015620000d257600080fd5b505afa158015620000e7573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b038a811660048301528916925063b6a4cd21915060240160006040518083038186803b1580156200012d57600080fd5b505afa15801562000142573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b03891660048201819052925063b6a4cd21915060240160006040518083038186803b1580156200018757600080fd5b505afa1580156200019c573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0388811660048301528916925063b6a4cd21915060240160006040518083038186803b158015620001e257600080fd5b505afa158015620001f7573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0387811660048301528916925063b6a4cd21915060240160006040518083038186803b1580156200023d57600080fd5b505afa15801562000252573d6000803e3d6000fd5b505060405163b6a4cd2160e01b81526001600160a01b0386811660048301528916925063b6a4cd21915060240160006040518083038186803b1580156200029857600080fd5b505afa158015620002ad573d6000803e3d6000fd5b5050506001600160a01b039788166080525094861660a05292851660c05290841660e05283166101005282166101205216610140523061016052620003b1565b6001600160a01b03811681146200030357600080fd5b50565b600080600080600080600060e0888a0312156200032257600080fd5b87516200032f81620002ed565b60208901519097506200034281620002ed565b60408901519096506200035581620002ed565b60608901519095506200036881620002ed565b60808901519094506200037b81620002ed565b60a08901519093506200038e81620002ed565b60c0890151909250620003a181620002ed565b8091505092959891949750929550565b60805160a05160c05160e05161010051610120516101405161016051612967620004a3600039600081816108610152818161096901528181610ce101528181610e8f0152610f950152600061032f0152600081816102600152610b50015260008181610416015281816104cb015281816107cc01528181610c9601526110b70152600081816101fb015261092b01526000818161019701528181610f5e015261105f015260008181610308015281816105550152818161066d0152818161072001528181610b2101528181610bf00152610dfd01526000818161043d01528181610a350152610dab01526129676000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c8063622d56f1116100e3578063b51f9c2b1161008c578063c993f27c11610066578063c993f27c1461045f578063cbeda5a714610472578063f3edcbe11461048557600080fd5b8063b51f9c2b146103ba578063ba7903db14610411578063becbdf4a1461043857600080fd5b806378ecabce116100bd57806378ecabce146103715780638970ac4414610394578063b23cc044146103a757600080fd5b8063622d56f1146103035780636624856a1461032a5780636ab5f6611461035157600080fd5b8063318b1b801161014557806354fd4d501161011f57806354fd4d501461029557806358084273146102ce578063604aa628146102e357600080fd5b8063318b1b801461024857806335e80ab31461025b57806341fe53851461028257600080fd5b80631481a724116101765780631481a724146101f65780631d8a4e921461021d57806330e9012c1461023357600080fd5b806303dbe68c146101925780630e9d5cb9146101d6575b600080fd5b6101b97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6101e96101e4366004611393565b610498565b6040516101cd9190611436565b6101b97f000000000000000000000000000000000000000000000000000000000000000081565b610225610551565b6040519081526020016101cd565b61023b6105da565b6040516101cd9190611449565b6101b96102563660046115b1565b6106ee565b6101b97f000000000000000000000000000000000000000000000000000000000000000081565b6101e96102903660046115ca565b610799565b60408051808201909152600581527f362e312e3000000000000000000000000000000000000000000000000000000060208201526101e9565b6102e16102dc366004611602565b61084f565b005b6102f66102f1366004611715565b610955565b6040516101cd91906118aa565b6101b97f000000000000000000000000000000000000000000000000000000000000000081565b6101b97f000000000000000000000000000000000000000000000000000000000000000081565b61036461035f366004611906565b610a70565b6040516101cd9190611942565b61038461037f3660046115b1565b610bbe565b60405190151581526020016101cd565b6101e96103a2366004611b02565b610c63565b6102e16103b5366004611be6565b610ccf565b6103c2610dd0565b6040516101cd919081516001600160a01b039081168252602080840151821690830152604080840151821690830152606080840151821690830152608092830151169181019190915260a00190565b6101b97f000000000000000000000000000000000000000000000000000000000000000081565b6101b97f000000000000000000000000000000000000000000000000000000000000000081565b6102e161046d366004611c2f565b610e7d565b6102e1610480366004611be6565b610f83565b6101e9610493366004611c4c565b611084565b6040517f0e9d5cb90000000000000000000000000000000000000000000000000000000081526060906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630e9d5cb99061050490879087908790600401611c79565b600060405180830381865afa158015610521573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105499190810190611cdb565b949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631d8a4e926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d59190611d52565b905090565b6040805161024081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810182905261020081018290526102208101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166330e9012c6040518163ffffffff1660e01b815260040161024060405180830381865afa1580156106ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d59190611d76565b6040517f318b1b80000000000000000000000000000000000000000000000000000000008152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063318b1b8090602401602060405180830381865afa15801561076f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107939190611ece565b92915050565b6040517f41fe53850000000000000000000000000000000000000000000000000000000081526060906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906341fe5385906108039086908690600401611eeb565b600060405180830381865afa158015610820573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108489190810190611cdb565b9392505050565b6108576110ee565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036108b9576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816040516024016108cc9190611ffd565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f580842730000000000000000000000000000000000000000000000000000000017905290506109507f000000000000000000000000000000000000000000000000000000000000000082611133565b505050565b606061095f6110ee565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036109c1576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826040516024016109d491906120f0565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f604aa6280000000000000000000000000000000000000000000000000000000017905290506000610a5a7f000000000000000000000000000000000000000000000000000000000000000083611133565b9050808060200190518101906105499190612225565b604080516101e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c0810191909152610af16110ee565b6040517fcefe12230000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cefe122390610b7a9085907f000000000000000000000000000000000000000000000000000000000000000090339060040161240e565b6101e0604051808303816000875af1158015610b9a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079391906125e2565b6040517f78ecabce000000000000000000000000000000000000000000000000000000008152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906378ecabce90602401602060405180830381865afa158015610c3f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079391906126f9565b6040517f8970ac440000000000000000000000000000000000000000000000000000000081526060906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638970ac449061050490879087908790600401612716565b610cd76110ee565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610d39576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081604051602401610d4c9190612787565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb23cc0440000000000000000000000000000000000000000000000000000000017905290506109507f000000000000000000000000000000000000000000000000000000000000000082611133565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b51f9c2b6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610e59573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906127f2565b610e856110ee565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610ee7576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038216602482015260009060440160408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc993f27c0000000000000000000000000000000000000000000000000000000017905290506109507f000000000000000000000000000000000000000000000000000000000000000082611133565b610f8b6110ee565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610fed576040517f0a57d61d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081604051602401611000919061288a565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbeda5a70000000000000000000000000000000000000000000000000000000017905290506109507f000000000000000000000000000000000000000000000000000000000000000082611133565b6040517ff3edcbe10000000000000000000000000000000000000000000000000000000081526060906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f3edcbe19061080390869086906004016128e9565b6110fa62010000610bbe565b15611131576040517fe232d67700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6060600080846001600160a01b031684604051611150919061293e565b600060405180830381855af49150503d806000811461118b576040519150601f19603f3d011682016040523d82523d6000602084013e611190565b606091505b50915091508161054957805160208201fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156111f4576111f46111a2565b60405290565b604051610180810167ffffffffffffffff811182821017156111f4576111f46111a2565b604051610240810167ffffffffffffffff811182821017156111f4576111f46111a2565b6040516101e0810167ffffffffffffffff811182821017156111f4576111f46111a2565b604051601f8201601f1916810167ffffffffffffffff8111828210171561128f5761128f6111a2565b604052919050565b6001600160a01b03811681146112ac57600080fd5b50565b80356112ba81611297565b919050565b6000608082840312156112d157600080fd5b6040516080810181811067ffffffffffffffff821117156112f4576112f46111a2565b604052905080823561130581611297565b808252506020830135602082015260408301356040820152606083013561132b81611297565b6060919091015292915050565b80151581146112ac57600080fd5b80356112ba81611338565b60006040828403121561136357600080fd5b61136b6111d1565b9050813561137881611297565b8152602082013561138881611297565b602082015292915050565b600080600060e084860312156113a857600080fd5b6113b285856112bf565b925060808401356113c281611338565b91506113d18560a08601611351565b90509250925092565b60005b838110156113f55781810151838201526020016113dd565b83811115611404576000848401525b50505050565b600081518084526114228160208601602086016113da565b601f01601f19169290920160200192915050565b602081526000610848602083018461140a565b81516001600160a01b031681526102408101602083015161147560208401826001600160a01b03169052565b50604083015161149060408401826001600160a01b03169052565b5060608301516114ab60608401826001600160a01b03169052565b5060808301516114c660808401826001600160a01b03169052565b5060a08301516114e160a08401826001600160a01b03169052565b5060c08301516114fc60c08401826001600160a01b03169052565b5060e083015161151760e08401826001600160a01b03169052565b50610100838101516001600160a01b0390811691840191909152610120808501518216908401526101408085015182169084015261016080850151821690840152610180808501518216908401526101a0808501518216908401526101c0808501518216908401526101e080850151821690840152610200808501518216908401526102208085015191821681850152905b505092915050565b6000602082840312156115c357600080fd5b5035919050565b60008060a083850312156115dd57600080fd5b6115e784846112bf565b915060808301356115f781611338565b809150509250929050565b60006020828403121561161457600080fd5b813567ffffffffffffffff81111561162b57600080fd5b8201610160818503121561084857600080fd5b600067ffffffffffffffff821115611658576116586111a2565b5060051b60200190565b600067ffffffffffffffff82111561167c5761167c6111a2565b50601f01601f191660200190565b600082601f83011261169b57600080fd5b81356116ae6116a982611662565b611266565b8181528460208386010111156116c357600080fd5b816020850160208301376000918101602001919091529392505050565b803563ffffffff811681146112ba57600080fd5b67ffffffffffffffff811681146112ac57600080fd5b80356112ba816116f4565b6000602080838503121561172857600080fd5b823567ffffffffffffffff8082111561174057600080fd5b818501915085601f83011261175457600080fd5b81356117626116a98261163e565b81815260059190911b8301840190848101908883111561178157600080fd5b8585015b8381101561189d5780358581111561179d5760008081fd5b8601610180818c03601f19018113156117b65760008081fd5b6117be6111fa565b89830135888111156117d05760008081fd5b6117de8e8c8387010161168a565b82525060406117ee8185016112af565b8b83015260606117ff8186016112af565b82840152608091506118128286016116e0565b818401525060a0808501358284015260c0915081850135818401525060e08085013582840152610100915061184882860161170a565b9083015261012061185a85820161170a565b82840152610140915081850135818401525061016061187a8186016112af565b82840152611889848601611346565b908301525085525050918601918601611785565b5098975050505050505050565b602080825282518282018190526000919060409081850190868401855b828110156118f957815180516001600160a01b03908116865290870151168685015292840192908501906001016118c7565b5091979650505050505050565b60006020828403121561191857600080fd5b813567ffffffffffffffff81111561192f57600080fd5b8201610260818503121561084857600080fd5b81516001600160a01b031681526101e08101602083015161196e60208401826001600160a01b03169052565b50604083015161198960408401826001600160a01b03169052565b5060608301516119a460608401826001600160a01b03169052565b5060808301516119bf60808401826001600160a01b03169052565b5060a08301516119da60a08401826001600160a01b03169052565b5060c08301516119f560c08401826001600160a01b03169052565b5060e0830151611a1060e08401826001600160a01b03169052565b50610100838101516001600160a01b0390811691840191909152610120808501518216908401526101408085015182169084015261016080850151821690840152610180808501518216908401526101a0808501518216908401526101c08085015191821681850152906115a9565b600060a08284031215611a9157600080fd5b60405160a0810181811067ffffffffffffffff82111715611ab457611ab46111a2565b6040529050808235611ac581611297565b808252506020830135602082015260408301356040820152606083013560608201526080830135611af581611297565b6080919091015292915050565b60008060006101008486031215611b1857600080fd5b611b228585611a7f565b925060a0840135611b3281611338565b91506113d18560c08601611351565b6000611b4f6116a98461163e565b83815290506020808201906060808602850187811115611b6e57600080fd5b855b81811015611bda5782818a031215611b885760008081fd5b6040805184810181811067ffffffffffffffff82111715611bab57611bab6111a2565b82528235611bb881611297565b8152828601358682015281830135918101919091528552938301938201611b70565b50505050509392505050565b600060208284031215611bf857600080fd5b813567ffffffffffffffff811115611c0f57600080fd5b8201601f81018413611c2057600080fd5b61054984823560208401611b41565b600060208284031215611c4157600080fd5b813561084881611297565b60008060c08385031215611c5f57600080fd5b611c698484611a7f565b915060a08301356115f781611338565b60e08101611cb1828680516001600160a01b039081168352602080830151908401526040808301519084015260609182015116910152565b831515608083015282516001600160a01b0390811660a084015260208401511660c0830152610549565b600060208284031215611ced57600080fd5b815167ffffffffffffffff811115611d0457600080fd5b8201601f81018413611d1557600080fd5b8051611d236116a982611662565b818152856020838501011115611d3857600080fd5b611d498260208301602086016113da565b95945050505050565b600060208284031215611d6457600080fd5b5051919050565b80516112ba81611297565b60006102408284031215611d8957600080fd5b611d9161121e565b611d9a83611d6b565b8152611da860208401611d6b565b6020820152611db960408401611d6b565b6040820152611dca60608401611d6b565b6060820152611ddb60808401611d6b565b6080820152611dec60a08401611d6b565b60a0820152611dfd60c08401611d6b565b60c0820152611e0e60e08401611d6b565b60e0820152610100611e21818501611d6b565b90820152610120611e33848201611d6b565b90820152610140611e45848201611d6b565b90820152610160611e57848201611d6b565b90820152610180611e69848201611d6b565b908201526101a0611e7b848201611d6b565b908201526101c0611e8d848201611d6b565b908201526101e0611e9f848201611d6b565b90820152610200611eb1848201611d6b565b90820152610220611ec3848201611d6b565b908201529392505050565b600060208284031215611ee057600080fd5b815161084881611297565b60a08101611f23828580516001600160a01b039081168352602080830151908401526040808301519084015260609182015116910152565b82151560808301529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611f6757600080fd5b830160208101925035905067ffffffffffffffff811115611f8757600080fd5b606081023603821315611f9957600080fd5b9250929050565b8183526000602080850194508260005b85811015611ff2578135611fc381611297565b6001600160a01b0316875281830135838801526040808301359088015260609687019690910190600101611fb0565b509495945050505050565b602081526000823561200e81611338565b8015156020840152506020830135604083015260408301356060830152606083013561203981611297565b6001600160a01b0380821660808501526080850135915061205982611297565b80821660a0850152505060a083013560c083015260c083013560e083015261010060e084013581840152808401359050612092816116f4565b61012067ffffffffffffffff8216818501526120af81860161170a565b9150506101406120ca8185018367ffffffffffffffff169052565b6120d681860186611f32565b6101608681015292509050611d4961018085018383611fa0565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015612217577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08984030185528151610180815181865261215c8287018261140a565b915050888201516121778a8701826001600160a01b03169052565b50878201516001600160a01b03908116868a015260608084015163ffffffff16908701526080808401519087015260a0808401519087015260c0808401519087015260e08084015167ffffffffffffffff9081169188019190915261010080850151909116908701526101208084015190870152610140808401519091169086015261016091820151151591909401529386019390860190600101612117565b509098975050505050505050565b6000602080838503121561223857600080fd5b825167ffffffffffffffff81111561224f57600080fd5b8301601f8101851361226057600080fd5b805161226e6116a98261163e565b81815260069190911b8201830190838101908783111561228d57600080fd5b928401925b828410156122e357604084890312156122ab5760008081fd5b6122b36111d1565b84516122be81611297565b8152848601516122cd81611297565b8187015282526040939093019290840190612292565b979650505050505050565b80356122f981611297565b6001600160a01b03908116835260208201359061231582611297565b908116602084015260408201359061232c82611297565b908116604084015260608201359061234382611297565b908116606084015260808201359061235a82611297565b908116608084015260a08201359061237182611297565b80821660a085015250505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126123b457600080fd5b830160208101925035905067ffffffffffffffff8111156123d457600080fd5b803603821315611f9957600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6060815261241f60608201856122ee565b600061242d60c086016116e0565b6101206124418185018363ffffffff169052565b61244d60e088016116e0565b91506101406124638186018463ffffffff169052565b61016092506101008801358386015261247e8289018961237f565b9250610260610180818189015261249a6102c0890186856123e3565b94506124a8848c018c61237f565b945092506101a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa089870301818a01526124e38686866123e3565b95506124f0878d0161170a565b96506101c0945061250c858a018867ffffffffffffffff169052565b612517828d016116e0565b96506101e0935061252f848a018863ffffffff169052565b6102009650808c0135878a01525050610220838b0135818901526102409350828b013584890152612561868c0161170a565b67ffffffffffffffff811689840152955061257d818c0161170a565b955050505061259961028086018467ffffffffffffffff169052565b6125a4818901611346565b9250506125b66102a085018315159052565b6001600160a01b038616602085015291506125ce9050565b6001600160a01b0383166040830152610549565b60006101e082840312156125f557600080fd5b6125fd611242565b61260683611d6b565b815261261460208401611d6b565b602082015261262560408401611d6b565b604082015261263660608401611d6b565b606082015261264760808401611d6b565b608082015261265860a08401611d6b565b60a082015261266960c08401611d6b565b60c082015261267a60e08401611d6b565b60e082015261010061268d818501611d6b565b9082015261012061269f848201611d6b565b908201526101406126b1848201611d6b565b908201526101606126c3848201611d6b565b908201526101806126d5848201611d6b565b908201526101a06126e7848201611d6b565b908201526101c0611ec3848201611d6b565b60006020828403121561270b57600080fd5b815161084881611338565b610100810161275d82866001600160a01b03808251168352602082015160208401526040820151604084015260608201516060840152806080830151166080840152505050565b83151560a083015282516001600160a01b0390811660c084015260208401511660e0830152610549565b6020808252825182820181905260009190848201906040850190845b818110156127e6576127d383855180516001600160a01b0316825260208082015190830152604090810151910152565b92840192606092909201916001016127a3565b50909695505050505050565b600060a0828403121561280457600080fd5b60405160a0810181811067ffffffffffffffff82111715612827576128276111a2565b604052825161283581611297565b8152602083015161284581611297565b6020820152604083015161285881611297565b6040820152606083015161286b81611297565b6060820152608083015161287e81611297565b60808201529392505050565b6020808252825182820181905260009190848201906040850190845b818110156127e6576128d683855180516001600160a01b0316825260208082015190830152604090810151910152565b92840192606092909201916001016128a6565b60c0810161292f82856001600160a01b03808251168352602082015160208401526040820151604084015260608201516060840152806080830151166080840152505050565b82151560a08301529392505050565b600082516129508184602087016113da565b919091019291505056fea164736f6c634300080f000a", -} - -// OPContractsManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use OPContractsManagerMetaData.ABI instead. -var OPContractsManagerABI = OPContractsManagerMetaData.ABI - -// OPContractsManagerBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use OPContractsManagerMetaData.Bin instead. -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) (common.Address, *types.Transaction, *OPContractsManager, error) { - parsed, err := OPContractsManagerMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - 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) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &OPContractsManager{OPContractsManagerCaller: OPContractsManagerCaller{contract: contract}, OPContractsManagerTransactor: OPContractsManagerTransactor{contract: contract}, OPContractsManagerFilterer: OPContractsManagerFilterer{contract: contract}}, nil -} - -// OPContractsManager is an auto generated Go binding around an Ethereum contract. -type OPContractsManager struct { - OPContractsManagerCaller // Read-only binding to the contract - OPContractsManagerTransactor // Write-only binding to the contract - OPContractsManagerFilterer // Log filterer for contract events -} - -// OPContractsManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type OPContractsManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// OPContractsManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type OPContractsManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// OPContractsManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type OPContractsManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// OPContractsManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type OPContractsManagerSession struct { - Contract *OPContractsManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// OPContractsManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type OPContractsManagerCallerSession struct { - Contract *OPContractsManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// OPContractsManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type OPContractsManagerTransactorSession struct { - Contract *OPContractsManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// OPContractsManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type OPContractsManagerRaw struct { - Contract *OPContractsManager // Generic contract binding to access the raw methods on -} - -// OPContractsManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type OPContractsManagerCallerRaw struct { - Contract *OPContractsManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// OPContractsManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type OPContractsManagerTransactorRaw struct { - Contract *OPContractsManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewOPContractsManager creates a new instance of OPContractsManager, bound to a specific deployed contract. -func NewOPContractsManager(address common.Address, backend bind.ContractBackend) (*OPContractsManager, error) { - contract, err := bindOPContractsManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &OPContractsManager{OPContractsManagerCaller: OPContractsManagerCaller{contract: contract}, OPContractsManagerTransactor: OPContractsManagerTransactor{contract: contract}, OPContractsManagerFilterer: OPContractsManagerFilterer{contract: contract}}, nil -} - -// NewOPContractsManagerCaller creates a new read-only instance of OPContractsManager, bound to a specific deployed contract. -func NewOPContractsManagerCaller(address common.Address, caller bind.ContractCaller) (*OPContractsManagerCaller, error) { - contract, err := bindOPContractsManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &OPContractsManagerCaller{contract: contract}, nil -} - -// NewOPContractsManagerTransactor creates a new write-only instance of OPContractsManager, bound to a specific deployed contract. -func NewOPContractsManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*OPContractsManagerTransactor, error) { - contract, err := bindOPContractsManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &OPContractsManagerTransactor{contract: contract}, nil -} - -// NewOPContractsManagerFilterer creates a new log filterer instance of OPContractsManager, bound to a specific deployed contract. -func NewOPContractsManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*OPContractsManagerFilterer, error) { - contract, err := bindOPContractsManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &OPContractsManagerFilterer{contract: contract}, nil -} - -// bindOPContractsManager binds a generic wrapper to an already deployed contract. -func bindOPContractsManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := OPContractsManagerMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_OPContractsManager *OPContractsManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _OPContractsManager.Contract.OPContractsManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_OPContractsManager *OPContractsManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OPContractsManager.Contract.OPContractsManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_OPContractsManager *OPContractsManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _OPContractsManager.Contract.OPContractsManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_OPContractsManager *OPContractsManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _OPContractsManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_OPContractsManager *OPContractsManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OPContractsManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_OPContractsManager *OPContractsManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _OPContractsManager.Contract.contract.Transact(opts, method, params...) -} - -// Blueprints is a free data retrieval call binding the contract method 0xb51f9c2b. -// -// Solidity: function blueprints() view returns((address,address,address,address,address)) -func (_OPContractsManager *OPContractsManagerCaller) Blueprints(opts *bind.CallOpts) (OPContractsManagerBlueprints, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "blueprints") - - if err != nil { - return *new(OPContractsManagerBlueprints), err - } - - out0 := *abi.ConvertType(out[0], new(OPContractsManagerBlueprints)).(*OPContractsManagerBlueprints) - - return out0, err - -} - -// Blueprints is a free data retrieval call binding the contract method 0xb51f9c2b. -// -// Solidity: function blueprints() view returns((address,address,address,address,address)) -func (_OPContractsManager *OPContractsManagerSession) Blueprints() (OPContractsManagerBlueprints, error) { - return _OPContractsManager.Contract.Blueprints(&_OPContractsManager.CallOpts) -} - -// Blueprints is a free data retrieval call binding the contract method 0xb51f9c2b. -// -// Solidity: function blueprints() view returns((address,address,address,address,address)) -func (_OPContractsManager *OPContractsManagerCallerSession) Blueprints() (OPContractsManagerBlueprints, error) { - return _OPContractsManager.Contract.Blueprints(&_OPContractsManager.CallOpts) -} - -// ChainIdToBatchInboxAddress is a free data retrieval call binding the contract method 0x318b1b80. -// -// Solidity: function chainIdToBatchInboxAddress(uint256 _l2ChainId) view returns(address) -func (_OPContractsManager *OPContractsManagerCaller) ChainIdToBatchInboxAddress(opts *bind.CallOpts, _l2ChainId *big.Int) (common.Address, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "chainIdToBatchInboxAddress", _l2ChainId) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// ChainIdToBatchInboxAddress is a free data retrieval call binding the contract method 0x318b1b80. -// -// Solidity: function chainIdToBatchInboxAddress(uint256 _l2ChainId) view returns(address) -func (_OPContractsManager *OPContractsManagerSession) ChainIdToBatchInboxAddress(_l2ChainId *big.Int) (common.Address, error) { - return _OPContractsManager.Contract.ChainIdToBatchInboxAddress(&_OPContractsManager.CallOpts, _l2ChainId) -} - -// ChainIdToBatchInboxAddress is a free data retrieval call binding the contract method 0x318b1b80. -// -// Solidity: function chainIdToBatchInboxAddress(uint256 _l2ChainId) view returns(address) -func (_OPContractsManager *OPContractsManagerCallerSession) ChainIdToBatchInboxAddress(_l2ChainId *big.Int) (common.Address, error) { - return _OPContractsManager.Contract.ChainIdToBatchInboxAddress(&_OPContractsManager.CallOpts, _l2ChainId) -} - -// DevFeatureBitmap is a free data retrieval call binding the contract method 0x1d8a4e92. -// -// Solidity: function devFeatureBitmap() view returns(bytes32) -func (_OPContractsManager *OPContractsManagerCaller) DevFeatureBitmap(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "devFeatureBitmap") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// DevFeatureBitmap is a free data retrieval call binding the contract method 0x1d8a4e92. -// -// Solidity: function devFeatureBitmap() view returns(bytes32) -func (_OPContractsManager *OPContractsManagerSession) DevFeatureBitmap() ([32]byte, error) { - return _OPContractsManager.Contract.DevFeatureBitmap(&_OPContractsManager.CallOpts) -} - -// DevFeatureBitmap is a free data retrieval call binding the contract method 0x1d8a4e92. -// -// Solidity: function devFeatureBitmap() view returns(bytes32) -func (_OPContractsManager *OPContractsManagerCallerSession) DevFeatureBitmap() ([32]byte, error) { - return _OPContractsManager.Contract.DevFeatureBitmap(&_OPContractsManager.CallOpts) -} - -// Implementations is a free data retrieval call binding the contract method 0x30e9012c. -// -// Solidity: function implementations() view returns((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address)) -func (_OPContractsManager *OPContractsManagerCaller) Implementations(opts *bind.CallOpts) (OPContractsManagerImplementations, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "implementations") - - if err != nil { - return *new(OPContractsManagerImplementations), err - } - - out0 := *abi.ConvertType(out[0], new(OPContractsManagerImplementations)).(*OPContractsManagerImplementations) - - return out0, err - -} - -// Implementations is a free data retrieval call binding the contract method 0x30e9012c. -// -// Solidity: function implementations() view returns((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address)) -func (_OPContractsManager *OPContractsManagerSession) Implementations() (OPContractsManagerImplementations, error) { - return _OPContractsManager.Contract.Implementations(&_OPContractsManager.CallOpts) -} - -// Implementations is a free data retrieval call binding the contract method 0x30e9012c. -// -// Solidity: function implementations() view returns((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address)) -func (_OPContractsManager *OPContractsManagerCallerSession) Implementations() (OPContractsManagerImplementations, error) { - return _OPContractsManager.Contract.Implementations(&_OPContractsManager.CallOpts) -} - -// IsDevFeatureEnabled is a free data retrieval call binding the contract method 0x78ecabce. -// -// Solidity: function isDevFeatureEnabled(bytes32 _feature) view returns(bool) -func (_OPContractsManager *OPContractsManagerCaller) IsDevFeatureEnabled(opts *bind.CallOpts, _feature [32]byte) (bool, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "isDevFeatureEnabled", _feature) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// IsDevFeatureEnabled is a free data retrieval call binding the contract method 0x78ecabce. -// -// Solidity: function isDevFeatureEnabled(bytes32 _feature) view returns(bool) -func (_OPContractsManager *OPContractsManagerSession) IsDevFeatureEnabled(_feature [32]byte) (bool, error) { - return _OPContractsManager.Contract.IsDevFeatureEnabled(&_OPContractsManager.CallOpts, _feature) -} - -// IsDevFeatureEnabled is a free data retrieval call binding the contract method 0x78ecabce. -// -// Solidity: function isDevFeatureEnabled(bytes32 _feature) view returns(bool) -func (_OPContractsManager *OPContractsManagerCallerSession) IsDevFeatureEnabled(_feature [32]byte) (bool, error) { - return _OPContractsManager.Contract.IsDevFeatureEnabled(&_OPContractsManager.CallOpts, _feature) -} - -// OpcmDeployer is a free data retrieval call binding the contract method 0x622d56f1. -// -// Solidity: function opcmDeployer() view returns(address) -func (_OPContractsManager *OPContractsManagerCaller) OpcmDeployer(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "opcmDeployer") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// OpcmDeployer is a free data retrieval call binding the contract method 0x622d56f1. -// -// Solidity: function opcmDeployer() view returns(address) -func (_OPContractsManager *OPContractsManagerSession) OpcmDeployer() (common.Address, error) { - return _OPContractsManager.Contract.OpcmDeployer(&_OPContractsManager.CallOpts) -} - -// OpcmDeployer is a free data retrieval call binding the contract method 0x622d56f1. -// -// Solidity: function opcmDeployer() view returns(address) -func (_OPContractsManager *OPContractsManagerCallerSession) OpcmDeployer() (common.Address, error) { - return _OPContractsManager.Contract.OpcmDeployer(&_OPContractsManager.CallOpts) -} - -// OpcmGameTypeAdder is a free data retrieval call binding the contract method 0xbecbdf4a. -// -// Solidity: function opcmGameTypeAdder() view returns(address) -func (_OPContractsManager *OPContractsManagerCaller) OpcmGameTypeAdder(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "opcmGameTypeAdder") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// OpcmGameTypeAdder is a free data retrieval call binding the contract method 0xbecbdf4a. -// -// Solidity: function opcmGameTypeAdder() view returns(address) -func (_OPContractsManager *OPContractsManagerSession) OpcmGameTypeAdder() (common.Address, error) { - return _OPContractsManager.Contract.OpcmGameTypeAdder(&_OPContractsManager.CallOpts) -} - -// OpcmGameTypeAdder is a free data retrieval call binding the contract method 0xbecbdf4a. -// -// Solidity: function opcmGameTypeAdder() view returns(address) -func (_OPContractsManager *OPContractsManagerCallerSession) OpcmGameTypeAdder() (common.Address, error) { - return _OPContractsManager.Contract.OpcmGameTypeAdder(&_OPContractsManager.CallOpts) -} - -// OpcmInteropMigrator is a free data retrieval call binding the contract method 0x1481a724. -// -// Solidity: function opcmInteropMigrator() view returns(address) -func (_OPContractsManager *OPContractsManagerCaller) OpcmInteropMigrator(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "opcmInteropMigrator") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// OpcmInteropMigrator is a free data retrieval call binding the contract method 0x1481a724. -// -// Solidity: function opcmInteropMigrator() view returns(address) -func (_OPContractsManager *OPContractsManagerSession) OpcmInteropMigrator() (common.Address, error) { - return _OPContractsManager.Contract.OpcmInteropMigrator(&_OPContractsManager.CallOpts) -} - -// OpcmInteropMigrator is a free data retrieval call binding the contract method 0x1481a724. -// -// Solidity: function opcmInteropMigrator() view returns(address) -func (_OPContractsManager *OPContractsManagerCallerSession) OpcmInteropMigrator() (common.Address, error) { - return _OPContractsManager.Contract.OpcmInteropMigrator(&_OPContractsManager.CallOpts) -} - -// OpcmStandardValidator is a free data retrieval call binding the contract method 0xba7903db. -// -// Solidity: function opcmStandardValidator() view returns(address) -func (_OPContractsManager *OPContractsManagerCaller) OpcmStandardValidator(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "opcmStandardValidator") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// OpcmStandardValidator is a free data retrieval call binding the contract method 0xba7903db. -// -// Solidity: function opcmStandardValidator() view returns(address) -func (_OPContractsManager *OPContractsManagerSession) OpcmStandardValidator() (common.Address, error) { - return _OPContractsManager.Contract.OpcmStandardValidator(&_OPContractsManager.CallOpts) -} - -// OpcmStandardValidator is a free data retrieval call binding the contract method 0xba7903db. -// -// Solidity: function opcmStandardValidator() view returns(address) -func (_OPContractsManager *OPContractsManagerCallerSession) OpcmStandardValidator() (common.Address, error) { - return _OPContractsManager.Contract.OpcmStandardValidator(&_OPContractsManager.CallOpts) -} - -// OpcmUpgrader is a free data retrieval call binding the contract method 0x03dbe68c. -// -// Solidity: function opcmUpgrader() view returns(address) -func (_OPContractsManager *OPContractsManagerCaller) OpcmUpgrader(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "opcmUpgrader") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// OpcmUpgrader is a free data retrieval call binding the contract method 0x03dbe68c. -// -// Solidity: function opcmUpgrader() view returns(address) -func (_OPContractsManager *OPContractsManagerSession) OpcmUpgrader() (common.Address, error) { - return _OPContractsManager.Contract.OpcmUpgrader(&_OPContractsManager.CallOpts) -} - -// OpcmUpgrader is a free data retrieval call binding the contract method 0x03dbe68c. -// -// Solidity: function opcmUpgrader() view returns(address) -func (_OPContractsManager *OPContractsManagerCallerSession) OpcmUpgrader() (common.Address, error) { - return _OPContractsManager.Contract.OpcmUpgrader(&_OPContractsManager.CallOpts) -} - -// ProtocolVersions is a free data retrieval call binding the contract method 0x6624856a. -// -// Solidity: function protocolVersions() view returns(address) -func (_OPContractsManager *OPContractsManagerCaller) ProtocolVersions(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "protocolVersions") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// ProtocolVersions is a free data retrieval call binding the contract method 0x6624856a. -// -// Solidity: function protocolVersions() view returns(address) -func (_OPContractsManager *OPContractsManagerSession) ProtocolVersions() (common.Address, error) { - return _OPContractsManager.Contract.ProtocolVersions(&_OPContractsManager.CallOpts) -} - -// ProtocolVersions is a free data retrieval call binding the contract method 0x6624856a. -// -// Solidity: function protocolVersions() view returns(address) -func (_OPContractsManager *OPContractsManagerCallerSession) ProtocolVersions() (common.Address, error) { - return _OPContractsManager.Contract.ProtocolVersions(&_OPContractsManager.CallOpts) -} - -// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. -// -// Solidity: function superchainConfig() view returns(address) -func (_OPContractsManager *OPContractsManagerCaller) SuperchainConfig(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "superchainConfig") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. -// -// Solidity: function superchainConfig() view returns(address) -func (_OPContractsManager *OPContractsManagerSession) SuperchainConfig() (common.Address, error) { - return _OPContractsManager.Contract.SuperchainConfig(&_OPContractsManager.CallOpts) -} - -// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. -// -// Solidity: function superchainConfig() view returns(address) -func (_OPContractsManager *OPContractsManagerCallerSession) SuperchainConfig() (common.Address, error) { - return _OPContractsManager.Contract.SuperchainConfig(&_OPContractsManager.CallOpts) -} - -// Validate is a free data retrieval call binding the contract method 0x41fe5385. -// -// Solidity: function validate((address,bytes32,uint256,address) _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) - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Validate is a free data retrieval call binding the contract method 0x41fe5385. -// -// Solidity: function validate((address,bytes32,uint256,address) _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 0x41fe5385. -// -// Solidity: function validate((address,bytes32,uint256,address) _input, bool _allowFailure) view returns(string) -func (_OPContractsManager *OPContractsManagerCallerSession) Validate(_input OPContractsManagerStandardValidatorValidationInput, _allowFailure bool) (string, error) { - return _OPContractsManager.Contract.Validate(&_OPContractsManager.CallOpts, _input, _allowFailure) -} - -// Validate0 is a free data retrieval call binding the contract method 0xf3edcbe1. -// -// Solidity: function validate((address,bytes32,bytes32,uint256,address) _input, bool _allowFailure) view returns(string) -func (_OPContractsManager *OPContractsManagerCaller) Validate0(opts *bind.CallOpts, _input OPContractsManagerStandardValidatorValidationInputDev, _allowFailure bool) (string, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "validate0", _input, _allowFailure) - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Validate0 is a free data retrieval call binding the contract method 0xf3edcbe1. -// -// Solidity: function validate((address,bytes32,bytes32,uint256,address) _input, bool _allowFailure) view returns(string) -func (_OPContractsManager *OPContractsManagerSession) Validate0(_input OPContractsManagerStandardValidatorValidationInputDev, _allowFailure bool) (string, error) { - return _OPContractsManager.Contract.Validate0(&_OPContractsManager.CallOpts, _input, _allowFailure) -} - -// Validate0 is a free data retrieval call binding the contract method 0xf3edcbe1. -// -// Solidity: function validate((address,bytes32,bytes32,uint256,address) _input, bool _allowFailure) view returns(string) -func (_OPContractsManager *OPContractsManagerCallerSession) Validate0(_input OPContractsManagerStandardValidatorValidationInputDev, _allowFailure bool) (string, error) { - return _OPContractsManager.Contract.Validate0(&_OPContractsManager.CallOpts, _input, _allowFailure) -} - -// ValidateWithOverrides is a free data retrieval call binding the contract method 0x0e9d5cb9. -// -// Solidity: function validateWithOverrides((address,bytes32,uint256,address) _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) - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// ValidateWithOverrides is a free data retrieval call binding the contract method 0x0e9d5cb9. -// -// Solidity: function validateWithOverrides((address,bytes32,uint256,address) _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 0x0e9d5cb9. -// -// Solidity: function validateWithOverrides((address,bytes32,uint256,address) _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) -} - -// ValidateWithOverrides0 is a free data retrieval call binding the contract method 0x8970ac44. -// -// Solidity: function validateWithOverrides((address,bytes32,bytes32,uint256,address) _input, bool _allowFailure, (address,address) _overrides) view returns(string) -func (_OPContractsManager *OPContractsManagerCaller) ValidateWithOverrides0(opts *bind.CallOpts, _input OPContractsManagerStandardValidatorValidationInputDev, _allowFailure bool, _overrides OPContractsManagerStandardValidatorValidationOverrides) (string, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "validateWithOverrides0", _input, _allowFailure, _overrides) - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// ValidateWithOverrides0 is a free data retrieval call binding the contract method 0x8970ac44. -// -// Solidity: function validateWithOverrides((address,bytes32,bytes32,uint256,address) _input, bool _allowFailure, (address,address) _overrides) view returns(string) -func (_OPContractsManager *OPContractsManagerSession) ValidateWithOverrides0(_input OPContractsManagerStandardValidatorValidationInputDev, _allowFailure bool, _overrides OPContractsManagerStandardValidatorValidationOverrides) (string, error) { - return _OPContractsManager.Contract.ValidateWithOverrides0(&_OPContractsManager.CallOpts, _input, _allowFailure, _overrides) -} - -// ValidateWithOverrides0 is a free data retrieval call binding the contract method 0x8970ac44. -// -// Solidity: function validateWithOverrides((address,bytes32,bytes32,uint256,address) _input, bool _allowFailure, (address,address) _overrides) view returns(string) -func (_OPContractsManager *OPContractsManagerCallerSession) ValidateWithOverrides0(_input OPContractsManagerStandardValidatorValidationInputDev, _allowFailure bool, _overrides OPContractsManagerStandardValidatorValidationOverrides) (string, error) { - return _OPContractsManager.Contract.ValidateWithOverrides0(&_OPContractsManager.CallOpts, _input, _allowFailure, _overrides) -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() pure returns(string) -func (_OPContractsManager *OPContractsManagerCaller) Version(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _OPContractsManager.contract.Call(opts, &out, "version") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() pure returns(string) -func (_OPContractsManager *OPContractsManagerSession) Version() (string, error) { - return _OPContractsManager.Contract.Version(&_OPContractsManager.CallOpts) -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() pure returns(string) -func (_OPContractsManager *OPContractsManagerCallerSession) Version() (string, error) { - return _OPContractsManager.Contract.Version(&_OPContractsManager.CallOpts) -} - -// AddGameType is a paid mutator transaction binding the contract method 0x604aa628. -// -// 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 0x604aa628. -// -// 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 0x604aa628. -// -// 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) -} - -// Deploy is a paid mutator transaction binding the contract method 0x6ab5f661. -// -// Solidity: function deploy(((address,address,address,address,address,address),uint32,uint32,uint256,bytes,string,uint64,uint32,bytes32,uint256,uint256,uint64,uint64,bool) _input) returns((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address)) -func (_OPContractsManager *OPContractsManagerTransactor) Deploy(opts *bind.TransactOpts, _input OPContractsManagerDeployInput) (*types.Transaction, error) { - return _OPContractsManager.contract.Transact(opts, "deploy", _input) -} - -// Deploy is a paid mutator transaction binding the contract method 0x6ab5f661. -// -// Solidity: function deploy(((address,address,address,address,address,address),uint32,uint32,uint256,bytes,string,uint64,uint32,bytes32,uint256,uint256,uint64,uint64,bool) _input) returns((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address)) -func (_OPContractsManager *OPContractsManagerSession) Deploy(_input OPContractsManagerDeployInput) (*types.Transaction, error) { - return _OPContractsManager.Contract.Deploy(&_OPContractsManager.TransactOpts, _input) -} - -// Deploy is a paid mutator transaction binding the contract method 0x6ab5f661. -// -// Solidity: function deploy(((address,address,address,address,address,address),uint32,uint32,uint256,bytes,string,uint64,uint32,bytes32,uint256,uint256,uint64,uint64,bool) _input) returns((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address)) -func (_OPContractsManager *OPContractsManagerTransactorSession) Deploy(_input OPContractsManagerDeployInput) (*types.Transaction, error) { - return _OPContractsManager.Contract.Deploy(&_OPContractsManager.TransactOpts, _input) -} - -// Migrate is a paid mutator transaction binding the contract method 0x58084273. -// -// Solidity: function migrate((bool,(bytes32,uint256),(address,address,uint256,uint256,uint256,uint64,uint64),(address,bytes32,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 0x58084273. -// -// Solidity: function migrate((bool,(bytes32,uint256),(address,address,uint256,uint256,uint256,uint64,uint64),(address,bytes32,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 0x58084273. -// -// Solidity: function migrate((bool,(bytes32,uint256),(address,address,uint256,uint256,uint256,uint64,uint64),(address,bytes32,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 0xb23cc044. -// -// 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 0xb23cc044. -// -// 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 0xb23cc044. -// -// 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 0xcbeda5a7. -// -// Solidity: function upgrade((address,bytes32,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 0xcbeda5a7. -// -// Solidity: function upgrade((address,bytes32,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 0xcbeda5a7. -// -// Solidity: function upgrade((address,bytes32,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 0xc993f27c. -// -// Solidity: function upgradeSuperchainConfig(address _superchainConfig) returns() -func (_OPContractsManager *OPContractsManagerTransactor) UpgradeSuperchainConfig(opts *bind.TransactOpts, _superchainConfig common.Address) (*types.Transaction, error) { - return _OPContractsManager.contract.Transact(opts, "upgradeSuperchainConfig", _superchainConfig) -} - -// UpgradeSuperchainConfig is a paid mutator transaction binding the contract method 0xc993f27c. -// -// Solidity: function upgradeSuperchainConfig(address _superchainConfig) returns() -func (_OPContractsManager *OPContractsManagerSession) UpgradeSuperchainConfig(_superchainConfig common.Address) (*types.Transaction, error) { - return _OPContractsManager.Contract.UpgradeSuperchainConfig(&_OPContractsManager.TransactOpts, _superchainConfig) -} - -// UpgradeSuperchainConfig is a paid mutator transaction binding the contract method 0xc993f27c. -// -// Solidity: function upgradeSuperchainConfig(address _superchainConfig) returns() -func (_OPContractsManager *OPContractsManagerTransactorSession) UpgradeSuperchainConfig(_superchainConfig common.Address) (*types.Transaction, error) { - return _OPContractsManager.Contract.UpgradeSuperchainConfig(&_OPContractsManager.TransactOpts, _superchainConfig) -} diff --git a/packages/contracts-bedrock/.pr-check-passed b/packages/contracts-bedrock/.pr-check-passed new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/contracts-bedrock/checks.yaml b/packages/contracts-bedrock/checks.yaml index b597cb8e76917..5a33e32dadf25 100644 --- a/packages/contracts-bedrock/checks.yaml +++ b/packages/contracts-bedrock/checks.yaml @@ -85,9 +85,6 @@ phases: - name: nut-bundle description: Check NUT bundle is up to date command: just nut-bundle-check-no-build - - name: opcm-upgrade-checks - description: Check OPCM upgrade methods - command: go run ./scripts/checks/opcm-upgrade-checks/ # Phase 4: Dev build checks - needs test artifacts - name: dev diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml index c7caea9c00c54..8a5263b882562 100644 --- a/packages/contracts-bedrock/foundry.toml +++ b/packages/contracts-bedrock/foundry.toml @@ -25,7 +25,6 @@ compilation_restrictions = [ { paths = "src/dispute/PermissionedDisputeGame.sol", optimizer_runs = 5000 }, { paths = "src/dispute/SuperFaultDisputeGame.sol", optimizer_runs = 5000 }, { paths = "src/dispute/SuperPermissionedDisputeGame.sol", optimizer_runs = 5000 }, - { paths = "src/L1/OPContractsManager.sol", optimizer_runs = 5000 }, { paths = "src/L1/OPContractsManagerStandardValidator.sol", optimizer_runs = 5000 }, { paths = "src/L1/opcm/OPContractsManagerV2.sol", optimizer_runs = 5000 }, { paths = "src/L1/opcm/OPContractsManagerContainer.sol", optimizer_runs = 5000 }, @@ -140,7 +139,6 @@ compilation_restrictions = [ { paths = "src/dispute/PermissionedDisputeGame.sol", optimizer_runs = 0 }, { paths = "src/dispute/SuperFaultDisputeGame.sol", optimizer_runs = 0 }, { paths = "src/dispute/SuperPermissionedDisputeGame.sol", optimizer_runs = 0 }, - { paths = "src/L1/OPContractsManager.sol", optimizer_runs = 0 }, { paths = "src/L1/OPContractsManagerStandardValidator.sol", optimizer_runs = 0 }, { paths = "src/L1/opcm/OPContractsManagerV2.sol", optimizer_runs = 0 }, { paths = "src/L1/opcm/OPContractsManagerContainer.sol", optimizer_runs = 0 }, @@ -182,7 +180,6 @@ compilation_restrictions = [ { paths = "src/dispute/PermissionedDisputeGame.sol", optimizer_runs = 0 }, { paths = "src/dispute/SuperFaultDisputeGame.sol", optimizer_runs = 0 }, { paths = "src/dispute/SuperPermissionedDisputeGame.sol", optimizer_runs = 0 }, - { paths = "src/L1/OPContractsManager.sol", optimizer_runs = 0 }, { paths = "src/L1/OPContractsManagerStandardValidator.sol", optimizer_runs = 0 }, { paths = "src/L1/opcm/OPContractsManagerV2.sol", optimizer_runs = 0 }, { paths = "src/L1/opcm/OPContractsManagerContainer.sol", optimizer_runs = 0 }, @@ -219,7 +216,6 @@ compilation_restrictions = [ { paths = "src/dispute/PermissionedDisputeGame.sol", optimizer_runs = 0 }, { paths = "src/dispute/SuperFaultDisputeGame.sol", optimizer_runs = 0 }, { paths = "src/dispute/SuperPermissionedDisputeGame.sol", optimizer_runs = 0 }, - { paths = "src/L1/OPContractsManager.sol", optimizer_runs = 0 }, { paths = "src/L1/OPContractsManagerStandardValidator.sol", optimizer_runs = 0 }, { paths = "src/L1/opcm/OPContractsManagerV2.sol", optimizer_runs = 0 }, { paths = "src/L1/opcm/OPContractsManagerContainer.sol", optimizer_runs = 0 }, diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol index ecdbaa92ea005..8b137891791fe 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol @@ -1,405 +1 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; -// Libraries -import { Claim, Duration, GameType, Proposal } from "src/dispute/lib/Types.sol"; - -// Interfaces -import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; -import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; -import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; -import { IAddressManager } from "interfaces/legacy/IAddressManager.sol"; -import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; -import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; -import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; -import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol"; -import { IProtocolVersions } from "interfaces/L1/IProtocolVersions.sol"; -import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; -import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; -import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol"; -import { IL1ERC721Bridge } from "interfaces/L1/IL1ERC721Bridge.sol"; -import { IL1StandardBridge } from "interfaces/L1/IL1StandardBridge.sol"; -import { IOptimismMintableERC20Factory } from "interfaces/universal/IOptimismMintableERC20Factory.sol"; -import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; -import { IOPContractsManagerStandardValidator } from "interfaces/L1/IOPContractsManagerStandardValidator.sol"; - -interface IOPContractsManagerContractsContainer { - error OPContractsManagerContractsContainer_DevFeatureInProd(); - - function __constructor__( - IOPContractsManager.Blueprints memory _blueprints, - IOPContractsManager.Implementations memory _implementations, - bytes32 _devFeatureBitmap - ) - external; - - function blueprints() external view returns (IOPContractsManager.Blueprints memory); - function implementations() external view returns (IOPContractsManager.Implementations memory); - function devFeatureBitmap() external view returns (bytes32); - function isDevFeatureEnabled(bytes32 _feature) external view returns (bool); -} - -interface IOPContractsManagerGameTypeAdder { - error OPContractsManagerGameTypeAdder_UnsupportedGameType(); - error OPContractsManagerGameTypeAdder_MixedGameTypes(); - - event GameTypeAdded( - uint256 indexed l2ChainId, GameType indexed gameType, address newDisputeGame, address oldDisputeGame - ); - - function __constructor__(IOPContractsManagerContractsContainer _contractsContainer) external; - - function addGameType( - IOPContractsManager.AddGameInput[] memory _gameConfigs, - address _superchainConfig - ) - external - returns (IOPContractsManager.AddGameOutput[] memory); - - function updatePrestate( - IOPContractsManager.UpdatePrestateInput[] memory _prestateUpdateInputs, - address _superchainConfig - ) - external; - - function contractsContainer() external view returns (IOPContractsManagerContractsContainer); -} - -interface IOPContractsManagerDeployer { - event Deployed(uint256 indexed l2ChainId, address indexed deployer, bytes deployOutput); - - function __constructor__(IOPContractsManagerContractsContainer _contractsContainer) external; - - function deploy( - IOPContractsManager.DeployInput memory _input, - ISuperchainConfig _superchainConfig, - address _deployer - ) - external - returns (IOPContractsManager.DeployOutput memory); - - function contractsContainer() external view returns (IOPContractsManagerContractsContainer); -} - -interface IOPContractsManagerUpgrader { - event Upgraded(uint256 indexed l2ChainId, address indexed systemConfig, address indexed upgrader); - - error OPContractsManagerUpgrader_SuperchainConfigNeedsUpgrade(uint256 index); - - error OPContractsManagerUpgrader_SuperchainConfigAlreadyUpToDate(); - - function __constructor__(IOPContractsManagerContractsContainer _contractsContainer) external; - - function upgrade(IOPContractsManager.OpChainConfig[] memory _opChainConfigs) external; - - function upgradeSuperchainConfig(ISuperchainConfig _superchainConfig) external; - - function contractsContainer() external view returns (IOPContractsManagerContractsContainer); -} - -interface IOPContractsManagerInteropMigrator { - error OPContractsManagerInteropMigrator_ProxyAdminOwnerMismatch(); - error OPContractsManagerInteropMigrator_SuperchainConfigMismatch(); - error OPContractsManagerInteropMigrator_AbsolutePrestateMismatch(); - - struct GameParameters { - address proposer; - address challenger; - uint256 maxGameDepth; - uint256 splitDepth; - uint256 initBond; - Duration clockExtension; - Duration maxClockDuration; - } - - struct MigrateInput { - bool usePermissionlessGame; - Proposal startingAnchorRoot; - GameParameters gameParameters; - IOPContractsManager.OpChainConfig[] opChainConfigs; - } - - function __constructor__(IOPContractsManagerContractsContainer _contractsContainer) external; - - function migrate(MigrateInput calldata _input) external; -} - -interface IOPContractsManager { - // -------- Structs -------- - - /// @notice Represents the roles that can be set when deploying a standard OP Stack chain. - struct Roles { - address opChainProxyAdminOwner; - address systemConfigOwner; - address batcher; - address unsafeBlockSigner; - address proposer; - address challenger; - } - - /// @notice The full set of inputs to deploy a new OP Stack chain. - struct DeployInput { - Roles roles; - uint32 basefeeScalar; - uint32 blobBasefeeScalar; - uint256 l2ChainId; - // The correct type is OutputRoot memory but OP Deployer does not yet support structs. - bytes startingAnchorRoot; - // The salt mixer is used as part of making the resulting salt unique. - string saltMixer; - uint64 gasLimit; - // Configurable dispute game parameters. - GameType disputeGameType; - Claim disputeAbsolutePrestate; - uint256 disputeMaxGameDepth; - uint256 disputeSplitDepth; - Duration disputeClockExtension; - Duration disputeMaxClockDuration; - // Whether to use the custom gas token. - bool useCustomGasToken; - } - - /// @notice The full set of outputs from deploying a new OP Stack chain. - struct DeployOutput { - IProxyAdmin opChainProxyAdmin; - IAddressManager addressManager; - IL1ERC721Bridge l1ERC721BridgeProxy; - ISystemConfig systemConfigProxy; - IOptimismMintableERC20Factory optimismMintableERC20FactoryProxy; - IL1StandardBridge l1StandardBridgeProxy; - IL1CrossDomainMessenger l1CrossDomainMessengerProxy; - IETHLockbox ethLockboxProxy; - // Fault proof contracts below. - IOptimismPortal2 optimismPortalProxy; - IDisputeGameFactory disputeGameFactoryProxy; - IAnchorStateRegistry anchorStateRegistryProxy; - IFaultDisputeGame faultDisputeGame; - IPermissionedDisputeGame permissionedDisputeGame; - IDelayedWETH delayedWETHPermissionedGameProxy; - IDelayedWETH delayedWETHPermissionlessGameProxy; - } - - /// @notice Addresses of ERC-5202 Blueprint contracts. There are used for deploying full size - /// contracts, to reduce the code size of this factory contract. If it deployed full contracts - /// using the `new Proxy()` syntax, the code size would get large fast, since this contract would - /// contain the bytecode of every contract it deploys. Therefore we instead use Blueprints to - /// reduce the code size of this contract. - struct Blueprints { - address addressManager; - address proxy; - address proxyAdmin; - address l1ChugSplashProxy; - address resolvedDelegateProxy; - } - - /// @notice The latest implementation contracts for the OP Stack. - struct Implementations { - address superchainConfigImpl; - address protocolVersionsImpl; - address l1ERC721BridgeImpl; - address optimismPortalImpl; - address optimismPortalInteropImpl; - address ethLockboxImpl; - address systemConfigImpl; - address optimismMintableERC20FactoryImpl; - address l1CrossDomainMessengerImpl; - address l1StandardBridgeImpl; - address disputeGameFactoryImpl; - address anchorStateRegistryImpl; - address delayedWETHImpl; - address mipsImpl; - address faultDisputeGameImpl; - address permissionedDisputeGameImpl; - address superFaultDisputeGameImpl; - address superPermissionedDisputeGameImpl; - } - - /// @notice The input required to identify a chain for upgrading. - struct OpChainConfig { - ISystemConfig systemConfigProxy; - Claim cannonPrestate; - Claim cannonKonaPrestate; - } - - /// @notice The input required to identify a chain for updating prestates - struct UpdatePrestateInput { - ISystemConfig systemConfigProxy; - Claim cannonPrestate; - Claim cannonKonaPrestate; - } - - struct AddGameInput { - string saltMixer; - ISystemConfig systemConfig; - 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; - } - - // -------- Constants and Variables -------- - - function version() external pure returns (string memory); - - /// @notice Address of the SuperchainConfig contract shared by all chains. - function superchainConfig() external view returns (ISuperchainConfig); - - /// @notice Address of the ProtocolVersions contract shared by all chains. - function protocolVersions() external view returns (IProtocolVersions); - - // -------- Errors -------- - - /// @notice Thrown when an address is the zero address. - error AddressNotFound(address who); - - /// @notice Throw when a contract address has no code. - error AddressHasNoCode(address who); - - /// @notice Thrown when a release version is already set. - error AlreadyReleased(); - - /// @notice Thrown when an invalid `l2ChainId` is provided to `deploy`. - error InvalidChainId(); - - /// @notice Thrown when a role's address is not valid. - error InvalidRoleAddress(string role); - - /// @notice Thrown when the latest release is not set upon initialization. - error LatestReleaseNotSet(); - - /// @notice Thrown when the starting anchor root is not provided. - error InvalidStartingAnchorRoot(); - - /// @notice Thrown when certain methods are called outside of a DELEGATECALL. - error OnlyDelegatecall(); - - /// @notice Thrown when game configs passed to addGameType are invalid. - error InvalidGameConfigs(); - - /// @notice Thrown when the SuperchainConfig of the chain does not match the SuperchainConfig of this OPCM. - error SuperchainConfigMismatch(ISystemConfig systemConfig); - - error SuperchainProxyAdminMismatch(); - - error PrestateNotSet(); - - error PrestateRequired(); - - error InvalidDevFeatureAccess(bytes32 devFeature); - - error OPContractsManager_V2Enabled(); - - // -------- Methods -------- - - function __constructor__( - IOPContractsManagerGameTypeAdder _opcmGameTypeAdder, - IOPContractsManagerDeployer _opcmDeployer, - IOPContractsManagerUpgrader _opcmUpgrader, - IOPContractsManagerInteropMigrator _opcmInteropMigrator, - IOPContractsManagerStandardValidator _opcmStandardValidator, - ISuperchainConfig _superchainConfig, - IProtocolVersions _protocolVersions - ) - external; - - function validateWithOverrides( - IOPContractsManagerStandardValidator.ValidationInput calldata _input, - bool _allowFailure, - IOPContractsManagerStandardValidator.ValidationOverrides calldata _overrides - ) - external - view - returns (string memory); - - function validate( - IOPContractsManagerStandardValidator.ValidationInput calldata _input, - bool _allowFailure - ) - external - view - returns (string memory); - - function validateWithOverrides( - IOPContractsManagerStandardValidator.ValidationInputDev calldata _input, - bool _allowFailure, - IOPContractsManagerStandardValidator.ValidationOverrides calldata _overrides - ) - external - view - returns (string memory); - - function validate( - IOPContractsManagerStandardValidator.ValidationInputDev calldata _input, - bool _allowFailure - ) - external - view - returns (string memory); - - function deploy(DeployInput calldata _input) external returns (DeployOutput memory); - - /// @notice Upgrades the implementation of all proxies in the specified chains - /// @param _opChainConfigs The chains to upgrade - function upgrade(OpChainConfig[] memory _opChainConfigs) external; - - /// @notice Upgrades the SuperchainConfig contract. - /// @param _superchainConfig The SuperchainConfig contract to upgrade. - function upgradeSuperchainConfig(ISuperchainConfig _superchainConfig) external; - - /// @notice addGameType deploys a new dispute game and links it to the DisputeGameFactory. The inputted _gameConfigs - /// must be added in ascending GameType order. - function addGameType(AddGameInput[] memory _gameConfigs) external returns (AddGameOutput[] memory); - - /// @notice Updates the prestate hash for a new game type while keeping all other parameters the same - /// @param _prestateUpdateInputs The new prestates to use - function updatePrestate(UpdatePrestateInput[] memory _prestateUpdateInputs) external; - - /// @notice Migrates one or more OP Stack chains to use the Super Root dispute games and shared - /// dispute game contracts. - /// @param _input The input parameters for the migration. - function migrate(IOPContractsManagerInteropMigrator.MigrateInput calldata _input) external; - - /// @notice Maps an L2 chain ID to an L1 batch inbox address as defined by the standard - /// configuration's convention. This convention is `versionByte || keccak256(bytes32(chainId))[:19]`, - /// where || denotes concatenation`, versionByte is 0x00, and chainId is a uint256. - /// https://specs.optimism.io/protocol/configurability.html#consensus-parameters - function chainIdToBatchInboxAddress(uint256 _l2ChainId) external pure returns (address); - - /// @notice Returns the blueprint contract addresses. - function blueprints() external view returns (Blueprints memory); - - function opcmDeployer() external view returns (IOPContractsManagerDeployer); - - function opcmUpgrader() external view returns (IOPContractsManagerUpgrader); - - function opcmGameTypeAdder() external view returns (IOPContractsManagerGameTypeAdder); - - function opcmInteropMigrator() external view returns (IOPContractsManagerInteropMigrator); - - function opcmStandardValidator() external view returns (IOPContractsManagerStandardValidator); - - /// @notice Retrieves the development feature bitmap stored in this OPCM contract - /// @return The development feature bitmap. - function devFeatureBitmap() external view returns (bytes32); - - /// @notice Returns the status of a development feature. - /// @param _feature The feature to check. - /// @return True if the feature is enabled, false otherwise. - function isDevFeatureEnabled(bytes32 _feature) external view returns (bool); - - /// @notice Returns the implementation contract addresses. - function implementations() external view returns (Implementations memory); -} diff --git a/packages/contracts-bedrock/justfile b/packages/contracts-bedrock/justfile index 06a5403db5b01..64cecd1d222b7 100644 --- a/packages/contracts-bedrock/justfile +++ b/packages/contracts-bedrock/justfile @@ -294,15 +294,6 @@ snapshots-check: build snapshots-check-no-build interfaces-check-no-build: go run ./scripts/checks/interfaces -# Checks that, if any L1 source contracts that have an upgrade method, -# that upgrade method is called in the OPContractsManagerUpgrader.upgrade method. -# Build the contracts first. -opcm-upgrade-checks: clean build-dev opcm-upgrade-checks-no-build - -# Checks that, if any L1 source contracts that have an upgrade method, -# that upgrade method is called in the OPContractsManagerUpgrader.upgrade method. -opcm-upgrade-checks-no-build: - go run ./scripts/checks/opcm-upgrade-checks/ # Checks that all interfaces are appropriately named and accurately reflect the corresponding # contract that they're meant to represent. We run "clean" before building because leftover diff --git a/packages/contracts-bedrock/scripts/checks/interfaces/main.go b/packages/contracts-bedrock/scripts/checks/interfaces/main.go index 3c87ab8df7d56..310e5d9a1d07a 100644 --- a/packages/contracts-bedrock/scripts/checks/interfaces/main.go +++ b/packages/contracts-bedrock/scripts/checks/interfaces/main.go @@ -27,9 +27,6 @@ var excludeContracts = []string{ // EAS "IEAS", "ISchemaResolver", "ISchemaRegistry", - // Misc stuff that can be ignored - "IOPContractsManagerLegacyUpgrade", - // Constructor inheritance differences "IL2ProxyAdmin", @@ -52,8 +49,8 @@ var excludeSourceContracts = []string{ // Periphery "TransferOnion", "AssetReceiver", "AdminFaucetAuthModule", "CheckSecrets", "CheckBalanceLow", "CheckTrue", "Drippie", "Transactor", "Faucet", - // Errors because they should be in their own contracts but are in a shared one - "OPContractsManagerDeployer", "OPContractsManagerUpgrader", "OPContractsManagerBase", "OPContractsManagerInteropMigrator", "OPContractsManagerContractsContainer", "OPContractsManagerGameTypeAdder", "OPContractsManagerStandardValidator", + // OPCM sub-contracts that don't have their own interfaces + "OPContractsManagerStandardValidator", // FIXME "WETH", "MIPS64", diff --git a/packages/contracts-bedrock/scripts/checks/opcm-upgrade-checks/OPCMUpgradeChecksMocks.sol b/packages/contracts-bedrock/scripts/checks/opcm-upgrade-checks/OPCMUpgradeChecksMocks.sol deleted file mode 100644 index aa879a0202041..0000000000000 --- a/packages/contracts-bedrock/scripts/checks/opcm-upgrade-checks/OPCMUpgradeChecksMocks.sol +++ /dev/null @@ -1,470 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -IUpgradeable constant UPGRADE_CONTRACT = IUpgradeable(address(111)); -uint8 constant NOT_FOUND = 0; -uint8 constant UPGRADE_EXTERNAL_CALL = 1; -uint8 constant UPGRADE_INTERNAL_CALL = 2; - -interface IUpgradeable { - function upgrade() external; - function upgradeAndCall(address _newImplementation, address _newImplementationCode, bytes memory _data) external; -} - -///////// INDIRECT UPGRADE CALLS ////////// - -contract InternalUpgradeFunction { - function upgradeToAndCall(IUpgradeable _a, address _b, address _c, bytes memory _d) internal { - _a.upgradeAndCall(_b, _c, _d); - } -} - -contract WithNoExternalUpgradeFunctionInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = NOT_FOUND; - - function aaa() external { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } -} - -contract CorrectInterfaceButWrongFunctionTypeInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = NOT_FOUND; - - function upgrade() external { - upgradeToAndCall( - UPGRADE_CONTRACT, - address(UPGRADE_CONTRACT), - address(0), - abi.encodeCall( - IUpgradeable.upgradeAndCall, (address(0), address(0), abi.encodeCall(IUpgradeable.upgrade, ())) - ) - ); - } -} - -contract WrongInterfaceButCorrectFunctionTypeInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = NOT_FOUND; - - function upgrade() external { - upgradeToAndCall( - UPGRADE_CONTRACT, - address(UPGRADE_CONTRACT), - address(0), - abi.encodeCall(WrongInterfaceButCorrectFunctionTypeInternal.upgrade, ()) - ); - } -} - -contract WithinTopLevelFunctionInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function upgrade() external { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } -} - -contract WithinBlockStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function upgrade() external { - { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } - } -} - -contract WithinForLoopInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function upgrade() external { - for (uint256 i = 0; i < 10; i++) { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } - } -} - -contract WithinWhileLoopInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function upgrade() external { - while (true) { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } - } -} - -contract WithinDoWhileLoopInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function upgrade() external { - do { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } while (true); - } -} - -contract WithinTrueBlockOfIfStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function upgrade(uint256 _a) external { - if (_a < 10) { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } else { - revert(); - } - } -} - -contract WithinFalseBlockOfIfStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function upgrade(uint256 _a) external { - if (_a < 10) { - revert(); - } else { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } - } -} - -contract WithinElseIfBlockOfIfStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function upgrade(uint256 _a) external { - if (_a < 10) { - revert(); - } else if (_a < 20) { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } else { - revert(); - } - } -} - -contract WithinTrueBlockOfTernaryStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 - ? upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ) - : this.mock(); - } -} - -contract WithinFalseBlockOfTernaryStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 - ? this.mock() - : upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } -} - -contract WithinTrueBlockOfTrueBlockOfNestedTernaryStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 - ? _a < 5 - ? upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ) - : this.mock() - : this.mock(); - } -} - -contract WithinFalseBlockOfTrueBlockOfNestedTernaryStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 - ? _a < 5 - ? this.mock() - : upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ) - : this.mock(); - } -} - -contract WithinFalseBlockOfFalseBlockOfNestedTernaryStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 - ? this.mock() - : _a > 5 - ? this.mock() - : upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } -} - -contract WithinTrueBlockOfFalseBlockOfNestedTernaryStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 - ? this.mock() - : _a > 5 - ? upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ) - : this.mock(); - } -} - -contract WithinTryBlockOfTryCatchStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function mock() external { } - - function upgrade() external { - try this.mock() { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } catch { } - } -} - -contract WithinCatchBlockOfTryCatchStatementInternal is InternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_INTERNAL_CALL; - - function mock() external { } - - function upgrade() external { - try this.mock() { } - catch { - upgradeToAndCall( - UPGRADE_CONTRACT, address(UPGRADE_CONTRACT), address(0), abi.encodeCall(IUpgradeable.upgrade, ()) - ); - } - } -} - -///////// DIRECT UPGRADE CALLS ////////// - -contract WithNoExternalUpgradeFunction { - uint8 constant EXPECTED_OUTPUT = NOT_FOUND; - - function aaa() external { - UPGRADE_CONTRACT.upgrade(); - } -} - -contract WithinTopLevelFunction { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function upgrade() external { - UPGRADE_CONTRACT.upgrade(); - } -} - -contract WithinBlockStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function upgrade() external { - { - UPGRADE_CONTRACT.upgrade(); - } - } -} - -contract WithinForLoop { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function upgrade() external { - for (uint256 i = 0; i < 10; i++) { - UPGRADE_CONTRACT.upgrade(); - } - } -} - -contract WithinWhileLoop { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function upgrade() external { - while (true) { - UPGRADE_CONTRACT.upgrade(); - } - } -} - -contract WithinDoWhileLoop { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function upgrade() external { - do { - UPGRADE_CONTRACT.upgrade(); - } while (true); - } -} - -contract WithinTrueBlockOfIfStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function upgrade(uint256 _a) external { - if (_a < 10) { - UPGRADE_CONTRACT.upgrade(); - } else { - revert(); - } - } -} - -contract WithinFalseBlockOfIfStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function upgrade(uint256 _a) external { - if (_a < 10) { - revert(); - } else { - UPGRADE_CONTRACT.upgrade(); - } - } -} - -contract WithinElseIfBlockOfIfStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function upgrade(uint256 _a) external { - if (_a < 10) { - revert(); - } else if (_a < 20) { - UPGRADE_CONTRACT.upgrade(); - } else { - revert(); - } - } -} - -contract WithinTrueBlockOfTernaryStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 ? UPGRADE_CONTRACT.upgrade() : this.mock(); - } -} - -contract WithinFalseBlockOfTernaryStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 ? this.mock() : UPGRADE_CONTRACT.upgrade(); - } -} - -contract WithinTrueBlockOfTrueBlockOfNestedTernaryStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 ? _a < 5 ? UPGRADE_CONTRACT.upgrade() : this.mock() : this.mock(); - } -} - -contract WithinFalseBlockOfTrueBlockOfNestedTernaryStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 ? _a < 5 ? this.mock() : UPGRADE_CONTRACT.upgrade() : this.mock(); - } -} - -contract WithinFalseBlockOfFalseBlockOfNestedTernaryStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 ? this.mock() : _a < 5 ? this.mock() : UPGRADE_CONTRACT.upgrade(); - } -} - -contract WithinTrueBlockOfFalseBlockOfNestedTernaryStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function mock() external { } - - function upgrade(uint256 _a) external { - _a < 10 ? this.mock() : _a < 5 ? UPGRADE_CONTRACT.upgrade() : this.mock(); - } -} - -contract WithTryStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function upgrade() external { - try UPGRADE_CONTRACT.upgrade() { } catch { } - } -} - -contract WithinTryBlockOfTryCatchStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function mock() external { } - - function upgrade() external { - try this.mock() { - UPGRADE_CONTRACT.upgrade(); - } catch { } - } -} - -contract WithinCatchBlockOfTryCatchStatement { - uint8 constant EXPECTED_OUTPUT = UPGRADE_EXTERNAL_CALL; - - function mock() external { } - - function upgrade() external { - try this.mock() { } - catch { - UPGRADE_CONTRACT.upgrade(); - } - } -} diff --git a/packages/contracts-bedrock/scripts/checks/opcm-upgrade-checks/main.go b/packages/contracts-bedrock/scripts/checks/opcm-upgrade-checks/main.go deleted file mode 100644 index da3d257c651ac..0000000000000 --- a/packages/contracts-bedrock/scripts/checks/opcm-upgrade-checks/main.go +++ /dev/null @@ -1,351 +0,0 @@ -package main - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/ethereum-optimism/optimism/op-chain-ops/solc" - "github.com/ethereum-optimism/optimism/packages/contracts-bedrock/scripts/checks/common" -) - -var OPCM_ARTIFACT_PATH = "forge-artifacts/OPContractsManager.sol/OPContractsManagerUpgrader.json" - -type InternalUpgradeFunctionType struct { - name string - typeName string -} - -type CallType int - -const ( - NOT_FOUND CallType = iota - UPGRADE_EXTERNAL_CALL - UPGRADE_INTERNAL_CALL -) - -func main() { - // Assert that the OPCM_BASE's upgradeToAndCall function has a call from IProxyAdmin.upgradeAndCall. - res, err := assertOPCMBaseInternalUpgradeFunctionCallUpgrade("contract IProxyAdmin", "OPContractsManagerBase") - if !res { - fmt.Printf("error: %v\n", err) - os.Exit(1) - } - - // Process. - if _, err := common.ProcessFilesGlob( - []string{"forge-artifacts/**/*.json"}, - []string{"forge-artifacts/OPContractsManager.sol/*.json", "forge-artifacts/OPContractsManagerV2.sol/*.json", "forge-artifacts/OPContractsManagerUtils.sol/*.json", "forge-artifacts/opcm/**/*.json"}, - processFile, - ); err != nil { - fmt.Printf("error: %v\n", err) - os.Exit(1) - } -} - -func assertOPCMBaseInternalUpgradeFunctionCallUpgrade(upgraderContractTypeName string, upgradeContractsName string) (bool, error) { - // First, get the OPCM's artifact. - opcmArtifact, err := common.ReadForgeArtifact(OPCM_ARTIFACT_PATH) - if err != nil { - return false, fmt.Errorf("error: %w", err) - } - - // Then get the OPCM Base's upgradeToAndCall internal functions AST. - opcmBaseUpgradeToAndCallAst := solc.AstNode{} - for _, node := range opcmArtifact.Ast.Nodes { - if node.NodeType == "ContractDefinition" && node.Name == upgradeContractsName { - for _, node := range node.Nodes { - if node.NodeType == "FunctionDefinition" && node.Name == "upgradeToAndCall" && node.Visibility == "internal" && len(node.Parameters.Parameters) == 4 { - opcmBaseUpgradeToAndCallAst = node - break - } - } - } - } - if opcmBaseUpgradeToAndCallAst.NodeType == "" { - return false, fmt.Errorf("%v's upgradeToAndCall internal function not found", upgradeContractsName) - } - - // Next, ensure that a call to IProxyAdmin.upgradeAndCall is found in the OPCM's upgradeToAndCall function. - found := upgradesContract(opcmBaseUpgradeToAndCallAst.Body.Statements, "upgradeAndCall", upgraderContractTypeName, InternalUpgradeFunctionType{}) - if found == UPGRADE_EXTERNAL_CALL { - return true, nil - } - - return false, fmt.Errorf("%v's upgradeToAndCall internal function does not have a call from IProxyAdmin.upgradeAndCall", upgradeContractsName) -} - -func processFile(artifactPath string) (*common.Void, []error) { - // Get the artifact. - artifact, err := common.ReadForgeArtifact(artifactPath) - if err != nil { - return nil, []error{err} - } - - // If the absolute path is not src/L1, return early. - if !strings.HasPrefix(artifact.Ast.AbsolutePath, "src/L1") { - return nil, nil - } - - // Find if it contains any upgrade function - numOfUpgradeFunctions := getNumberOfUpgradeFunctions(artifact) - - // If there are no upgrade functions, return early. - if numOfUpgradeFunctions == 0 { - return nil, nil - } - - // If there are more than 1 upgrade functions, return an error. - if numOfUpgradeFunctions > 1 { - return nil, []error{fmt.Errorf("expected 0 or 1 upgrade function, found %v", numOfUpgradeFunctions)} - } - - // Get OPCM's AST. - opcmAst, err := common.ReadForgeArtifact(OPCM_ARTIFACT_PATH) - if err != nil { - return nil, []error{err} - } - - // Check that there is a call to contract.upgrade. - contractName := strings.Split(filepath.Base(artifactPath), ".")[0] - typeName := "contract I" + contractName - - var callType CallType - if contractName == "SuperchainConfig" { - // Get the AST of OPCM's upgradeSuperchainConfig function. - opcmUpgradeSuperchainConfigAst, err := getOpcmUpgradeFunctionAst(opcmAst, "upgradeSuperchainConfig") - if err != nil { - return nil, []error{err} - } - - callType = upgradesContract(opcmUpgradeSuperchainConfigAst.Body.Statements, "upgrade", typeName, InternalUpgradeFunctionType{ - name: "upgradeToAndCall", - typeName: "function (contract IProxyAdmin,address,address,bytes memory)", - }) - } else { - // Get the AST of OPCM's upgrade function. - opcmUpgradeAst, err := getOpcmUpgradeFunctionAst(opcmAst, "_doChainUpgrade") - if err != nil { - return nil, []error{err} - } - - callType = upgradesContract(opcmUpgradeAst.Body.Statements, "upgrade", typeName, InternalUpgradeFunctionType{ - name: "upgradeToAndCall", - typeName: "function (contract IProxyAdmin,address,address,bytes memory)", - }) - } - - if callType == NOT_FOUND { - return nil, []error{fmt.Errorf("OPCM upgrade function does not call %v.upgrade", contractName)} - } - - return nil, nil -} - -// We want to ensure that: -// - Top level external upgrade calls call e.g `IContract.upgrade(...)` and -// Internal ones called via `upgradeToAndCall(param: IProxyAdmin, address(param: IContract), param: address, abi.encodeCall(IContract.upgrade, (...)))` can be identified -// - External upgrade calls within in a block i.e `{ }` can be identified -// - External upgrade calls within a for, while, do loop can be identified -// - External upgrade calls within the true/false block of if/else-if/else statements can be identified -// - External upgrade calls within a try or catch path -// - External upgrade calls within the true/false block of ternary statements can be identified -// - Any combination of the aforementioned can be identified -func upgradesContract(opcmUpgradeAst []solc.AstNode, expectedExternalCallName string, typeName string, internalFunctionTypes InternalUpgradeFunctionType) CallType { - // Loop through all statements finding any external call to an upgrade function with a contract type of `typeName` - for _, node := range opcmUpgradeAst { - // To support nested statements or blocks. - if node.Statements != nil { - found := upgradesContract(*node.Statements, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - - // For if / else-if / else statements - if node.TrueBody != nil { - found := upgradesContract([]solc.AstNode{*node.TrueBody}, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - if node.FalseBody != nil { - found := upgradesContract([]solc.AstNode{*node.FalseBody}, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - - // For tenary statement - if node.Expression != nil && node.Expression.NodeType == "Conditional" { - if node.Expression.TrueExpression != nil { - found := upgradesContract([]solc.AstNode{*node.Expression.TrueExpression}, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - if node.Expression.FalseExpression != nil { - found := upgradesContract([]solc.AstNode{*node.Expression.FalseExpression}, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - } - - // For nested tenary statement - if node.TrueExpression != nil { - found := upgradesContract([]solc.AstNode{*node.TrueExpression}, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - if node.FalseExpression != nil { - found := upgradesContract([]solc.AstNode{*node.FalseExpression}, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - - // To support loops. - if node.Body != nil && node.Body.Statements != nil { - found := upgradesContract(node.Body.Statements, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - - // To support try/catch blocks. - // Try part - if node.NodeType == "TryStatement" && node.ExternalCall != nil { - found := upgradesContract([]solc.AstNode{*node.ExternalCall}, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - // Catch part - if node.Clauses != nil { - for _, clause := range node.Clauses { - if clause.Block != nil && clause.Block.Statements != nil { - found := upgradesContract(clause.Block.Statements, expectedExternalCallName, typeName, internalFunctionTypes) - if found != NOT_FOUND { - return found - } - } - } - } - - // If not nested, check if the statement is an external call to an upgrade function with a contract type of `typeName` - if node.NodeType == "ExpressionStatement" { - if identifyValidExternalUpgradeCall(node.Expression.Expression, expectedExternalCallName, typeName) { - return UPGRADE_EXTERNAL_CALL - } - } - - // To support try external calls and external calls within tenary statements. - if node.NodeType == "FunctionCall" { - if identifyValidExternalUpgradeCall(node.Expression, expectedExternalCallName, typeName) { - return UPGRADE_EXTERNAL_CALL - } - } - - // To support internal upgrade functions. - if node.NodeType == "ExpressionStatement" { - if identifyValidInternalUpgradeCall(node.Expression, internalFunctionTypes, typeName) { - return UPGRADE_INTERNAL_CALL - } - } - - // To support internal upgrade function calls within tenary statements. - if node.NodeType == "FunctionCall" { - // cast node into an expression-like type with relevant fields that we need - expression := solc.Expression{ - Expression: node.Expression, - Arguments: node.Arguments, - } - if identifyValidInternalUpgradeCall(&expression, internalFunctionTypes, typeName) { - return UPGRADE_INTERNAL_CALL - } - } - } - - // Else return false. - return NOT_FOUND -} - -func identifyValidExternalUpgradeCall(expression *solc.Expression, expectedExternalCallName string, typeName string) bool { - // To support external upgrade calls. - if expression != nil && expression.Expression != nil { - if expression.MemberName == expectedExternalCallName && expression.Expression.TypeDescriptions.TypeString == typeName { - return true - } - } - - return false -} - -func identifyValidInternalUpgradeCall(expression *solc.Expression, internalFunctionTypes InternalUpgradeFunctionType, typeName string) bool { - // To support internal upgrade functions. - if expression != nil && expression.Expression != nil { - if expression.Expression.Name == internalFunctionTypes.name && expression.Expression.TypeDescriptions.TypeString == internalFunctionTypes.typeName { - // Assert that the second argument is of type `typeName` that was cast (within the argument list) into an address - if expression.Arguments[1].Arguments[0].TypeDescriptions.TypeString == typeName { - // Assert that the fourth argument is of type `abi.encodeCall(IContract.upgrade, (...))` - expectedTypeString := "type(" + typeName + ")" - if expression.Arguments[3].Arguments[0].Expression.TypeDescriptions.TypeString == expectedTypeString && - expression.Arguments[3].Arguments[0].MemberName == "upgrade" && - expression.Arguments[3].Expression.Expression.Name == "abi" && - expression.Arguments[3].Expression.MemberName == "encodeCall" { - // If all of the above passes, return true - return true - } - } - } - } - - return false -} - -// Get the AST of OPCM's upgrade function. -// Returns an error if zero or more than one external upgrade function is found. -func getOpcmUpgradeFunctionAst(opcmArtifact *solc.ForgeArtifact, upgradeFunctionName string) (*solc.AstNode, error) { - opcmUpgradeFunctions := []solc.AstNode{} - for _, astNode := range opcmArtifact.Ast.Nodes { - if astNode.NodeType == "ContractDefinition" && astNode.Name == "OPContractsManagerUpgrader" { - for _, node := range astNode.Nodes { - if node.NodeType == "FunctionDefinition" && - node.Name == upgradeFunctionName { - opcmUpgradeFunctions = append(opcmUpgradeFunctions, node) - } - } - } - } - - if len(opcmUpgradeFunctions) == 0 { - return nil, fmt.Errorf("no external %s function found in OPContractsManagerUpgrader", upgradeFunctionName) - } - - if len(opcmUpgradeFunctions) > 1 { - return nil, fmt.Errorf("multiple external %s functions found in OPContractsManagerUpgrader, expected 1", upgradeFunctionName) - } - - return &opcmUpgradeFunctions[0], nil -} - -// Get the number of upgrade functions from the input artifact. -func getNumberOfUpgradeFunctions(artifact *solc.ForgeArtifact) int { - upgradeFunctions := []solc.AstNode{} - for _, astNode := range artifact.Ast.Nodes { - if astNode.NodeType == "ContractDefinition" { - for _, node := range astNode.Nodes { - if node.NodeType == "FunctionDefinition" && - node.Name == "upgrade" && - (node.Visibility == "external" || node.Visibility == "public") { - upgradeFunctions = append(upgradeFunctions, node) - } - } - } - } - - return len(upgradeFunctions) -} diff --git a/packages/contracts-bedrock/scripts/checks/opcm-upgrade-checks/main_test.go b/packages/contracts-bedrock/scripts/checks/opcm-upgrade-checks/main_test.go deleted file mode 100644 index b7b7ef16bea58..0000000000000 --- a/packages/contracts-bedrock/scripts/checks/opcm-upgrade-checks/main_test.go +++ /dev/null @@ -1,388 +0,0 @@ -package main - -import ( - "testing" - - "github.com/ethereum-optimism/optimism/op-chain-ops/solc" - "github.com/ethereum-optimism/optimism/packages/contracts-bedrock/scripts/checks/common" - "github.com/stretchr/testify/assert" -) - -func TestGetOpcmUpgradeFunctionAst(t *testing.T) { - tests := []struct { - name string - opcmArtifact *solc.ForgeArtifact - upgradeFunctionName string - expectedAst *solc.AstNode - expectedError string - }{ - { - name: "With one _doChainUpgrade function", - opcmArtifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{ - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "_doChainUpgrade", - Visibility: "external", - Nodes: []solc.AstNode{ - { - NodeType: "UniqueNonExistentNodeType", - }, - }, - }, - }, - Name: "OPContractsManagerUpgrader", - }, - }, - }, - }, - upgradeFunctionName: "_doChainUpgrade", - expectedAst: &solc.AstNode{ - NodeType: "FunctionDefinition", - Name: "_doChainUpgrade", - Visibility: "external", - Nodes: []solc.AstNode{ - { - NodeType: "UniqueNonExistentNodeType", - }, - }, - }, - expectedError: "", - }, - { - name: "With a _doChainUpgrade function but public visibility", - opcmArtifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{ - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "_doChainUpgrade", - Visibility: "public", - }, - }, - Name: "OPContractsManagerUpgrader", - }, - }, - }, - }, - upgradeFunctionName: "_doChainUpgrade", - expectedAst: &solc.AstNode{ - NodeType: "FunctionDefinition", - Name: "_doChainUpgrade", - Visibility: "public", - }, - expectedError: "", - }, - { - name: "With a _doChainUpgrade function and irrelevant function selector", - opcmArtifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{ - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "_doChainUpgrade", - Visibility: "external", - FunctionSelector: "aabbccdd", - Nodes: []solc.AstNode{ - { - NodeType: "UniqueNonExistentNodeType", - }, - }, - }, - }, - Name: "OPContractsManagerUpgrader", - }, - }, - }, - }, - upgradeFunctionName: "_doChainUpgrade", - expectedAst: &solc.AstNode{ - NodeType: "FunctionDefinition", - Name: "_doChainUpgrade", - Visibility: "external", - FunctionSelector: "aabbccdd", - Nodes: []solc.AstNode{ - { - NodeType: "UniqueNonExistentNodeType", - }, - }, - }, - expectedError: "", - }, - { - name: "With multiple _doChainUpgrade functions", - opcmArtifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{ - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "_doChainUpgrade", - Visibility: "external", - }, - { - NodeType: "FunctionDefinition", - Name: "_doChainUpgrade", - Visibility: "external", - }, - }, - Name: "OPContractsManagerUpgrader", - }, - }, - }, - }, - upgradeFunctionName: "_doChainUpgrade", - expectedAst: nil, - expectedError: "multiple external _doChainUpgrade functions found in OPContractsManagerUpgrader, expected 1", - }, - { - name: "With no _doChainUpgrade function", - opcmArtifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{ - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "randomFunctionName", - Visibility: "external", - Nodes: []solc.AstNode{ - { - NodeType: "UniqueNonExistentNodeType", - }, - }, - }, - }, - Name: "OPContractsManagerUpgrader", - }, - }, - }, - }, - upgradeFunctionName: "_doChainUpgrade", - expectedAst: nil, - expectedError: "no external _doChainUpgrade function found in OPContractsManagerUpgrader", - }, - { - name: "With no contract definition", - opcmArtifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{}, - }, - }, - upgradeFunctionName: "_doChainUpgrade", - expectedAst: nil, - expectedError: "no external _doChainUpgrade function found in OPContractsManagerUpgrader", - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - ast, err := getOpcmUpgradeFunctionAst(test.opcmArtifact, test.upgradeFunctionName) - - if test.expectedError == "" { - assert.NoError(t, err) - assert.Equal(t, test.expectedAst, ast) - } else { - assert.Error(t, err) - assert.Nil(t, ast) - if err != nil { - assert.Equal(t, test.expectedError, err.Error()) - } - } - }) - } -} - -func TestGetNumberOfUpgradeFunctions(t *testing.T) { - tests := []struct { - name string - artifact *solc.ForgeArtifact - expectedNum int - }{ - { - name: "With an external upgrade function", - artifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{ - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "upgrade", - Visibility: "external", - }, - }, - }, - }, - }, - }, - expectedNum: 1, - }, - { - name: "With a public upgrade function", - artifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{ - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "upgrade", - Visibility: "public", - }, - }, - }, - }, - }, - }, - expectedNum: 1, - }, - { - name: "With multiple upgrade functions", - artifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{ - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "upgrade", - Visibility: "external", - }, - }, - }, - { - NodeType: "ContractDefinition", - Nodes: []solc.AstNode{ - { - NodeType: "FunctionDefinition", - Name: "upgrade", - Visibility: "public", - }, - }, - }, - }, - }, - }, - expectedNum: 2, - }, - { - name: "With no upgrade functions", - artifact: &solc.ForgeArtifact{ - Ast: solc.Ast{ - Nodes: []solc.AstNode{}, - }, - }, - expectedNum: 0, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - num := getNumberOfUpgradeFunctions(test.artifact) - assert.Equal(t, test.expectedNum, num) - }) - } -} - -func TestUpgradesContract(t *testing.T) { - // To add tests for this, create a contract with one or a combination of solidity statements and an optional upgrade function call within it to a contract type of IUpgradeable. - // Then create a constant bool variable EXPECTED_OUTPUT and set it to true if the upgrade function call is expected to be found and false otherwise. - // See opcm_upgrade_checks_mocks.sol for already existing mock contracts used for testing. - - artifact, err := common.ReadForgeArtifact("../../../forge-artifacts/OPCMUpgradeChecksMocks.sol/IUpgradeable.json") - if err != nil { - t.Fatalf("Failed to load artifact: %v", err) - } - - type test struct { - name string - upgradeAst []solc.AstNode - typeName string - internalUpgradeFunctionTypeStrings InternalUpgradeFunctionType - expectedOutput CallType - } - - tests := []test{} - - for _, node := range artifact.Ast.Nodes { - if node.NodeType == "ContractDefinition" && node.Name != "IUpgradeable" && node.Name != "InternalUpgradeFunction" { - upgradeAst := solc.AstNode{} - expectedOutput := NOT_FOUND - for _, astNode := range node.Nodes { - if astNode.NodeType == "FunctionDefinition" && astNode.Name == "upgrade" { - if upgradeAst.NodeType != "" { - t.Fatalf("Expected only one upgrade function") - } - upgradeAst = astNode - } - - if astNode.NodeType == "VariableDeclaration" && - astNode.Name == "EXPECTED_OUTPUT" && - astNode.Mutability == "constant" { - - value, ok := astNode.Value.(map[string]interface{}) - if !ok { - t.Fatalf("Expected value to be a map: %v", astNode.Value) - } - - typeDescriptions, ok := value["typeDescriptions"].(map[string]interface{}) - if !ok { - t.Fatalf("Expected typeDescriptions to be a map: %v", value) - } - if typeDescriptions["typeString"] != "uint8" { - t.Fatalf("Expected the typeString to be uint8: %v", value) - } - - name, ok := value["name"].(string) - if !ok { - t.Fatalf("Expected name to be a string: %v", value) - } - if name == "NOT_FOUND" { - expectedOutput = NOT_FOUND - } else if name == "UPGRADE_EXTERNAL_CALL" { - expectedOutput = UPGRADE_EXTERNAL_CALL - } else if name == "UPGRADE_INTERNAL_CALL" { - expectedOutput = UPGRADE_INTERNAL_CALL - } else { - t.Fatalf("Expected output is not a boolean: %s", astNode.Value) - } - } - } - - tests = append(tests, test{ - name: node.Name, - upgradeAst: []solc.AstNode{upgradeAst}, - typeName: "contract IUpgradeable", - internalUpgradeFunctionTypeStrings: InternalUpgradeFunctionType{ - name: "upgradeToAndCall", - typeName: "function (contract IUpgradeable,address,address,bytes memory)", - }, - expectedOutput: expectedOutput, - }) - } - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - output := upgradesContract(test.upgradeAst, "upgrade", test.typeName, test.internalUpgradeFunctionTypeStrings) - assert.Equal(t, test.expectedOutput, output) - }) - } -} diff --git a/packages/contracts-bedrock/scripts/checks/test-validation/exclusions.toml b/packages/contracts-bedrock/scripts/checks/test-validation/exclusions.toml index 0208a3ed8bcf8..fb3d5e09a7a52 100644 --- a/packages/contracts-bedrock/scripts/checks/test-validation/exclusions.toml +++ b/packages/contracts-bedrock/scripts/checks/test-validation/exclusions.toml @@ -59,7 +59,6 @@ contract_name_validation = [ "test/L2/CrossDomainOwnable3.t.sol", # Contains contracts not matching CrossDomainOwnable3 base name "test/L2/GasPriceOracle.t.sol", # Contains contracts not matching GasPriceOracle base name "test/universal/StandardBridge.t.sol", # Contains contracts not matching StandardBridge base name - "test/L1/OPContractsManagerContractsContainer.t.sol", # Contains contracts not matching OPContractsManagerContractsContainer base name "test/L2/RevenueSharingIntegration.t.sol", # Contains contracts not matching RevenueSharingIntegration base name "test/libraries/Blueprint.t.sol", # Contains helper contracts (BlueprintHarness, ConstructorArgMock) "test/libraries/SafeCall.t.sol", # Contains helper contracts (SimpleSafeCaller) diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol deleted file mode 100644 index 42bcf189fbf59..0000000000000 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; - -// Forge -import { Script } from "forge-std/Script.sol"; - -// Scripts -import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; -import { DummyCaller } from "scripts/libraries/DummyCaller.sol"; - -// Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; -import { ISystemConfig } from "interfaces/L1/ISystemConfig.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"; -import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; - -/// @title AddGameType -/// @notice This script is used to add a new game type to the chain using the OPContractsManager V1. -/// Support for OPCM v2 is provided through the UpgradeOPChain script. -contract AddGameType is Script { - struct Input { - // Address that will be used for the DummyCaller contract - address prank; - // OPCM contract address - IOPContractsManager opcmImpl; - // SystemConfig contract address - ISystemConfig systemConfigProxy; - // DelayedWETH contract address (optional) - IDelayedWETH delayedWETHProxy; - // Game type to add - GameType disputeGameType; - // Absolute prestate for the game - Claim disputeAbsolutePrestate; - // Maximum game depth - uint256 disputeMaxGameDepth; - // Split depth for the game - uint256 disputeSplitDepth; - // Clock extension duration - Duration disputeClockExtension; - // Maximum clock duration - Duration disputeMaxClockDuration; - // Initial bond amount - uint256 initialBond; - // VM contract address - IBigStepper vm; - // Whether this is a permissioned game - bool permissioned; - // Salt mixer for deterministic addresses - string saltMixer; - } - - struct Output { - IDelayedWETH delayedWETHProxy; - IFaultDisputeGame faultDisputeGameProxy; - } - - function run(Input memory _agi) public returns (Output memory) { - // 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 = _agi.prank; - - bytes memory code = type(DummyCaller).runtimeCode; - 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. - // The DummyCaller uses a fallback that reverts on failure, so no need to check success. - vm.broadcast(msg.sender); - IOPContractsManager.AddGameOutput[] memory outputs = IOPContractsManager(prank).addGameType(gameConfigs); - - // Decode the result and set it in the output - 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 { - DeployUtils.assertValidContractAddress(address(_ago.delayedWETHProxy)); - DeployUtils.assertValidContractAddress(address(_ago.faultDisputeGameProxy)); - } -} diff --git a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol index 1bc01bd8c6535..d06bcdeeac658 100644 --- a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol +++ b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol @@ -16,10 +16,9 @@ import { Types } from "scripts/libraries/Types.sol"; import { Blueprint } from "src/libraries/Blueprint.sol"; import { GameType, GameTypes } from "src/dispute/lib/Types.sol"; import { Hash } from "src/dispute/lib/Types.sol"; -import { DevFeatures } from "src/libraries/DevFeatures.sol"; - // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; +import { IOPContractsManagerContainer } from "interfaces/L1/opcm/IOPContractsManagerContainer.sol"; import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; @@ -112,19 +111,12 @@ library ChainAssertions { require(config.scalar() >> 248 == 1, "CHECK-SCFG-70"); // Depends on start block being set to 0 in `initialize` require(config.startBlock() == block.number, "CHECK-SCFG-140"); - if (IOPContractsManager(_doi.opcm).isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - require( - config.batchInbox() - == IOPContractsManagerUtils(IOPContractsManagerV2(address(_doi.opcm)).opcmUtils()) - .chainIdToBatchInboxAddress(_doi.l2ChainId), - "CHECK-SCFG-150" - ); - } else { - require( - config.batchInbox() == IOPContractsManager(_doi.opcm).chainIdToBatchInboxAddress(_doi.l2ChainId), - "CHECK-SCFG-150" - ); - } + require( + config.batchInbox() + == IOPContractsManagerUtils(IOPContractsManagerV2(address(_doi.opcm)).opcmUtils()) + .chainIdToBatchInboxAddress(_doi.l2ChainId), + "CHECK-SCFG-150" + ); // Check _addresses require(config.l1CrossDomainMessenger() == _contracts.L1CrossDomainMessenger, "CHECK-SCFG-160"); require(config.l1ERC721Bridge() == _contracts.L1ERC721Bridge, "CHECK-SCFG-170"); @@ -385,8 +377,7 @@ library ChainAssertions { /// @notice Asserts that the OPContractsManager is setup correctly function checkOPContractsManager( Types.ContractSet memory _impls, - Types.ContractSet memory _proxies, - IOPContractsManager _opcm, + IOPContractsManagerV2 _opcm, IMIPS64 _mips ) internal @@ -396,12 +387,8 @@ library ChainAssertions { require(address(_opcm) != address(0), "CHECK-OPCM-10"); require(bytes(_opcm.version()).length > 0, "CHECK-OPCM-15"); - if (!_opcm.isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - require(address(_opcm.protocolVersions()) == _proxies.ProtocolVersions, "CHECK-OPCM-17"); - require(address(_opcm.superchainConfig()) == _proxies.SuperchainConfig, "CHECK-OPCM-19"); - } // Ensure that the OPCM impls are correctly saved - IOPContractsManager.Implementations memory impls = _opcm.implementations(); + IOPContractsManagerContainer.Implementations memory impls = _opcm.implementations(); require(impls.l1ERC721BridgeImpl == _impls.L1ERC721Bridge, "CHECK-OPCM-50"); require(impls.optimismPortalImpl == _impls.OptimismPortal, "CHECK-OPCM-60"); require(impls.systemConfigImpl == _impls.SystemConfig, "CHECK-OPCM-70"); @@ -415,7 +402,7 @@ library ChainAssertions { require(impls.protocolVersionsImpl == _impls.ProtocolVersions, "CHECK-OPCM-150"); // Verify that initCode is correctly set into the blueprints - IOPContractsManager.Blueprints memory blueprints = _opcm.blueprints(); + IOPContractsManagerContainer.Blueprints memory blueprints = _opcm.blueprints(); Blueprint.Preamble memory addressManagerPreamble = Blueprint.parseBlueprintPreamble(address(blueprints.addressManager).code); require( diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index a40e583817cac..fa53fd43050cc 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -21,13 +21,11 @@ import { StandardConstants } from "scripts/deploy/StandardConstants.sol"; // Libraries import { Types } from "scripts/libraries/Types.sol"; -import { Duration } from "src/dispute/lib/LibUDT.sol"; import { GameType, Claim, GameTypes, Proposal, Hash } from "src/dispute/lib/Types.sol"; import { Constants } from "src/libraries/Constants.sol"; import { DevFeatures } from "src/libraries/DevFeatures.sol"; // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; import { IProxy } from "interfaces/universal/IProxy.sol"; @@ -178,11 +176,7 @@ contract Deploy is Deployer { deployImplementations(); // Deploy Current OPChain Contracts - if (!DevFeatures.isDevFeatureEnabled(cfg.devFeatureBitmap(), DevFeatures.OPCM_V2)) { - deployOpChain(); - } else { - deployOpChainV2(); - } + deployOpChainV2(); // Set the respected game type according to the deploy config vm.startPrank(ISuperchainConfig(artifacts.mustGetAddress("SuperchainConfigProxy")).guardian()); @@ -298,11 +292,7 @@ contract Deploy is Deployer { // Save the implementation addresses which are needed outside of this function or script. // When called in a fork test, this will overwrite the existing implementations. artifacts.save("MipsSingleton", address(dio.mipsSingleton)); - if (DevFeatures.isDevFeatureEnabled(cfg.devFeatureBitmap(), DevFeatures.OPCM_V2)) { - artifacts.save("OPContractsManagerV2", address(dio.opcmV2)); - } else { - artifacts.save("OPContractsManager", address(dio.opcm)); - } + artifacts.save("OPContractsManagerV2", address(dio.opcmV2)); artifacts.save("DelayedWETHImpl", address(dio.delayedWETHImpl)); artifacts.save("PreimageOracle", address(dio.preimageOracleSingleton)); artifacts.save("PermissionedDisputeGame", address(dio.permissionedDisputeGameImpl)); @@ -336,16 +326,9 @@ contract Deploy is Deployer { _mips: IMIPS64(address(dio.mipsSingleton)), _oracle: IPreimageOracle(address(dio.preimageOracleSingleton)) }); - IOPContractsManager _opcm; - if (DevFeatures.isDevFeatureEnabled(cfg.devFeatureBitmap(), DevFeatures.OPCM_V2)) { - _opcm = IOPContractsManager(address(dio.opcmV2)); - } else { - _opcm = IOPContractsManager(address(dio.opcm)); - } ChainAssertions.checkOPContractsManager({ _impls: impls, - _proxies: _proxies(), - _opcm: _opcm, + _opcm: IOPContractsManagerV2(address(dio.opcmV2)), _mips: IMIPS64(address(dio.mipsSingleton)) }); ChainAssertions.checkSystemConfigImpls(impls); @@ -353,57 +336,6 @@ contract Deploy is Deployer { } /// @notice Deploy all of the OP Chain specific contracts - function deployOpChain() public { - console.log("Deploying OP Chain"); - - // Ensure that the requisite contracts are deployed - IOPContractsManager opcm = IOPContractsManager(artifacts.mustGetAddress("OPContractsManager")); - - IOPContractsManager.DeployInput memory deployInput = getDeployInput(); - IOPContractsManager.DeployOutput memory deployOutput = opcm.deploy(deployInput); - - // Store code in the Final system owner address so that it can be used for prank delegatecalls - // Store "fe" opcode so that accidental calls to this address revert - vm.etch(cfg.finalSystemOwner(), hex"fe"); - - // Save all deploy outputs from the OPCM, in the order they are declared in the DeployOutput struct - artifacts.save("ProxyAdmin", address(deployOutput.opChainProxyAdmin)); - artifacts.save("AddressManager", address(deployOutput.addressManager)); - artifacts.save("L1ERC721BridgeProxy", address(deployOutput.l1ERC721BridgeProxy)); - artifacts.save("SystemConfigProxy", address(deployOutput.systemConfigProxy)); - artifacts.save("OptimismMintableERC20FactoryProxy", address(deployOutput.optimismMintableERC20FactoryProxy)); - artifacts.save("L1StandardBridgeProxy", address(deployOutput.l1StandardBridgeProxy)); - artifacts.save("L1CrossDomainMessengerProxy", address(deployOutput.l1CrossDomainMessengerProxy)); - artifacts.save("ETHLockboxProxy", address(deployOutput.ethLockboxProxy)); - - // Fault Proof contracts - artifacts.save("DisputeGameFactoryProxy", address(deployOutput.disputeGameFactoryProxy)); - artifacts.save("PermissionedDelayedWETHProxy", address(deployOutput.delayedWETHPermissionedGameProxy)); - artifacts.save("AnchorStateRegistryProxy", address(deployOutput.anchorStateRegistryProxy)); - artifacts.save("OptimismPortalProxy", address(deployOutput.optimismPortalProxy)); - artifacts.save("OptimismPortal2Proxy", address(deployOutput.optimismPortalProxy)); - - // Check if the permissionless game implementation is already set - IDisputeGameFactory factory = IDisputeGameFactory(artifacts.mustGetAddress("DisputeGameFactoryProxy")); - address permissionlessGameImpl = address(factory.gameImpls(GameTypes.CANNON)); - - // Deploy and setup the PermissionlessDelayedWeth not provided by the OPCM. - // If the following require statement is hit, you can delete the block of code after it. - require( - permissionlessGameImpl == address(0), - "Deploy: The PermissionlessDelayedWETH is already set by the OPCM, it is no longer necessary to deploy it separately." - ); - address delayedWETHImpl = artifacts.mustGetAddress("DelayedWETHImpl"); - address delayedWETHPermissionlessGameProxy = - deployERC1967ProxyWithOwner("DelayedWETHProxy", address(deployOutput.opChainProxyAdmin)); - vm.broadcast(address(deployOutput.opChainProxyAdmin)); - IProxy(payable(delayedWETHPermissionlessGameProxy)).upgradeToAndCall({ - _implementation: delayedWETHImpl, - _data: abi.encodeCall(IDelayedWETH.initialize, (deployOutput.systemConfigProxy)) - }); - } - - /// @notice Deploy all of the OP Chain specific contracts using OPCM v2 function deployOpChainV2() public { console.log("Deploying OP Chain"); @@ -467,36 +399,6 @@ contract Deploy is Deployer { addr_ = address(proxy); } - /// @notice Get the DeployInput struct to use for testing - function getDeployInput() public view returns (IOPContractsManager.DeployInput memory) { - string memory saltMixer = "salt mixer"; - return IOPContractsManager.DeployInput({ - roles: IOPContractsManager.Roles({ - opChainProxyAdminOwner: cfg.finalSystemOwner(), - systemConfigOwner: cfg.finalSystemOwner(), - batcher: cfg.batchSenderAddress(), - unsafeBlockSigner: cfg.p2pSequencerAddress(), - proposer: cfg.l2OutputOracleProposer(), - challenger: cfg.l2OutputOracleChallenger() - }), - basefeeScalar: cfg.basefeeScalar(), - blobBasefeeScalar: cfg.blobbasefeeScalar(), - l2ChainId: cfg.l2ChainID(), - startingAnchorRoot: abi.encode( - Proposal({ root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), l2SequenceNumber: cfg.faultGameGenesisBlock() }) - ), - saltMixer: saltMixer, - gasLimit: uint64(cfg.l2GenesisBlockGasLimit()), - disputeGameType: GameTypes.PERMISSIONED_CANNON, - disputeAbsolutePrestate: Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate())), - disputeMaxGameDepth: cfg.faultGameMaxDepth(), - disputeSplitDepth: cfg.faultGameSplitDepth(), - disputeClockExtension: Duration.wrap(uint64(cfg.faultGameClockExtension())), - disputeMaxClockDuration: Duration.wrap(uint64(cfg.faultGameMaxClockDuration())), - useCustomGasToken: cfg.useCustomGasToken() - }); - } - function getSuperRootDeployInputV2() public view returns (IOPContractsManagerV2.FullConfig memory) { IOPContractsManagerUtils.DisputeGameConfig[] memory disputeGameConfigs = new IOPContractsManagerUtils.DisputeGameConfig[](6); diff --git a/packages/contracts-bedrock/scripts/deploy/DeployImplementations.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployImplementations.s.sol index d2d2273011a37..b2c4a44fedb05 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployImplementations.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployImplementations.s.sol @@ -20,15 +20,6 @@ import { ISuperFaultDisputeGame } from "interfaces/dispute/ISuperFaultDisputeGam import { ISuperPermissionedDisputeGame } from "interfaces/dispute/ISuperPermissionedDisputeGame.sol"; import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol"; import { Duration, GameType, GameTypes } from "src/dispute/lib/Types.sol"; -import { - IOPContractsManager, - IOPContractsManagerGameTypeAdder, - IOPContractsManagerDeployer, - IOPContractsManagerUpgrader, - IOPContractsManagerContractsContainer, - IOPContractsManagerInteropMigrator, - IOPContractsManagerStandardValidator -} from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOPContractsManagerContainer } from "interfaces/L1/opcm/IOPContractsManagerContainer.sol"; import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; @@ -44,10 +35,10 @@ import { IOptimismMintableERC20Factory } from "interfaces/universal/IOptimismMin import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IStorageSetter } from "interfaces/universal/IStorageSetter.sol"; import { IOPContractsManagerStandardValidator } from "interfaces/L1/IOPContractsManagerStandardValidator.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; import { ChainAssertions } from "scripts/deploy/ChainAssertions.sol"; -import { DevFeatures } from "src/libraries/DevFeatures.sol"; contract DeployImplementations is Script { struct Input { @@ -72,17 +63,19 @@ contract DeployImplementations is Script { } struct Output { - IOPContractsManager opcm; - IOPContractsManagerContractsContainer opcmContractsContainer; - IOPContractsManagerGameTypeAdder opcmGameTypeAdder; - IOPContractsManagerDeployer opcmDeployer; - IOPContractsManagerUpgrader opcmUpgrader; - IOPContractsManagerInteropMigrator opcmInteropMigrator; + // Deprecated v1 OPCM fields — kept for Go ABI compatibility, always zero. + // Remove these when Go op-deployer drops v1 struct fields. + address opcm; + address opcmContractsContainer; + address opcmGameTypeAdder; + address opcmDeployer; + address opcmUpgrader; + address opcmInteropMigrator; IOPContractsManagerStandardValidator opcmStandardValidator; IOPContractsManagerUtils opcmUtils; IOPContractsManagerMigrator opcmMigrator; IOPContractsManagerV2 opcmV2; - IOPContractsManagerContainer opcmContainer; // v2 container + IOPContractsManagerContainer opcmContainer; IDelayedWETH delayedWETHImpl; IOptimismPortal optimismPortalImpl; IOptimismPortalInterop optimismPortalInteropImpl; @@ -155,67 +148,6 @@ contract DeployImplementations is Script { // --- OP Contracts Manager --- - /// @notice Deploys the OPCM v1 contract. - /// Sets the OPCM v2 addresses to zero to indicate that OPCM v2 was not deployed. - /// @param _input The deployment input parameters. - /// @param _output The deployment output parameters. - /// @param _blueprints The blueprints for the OPCM v1 contract. - /// @return opcm_ The deployed OPCM v1 contract. - function createOPCMContract( - Input memory _input, - Output memory _output, - IOPContractsManager.Blueprints memory _blueprints - ) - private - returns (IOPContractsManager opcm_) - { - IOPContractsManager.Implementations memory implementations = IOPContractsManager.Implementations({ - superchainConfigImpl: address(_output.superchainConfigImpl), - protocolVersionsImpl: address(_output.protocolVersionsImpl), - l1ERC721BridgeImpl: address(_output.l1ERC721BridgeImpl), - optimismPortalImpl: address(_output.optimismPortalImpl), - optimismPortalInteropImpl: address(_output.optimismPortalInteropImpl), - ethLockboxImpl: address(_output.ethLockboxImpl), - systemConfigImpl: address(_output.systemConfigImpl), - optimismMintableERC20FactoryImpl: address(_output.optimismMintableERC20FactoryImpl), - l1CrossDomainMessengerImpl: address(_output.l1CrossDomainMessengerImpl), - l1StandardBridgeImpl: address(_output.l1StandardBridgeImpl), - disputeGameFactoryImpl: address(_output.disputeGameFactoryImpl), - anchorStateRegistryImpl: address(_output.anchorStateRegistryImpl), - delayedWETHImpl: address(_output.delayedWETHImpl), - mipsImpl: address(_output.mipsSingleton), - faultDisputeGameImpl: address(_output.faultDisputeGameImpl), - permissionedDisputeGameImpl: address(_output.permissionedDisputeGameImpl), - superFaultDisputeGameImpl: address(_output.superFaultDisputeGameImpl), - superPermissionedDisputeGameImpl: address(_output.superPermissionedDisputeGameImpl) - }); - - // Deploy OPCM V1 components - deployOPCMBPImplsContainer(_input, _output, _blueprints, implementations); - deployOPCMGameTypeAdder(_output); - deployOPCMDeployer(_input, _output); - deployOPCMUpgrader(_output); - deployOPCMInteropMigrator(_output); - deployOPCMStandardValidator(_input, _output, implementations); - - // Semgrep rule will fail because the arguments are encoded inside of a separate function. - opcm_ = IOPContractsManager( - // nosemgrep: sol-safety-deployutils-args - DeployUtils.createDeterministic({ - _name: "OPContractsManager", - _args: encodeOPCMConstructor(_input, _output), - _salt: _salt - }) - ); - - vm.label(address(opcm_), "OPContractsManager"); - _output.opcm = opcm_; - - // Set OPCM V2 addresses to zero (not deployed) - _output.opcmV2 = IOPContractsManagerV2(address(0)); - _output.opcmContainer = IOPContractsManagerContainer(address(0)); - } - /// @notice Deploys the OPCM v2 contract and all the necessary components it uses, including the OPCM v2 container. /// Sets the OPCM v1 addresses to zero to indicate that OPCM v1 was not deployed. /// @param _input The deployment input parameters. @@ -225,7 +157,7 @@ contract DeployImplementations is Script { function createOPCMContractV2( Input memory _input, Output memory _output, - IOPContractsManager.Blueprints memory _blueprints + IOPContractsManagerContainer.Blueprints memory _blueprints ) private returns (IOPContractsManagerV2 opcmV2_) @@ -253,69 +185,23 @@ contract DeployImplementations is Script { storageSetterImpl: address(_output.storageSetterImpl) }); - // Convert blueprints to V2 blueprints - IOPContractsManagerContainer.Blueprints memory blueprints = IOPContractsManagerContainer.Blueprints({ - addressManager: _blueprints.addressManager, - proxy: _blueprints.proxy, - proxyAdmin: _blueprints.proxyAdmin, - l1ChugSplashProxy: _blueprints.l1ChugSplashProxy, - resolvedDelegateProxy: _blueprints.resolvedDelegateProxy - }); - // Deploy OPCM V2 components - deployOPCMContainer(_input, _output, blueprints, implementations); + deployOPCMContainer(_input, _output, _blueprints, implementations); deployOPCMStandardValidatorV2(_input, _output, implementations); deployOPCMUtils(_output); deployOPCMMigrator(_output); opcmV2_ = deployOPCMV2(_output); - // Set OPCM V1 addresses to zero (not deployed) - _output.opcm = IOPContractsManager(address(0)); - _output.opcmContractsContainer = IOPContractsManagerContractsContainer(address(0)); - _output.opcmGameTypeAdder = IOPContractsManagerGameTypeAdder(address(0)); - _output.opcmDeployer = IOPContractsManagerDeployer(address(0)); - _output.opcmUpgrader = IOPContractsManagerUpgrader(address(0)); - _output.opcmInteropMigrator = IOPContractsManagerInteropMigrator(address(0)); - return opcmV2_; } - /// @notice Encodes the constructor of the OPContractsManager contract. Used to avoid stack too - /// deep errors inside of the createOPCMContract function. - /// @param _input The deployment input parameters. - /// @param _output The deployment output parameters. - /// @return encoded_ The encoded constructor. - function encodeOPCMConstructor( - Input memory _input, - Output memory _output - ) - private - pure - returns (bytes memory encoded_) - { - encoded_ = DeployUtils.encodeConstructor( - abi.encodeCall( - IOPContractsManager.__constructor__, - ( - _output.opcmGameTypeAdder, - _output.opcmDeployer, - _output.opcmUpgrader, - _output.opcmInteropMigrator, - _output.opcmStandardValidator, - _input.superchainConfigProxy, - _input.protocolVersionsProxy - ) - ) - ); - } - - /// @notice Deploys the OPCM contract depending on the dev feature bitmap. + /// @notice Deploys the OPCM contract. /// @param _input The deployment input parameters. /// @param _output The deployment output parameters. function deployOPContractsManager(Input memory _input, Output memory _output) private { // First we deploy the blueprints for the singletons deployed by OPCM. // forgefmt: disable-start - IOPContractsManager.Blueprints memory blueprints; + IOPContractsManagerContainer.Blueprints memory blueprints; vm.startBroadcast(msg.sender); address checkAddress; (blueprints.addressManager, checkAddress) = DeployUtils.createDeterministicBlueprint(DeployUtils.getCode("AddressManager"), _salt); @@ -331,18 +217,9 @@ contract DeployImplementations is Script { // forgefmt: disable-end vm.stopBroadcast(); - // Check if OPCM V2 should be deployed - bool deployV2 = DevFeatures.isDevFeatureEnabled(_input.devFeatureBitmap, DevFeatures.OPCM_V2); - - if (deployV2) { - IOPContractsManagerV2 opcmV2 = createOPCMContractV2(_input, _output, blueprints); - vm.label(address(opcmV2), "OPContractsManagerV2"); - _output.opcmV2 = opcmV2; - } else { - IOPContractsManager opcm = createOPCMContract(_input, _output, blueprints); - vm.label(address(opcm), "OPContractsManager"); - _output.opcm = opcm; - } + IOPContractsManagerV2 opcmV2 = createOPCMContractV2(_input, _output, blueprints); + vm.label(address(opcmV2), "OPContractsManagerV2"); + _output.opcmV2 = opcmV2; } // --- Core Contracts --- @@ -661,30 +538,6 @@ contract DeployImplementations is Script { _output.superPermissionedDisputeGameImpl = impl; } - function deployOPCMBPImplsContainer( - Input memory _input, - Output memory _output, - IOPContractsManager.Blueprints memory _blueprints, - IOPContractsManager.Implementations memory _implementations - ) - private - { - IOPContractsManagerContractsContainer impl = IOPContractsManagerContractsContainer( - DeployUtils.createDeterministic({ - _name: "OPContractsManager.sol:OPContractsManagerContractsContainer", - _args: DeployUtils.encodeConstructor( - abi.encodeCall( - IOPContractsManagerContractsContainer.__constructor__, - (_blueprints, _implementations, _input.devFeatureBitmap) - ) - ), - _salt: _salt - }) - ); - vm.label(address(impl), "OPContractsManagerBPImplsContainerImpl"); - _output.opcmContractsContainer = impl; - } - function deployOPCMContainer( Input memory _input, Output memory _output, @@ -709,110 +562,6 @@ contract DeployImplementations is Script { _output.opcmContainer = impl; } - function deployOPCMGameTypeAdder(Output memory _output) private { - IOPContractsManagerGameTypeAdder impl = IOPContractsManagerGameTypeAdder( - DeployUtils.createDeterministic({ - _name: "OPContractsManager.sol:OPContractsManagerGameTypeAdder", - _args: DeployUtils.encodeConstructor( - abi.encodeCall(IOPContractsManagerGameTypeAdder.__constructor__, (_output.opcmContractsContainer)) - ), - _salt: _salt - }) - ); - vm.label(address(impl), "OPContractsManagerGameTypeAdderImpl"); - _output.opcmGameTypeAdder = impl; - } - - function deployOPCMDeployer(Input memory, Output memory _output) private { - IOPContractsManagerDeployer impl = IOPContractsManagerDeployer( - DeployUtils.createDeterministic({ - _name: "OPContractsManager.sol:OPContractsManagerDeployer", - _args: DeployUtils.encodeConstructor( - abi.encodeCall(IOPContractsManagerDeployer.__constructor__, (_output.opcmContractsContainer)) - ), - _salt: _salt - }) - ); - vm.label(address(impl), "OPContractsManagerDeployerImpl"); - _output.opcmDeployer = impl; - } - - function deployOPCMUpgrader(Output memory _output) private { - IOPContractsManagerUpgrader impl = IOPContractsManagerUpgrader( - DeployUtils.createDeterministic({ - _name: "OPContractsManager.sol:OPContractsManagerUpgrader", - _args: DeployUtils.encodeConstructor( - abi.encodeCall(IOPContractsManagerUpgrader.__constructor__, (_output.opcmContractsContainer)) - ), - _salt: _salt - }) - ); - vm.label(address(impl), "OPContractsManagerUpgraderImpl"); - _output.opcmUpgrader = impl; - } - - function deployOPCMInteropMigrator(Output memory _output) private { - IOPContractsManagerInteropMigrator impl = IOPContractsManagerInteropMigrator( - DeployUtils.createDeterministic({ - _name: "OPContractsManager.sol:OPContractsManagerInteropMigrator", - _args: DeployUtils.encodeConstructor( - abi.encodeCall(IOPContractsManagerInteropMigrator.__constructor__, (_output.opcmContractsContainer)) - ), - _salt: _salt - }) - ); - vm.label(address(impl), "OPContractsManagerInteropMigratorImpl"); - _output.opcmInteropMigrator = impl; - } - - function deployOPCMStandardValidator( - Input memory _input, - Output memory _output, - IOPContractsManager.Implementations memory _implementations - ) - private - { - IOPContractsManagerStandardValidator.Implementations memory opcmImplementations; - opcmImplementations.l1ERC721BridgeImpl = _implementations.l1ERC721BridgeImpl; - opcmImplementations.optimismPortalImpl = _implementations.optimismPortalImpl; - opcmImplementations.optimismPortalInteropImpl = _implementations.optimismPortalInteropImpl; - opcmImplementations.ethLockboxImpl = _implementations.ethLockboxImpl; - opcmImplementations.systemConfigImpl = _implementations.systemConfigImpl; - opcmImplementations.optimismMintableERC20FactoryImpl = _implementations.optimismMintableERC20FactoryImpl; - opcmImplementations.l1CrossDomainMessengerImpl = _implementations.l1CrossDomainMessengerImpl; - opcmImplementations.l1StandardBridgeImpl = _implementations.l1StandardBridgeImpl; - opcmImplementations.disputeGameFactoryImpl = _implementations.disputeGameFactoryImpl; - opcmImplementations.anchorStateRegistryImpl = _implementations.anchorStateRegistryImpl; - opcmImplementations.delayedWETHImpl = _implementations.delayedWETHImpl; - opcmImplementations.mipsImpl = _implementations.mipsImpl; - opcmImplementations.faultDisputeGameImpl = _implementations.faultDisputeGameImpl; - opcmImplementations.permissionedDisputeGameImpl = _implementations.permissionedDisputeGameImpl; - opcmImplementations.superFaultDisputeGameImpl = _implementations.superFaultDisputeGameImpl; - opcmImplementations.superPermissionedDisputeGameImpl = _implementations.superPermissionedDisputeGameImpl; - - IOPContractsManagerStandardValidator impl = IOPContractsManagerStandardValidator( - DeployUtils.createDeterministic({ - _name: "OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator", - _args: DeployUtils.encodeConstructor( - abi.encodeCall( - IOPContractsManagerStandardValidator.__constructor__, - ( - opcmImplementations, - _input.superchainConfigProxy, - _input.l1ProxyAdminOwner, - _input.challenger, - _input.withdrawalDelaySeconds, - _input.devFeatureBitmap - ) - ) - ), - _salt: _salt - }) - ); - vm.label(address(impl), "OPContractsManagerStandardValidatorImpl"); - _output.opcmStandardValidator = impl; - } - function deployOPCMUtils(Output memory _output) private { IOPContractsManagerUtils impl = IOPContractsManagerUtils( DeployUtils.createDeterministic({ @@ -972,11 +721,8 @@ contract DeployImplementations is Script { // With 12 addresses, we'd get a stack too deep error if we tried to do this inline as a // single call to `Solarray.addresses`. So we split it into two calls. - // Check which OPCM version was deployed - bool deployedV2 = DevFeatures.isDevFeatureEnabled(_input.devFeatureBitmap, DevFeatures.OPCM_V2); - address[] memory addrs1 = Solarray.addresses( - deployedV2 ? address(_output.opcmV2) : address(_output.opcm), + address(_output.opcmV2), address(_output.optimismPortalImpl), address(_output.delayedWETHImpl), address(_output.preimageOracleSingleton), @@ -1010,26 +756,7 @@ contract DeployImplementations is Script { DeployUtils.assertValidContractAddresses(Solarray.extend(addrs1, addrs2)); - // Validate OPCM V2 flag - if (DevFeatures.isDevFeatureEnabled(_input.devFeatureBitmap, DevFeatures.OPCM_V2)) { - require( - address(_output.opcmV2) != address(0), - "DeployImplementations: OPCM V2 flag enabled but OPCM V2 not deployed" - ); - require( - address(_output.opcm) == address(0), - "DeployImplementations: OPCM V2 flag enabled but OPCM V1 was deployed" - ); - } else { - require( - address(_output.opcm) != address(0), - "DeployImplementations: OPCM V2 flag disabled but OPCM V1 not deployed" - ); - require( - address(_output.opcmV2) == address(0), - "DeployImplementations: OPCM V2 flag disabled but OPCM V2 was deployed" - ); - } + require(address(_output.opcmV2) != address(0), "DeployImplementations: OPCM V2 not deployed"); if ( !DevFeatures.isDevFeatureEnabled(_input.devFeatureBitmap, DevFeatures.OPTIMISM_PORTAL_INTEROP) @@ -1065,19 +792,6 @@ contract DeployImplementations is Script { ChainAssertions.checkL1StandardBridgeImpl(_output.l1StandardBridgeImpl); ChainAssertions.checkMIPS(_output.mipsSingleton, _output.preimageOracleSingleton); - // Only check OPCM V1 if it was deployed - if (!DevFeatures.isDevFeatureEnabled(_input.devFeatureBitmap, DevFeatures.OPCM_V2)) { - Types.ContractSet memory proxies; - proxies.SuperchainConfig = address(_input.superchainConfigProxy); - proxies.ProtocolVersions = address(_input.protocolVersionsProxy); - ChainAssertions.checkOPContractsManager({ - _impls: impls, - _proxies: proxies, - _opcm: IOPContractsManager(address(_output.opcm)), - _mips: IMIPS64(address(_output.mipsSingleton)) - }); - } - ChainAssertions.checkOptimismMintableERC20FactoryImpl(_output.optimismMintableERC20FactoryImpl); ChainAssertions.checkOptimismPortal2({ _contracts: impls, diff --git a/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol index ebe7db022a3b2..2002a4408999b 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol @@ -9,10 +9,8 @@ import { Solarray } from "scripts/libraries/Solarray.sol"; import { ChainAssertions } from "scripts/deploy/ChainAssertions.sol"; import { Constants as ScriptConstants } from "scripts/libraries/Constants.sol"; import { Types } from "scripts/libraries/Types.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; import { IAddressManager } from "interfaces/legacy/IAddressManager.sol"; @@ -35,9 +33,6 @@ contract DeployOPChain is Script { /// @notice The default init bond for the dispute games. uint256 public constant DEFAULT_INIT_BOND = 0.08 ether; - /// @notice Whether to use OPCM v2. - bool public isOPCMv2; - /// @notice Whether the OPCM has SUPER_ROOT_GAMES_MIGRATION enabled. bool public isSuperRoot; @@ -77,28 +72,15 @@ contract DeployOPChain is Script { function run(Types.DeployOPChainInput memory _input) public returns (Output memory output_) { checkInput(_input); - // Check if OPCM v2 should be used, both v1 and v2 share the same interface for this function. require(address(_input.opcm).code.length > 0, "DeployOPChain: OPCM address has no code"); - isOPCMv2 = SemverComp.gte(IOPContractsManager(_input.opcm).version(), Constants.OPCM_V2_MIN_VERSION); - - if (isOPCMv2) { - IOPContractsManagerV2 opcmV2 = IOPContractsManagerV2(_input.opcm); - isSuperRoot = - DevFeatures.isDevFeatureEnabled(opcmV2.devFeatureBitmap(), DevFeatures.SUPER_ROOT_GAMES_MIGRATION); - IOPContractsManagerV2.FullConfig memory config = _toOPCMV2DeployInput(_input); - vm.broadcast(msg.sender); - IOPContractsManagerV2.ChainContracts memory chainContracts = opcmV2.deploy(config); - output_ = _fromOPCMV2OutputToOutput(chainContracts); - } else { - IOPContractsManager opcm = IOPContractsManager(_input.opcm); - IOPContractsManager.DeployInput memory deployInput = _toOPCMV1DeployInput(_input); + IOPContractsManagerV2 opcmV2 = IOPContractsManagerV2(_input.opcm); + isSuperRoot = DevFeatures.isDevFeatureEnabled(opcmV2.devFeatureBitmap(), DevFeatures.SUPER_ROOT_GAMES_MIGRATION); + IOPContractsManagerV2.FullConfig memory config = _toOPCMV2DeployInput(_input); - vm.broadcast(msg.sender); - IOPContractsManager.DeployOutput memory deployOutput = opcm.deploy(deployInput); - - output_ = _fromOPCMV1OutputToOutput(deployOutput); - } + vm.broadcast(msg.sender); + IOPContractsManagerV2.ChainContracts memory chainContracts = opcmV2.deploy(config); + output_ = _fromOPCMV2OutputToOutput(chainContracts); checkOutput(_input, output_); @@ -121,40 +103,6 @@ contract DeployOPChain is Script { // -------- Features -------- - /// @notice Converts Types.DeployOPChainInput to IOPContractsManager.DeployInput. - /// @param _input The input parameters. - /// @return deployInput_ The deployed input parameters. - function _toOPCMV1DeployInput(Types.DeployOPChainInput memory _input) - internal - pure - returns (IOPContractsManager.DeployInput memory deployInput_) - { - IOPContractsManager.Roles memory roles = IOPContractsManager.Roles({ - opChainProxyAdminOwner: _input.opChainProxyAdminOwner, - systemConfigOwner: _input.systemConfigOwner, - batcher: _input.batcher, - unsafeBlockSigner: _input.unsafeBlockSigner, - proposer: _input.proposer, - challenger: _input.challenger - }); - deployInput_ = IOPContractsManager.DeployInput({ - roles: roles, - basefeeScalar: _input.basefeeScalar, - blobBasefeeScalar: _input.blobBaseFeeScalar, - l2ChainId: _input.l2ChainId, - startingAnchorRoot: startingAnchorRoot(), - saltMixer: _input.saltMixer, - gasLimit: _input.gasLimit, - disputeGameType: _input.disputeGameType, - disputeAbsolutePrestate: _input.disputeAbsolutePrestate, - disputeMaxGameDepth: _input.disputeMaxGameDepth, - disputeSplitDepth: _input.disputeSplitDepth, - disputeClockExtension: _input.disputeClockExtension, - disputeMaxClockDuration: _input.disputeMaxClockDuration, - useCustomGasToken: _input.useCustomGasToken - }); - } - /// @notice Converts Types.DeployOPChainInput to IOPContractsManagerV2.FullConfig. /// @param _input The input parameters. /// @return config_ The deployed input parameters. @@ -294,33 +242,6 @@ contract DeployOPChain is Script { }); } - /// @notice Converts IOPContractsManager.DeployOutput to Output. - /// @param _deployOutput The deploy output. - /// @return output_ The output parameters. - function _fromOPCMV1OutputToOutput(IOPContractsManager.DeployOutput memory _deployOutput) - internal - pure - returns (Output memory output_) - { - output_ = Output({ - opChainProxyAdmin: _deployOutput.opChainProxyAdmin, - addressManager: _deployOutput.addressManager, - l1ERC721BridgeProxy: _deployOutput.l1ERC721BridgeProxy, - systemConfigProxy: _deployOutput.systemConfigProxy, - optimismMintableERC20FactoryProxy: _deployOutput.optimismMintableERC20FactoryProxy, - l1StandardBridgeProxy: _deployOutput.l1StandardBridgeProxy, - l1CrossDomainMessengerProxy: _deployOutput.l1CrossDomainMessengerProxy, - optimismPortalProxy: _deployOutput.optimismPortalProxy, - ethLockboxProxy: _deployOutput.ethLockboxProxy, - disputeGameFactoryProxy: _deployOutput.disputeGameFactoryProxy, - anchorStateRegistryProxy: _deployOutput.anchorStateRegistryProxy, - faultDisputeGame: _deployOutput.faultDisputeGame, - permissionedDisputeGame: _deployOutput.permissionedDisputeGame, - delayedWETHPermissionedGameProxy: _deployOutput.delayedWETHPermissionedGameProxy, - delayedWETHPermissionlessGameProxy: _deployOutput.delayedWETHPermissionlessGameProxy - }); - } - // -------- Validations -------- /// @notice Checks if the input is valid. @@ -398,20 +319,10 @@ contract DeployOPChain is Script { }); // Check dispute games and get superchain config - address expectedPDGImpl = address(_o.permissionedDisputeGame); - - if (isOPCMv2) { - // OPCM v2: use implementations from v2 contract - IOPContractsManagerV2 opcmV2 = IOPContractsManagerV2(_i.opcm); - expectedPDGImpl = isSuperRoot - ? opcmV2.implementations().superPermissionedDisputeGameImpl - : opcmV2.implementations().permissionedDisputeGameImpl; - } else { - // OPCM v1: use implementations from v1 contract - IOPContractsManager opcm = IOPContractsManager(_i.opcm); - // With v2 game contracts enabled, we use the predeployed pdg implementation - expectedPDGImpl = opcm.implementations().permissionedDisputeGameImpl; - } + IOPContractsManagerV2 opcmV2 = IOPContractsManagerV2(_i.opcm); + address expectedPDGImpl = isSuperRoot + ? opcmV2.implementations().superPermissionedDisputeGameImpl + : opcmV2.implementations().permissionedDisputeGameImpl; GameType permGameType = isSuperRoot ? GameTypes.SUPER_PERMISSIONED_CANNON : GameTypes.PERMISSIONED_CANNON; ChainAssertions.checkDisputeGameFactory( diff --git a/packages/contracts-bedrock/scripts/deploy/InteropMigration.s.sol b/packages/contracts-bedrock/scripts/deploy/InteropMigration.s.sol index 0ea4742123c84..f2c4c756b4d58 100644 --- a/packages/contracts-bedrock/scripts/deploy/InteropMigration.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/InteropMigration.s.sol @@ -3,13 +3,13 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; -import { IOPContractsManagerInteropMigrator, IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerMigrator } from "interfaces/L1/opcm/IOPContractsManagerMigrator.sol"; +import { ISemver } from "interfaces/universal/ISemver.sol"; +import { SemverComp } from "src/libraries/SemverComp.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { DummyCaller } from "scripts/libraries/DummyCaller.sol"; import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPortal2.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; contract InteropMigrationInput is BaseDeployIO { address internal _prank; @@ -25,17 +25,7 @@ contract InteropMigrationInput is BaseDeployIO { else revert("InteropMigrationInput: unknown selector"); } - /// @notice Sets the migrate input using the IOPContractsManagerInteropMigrator.MigrateInput type, - /// this is used when migrating chains using OPCM v1. - /// @param _sel The selector of the field to set. - /// @param _value The value to set. - function set(bytes4 _sel, IOPContractsManagerInteropMigrator.MigrateInput memory _value) public { - if (_sel == this.migrateInput.selector) _migrateInput = abi.encode(_value); - else revert("InteropMigrationInput: unknown selector"); - } - - /// @notice Sets the migrate input using the IOPContractsManagerMigrator.MigrateInput type, - /// this is used when migrating chains using OPCM v2. + /// @notice Sets the migrate input using the IOPContractsManagerMigrator.MigrateInput type. /// @param _sel The selector of the field to set. /// @param _value The value to set. function set(bytes4 _sel, IOPContractsManagerMigrator.MigrateInput memory _value) public { @@ -75,14 +65,13 @@ contract InteropMigrationOutput is BaseDeployIO { } contract InteropMigration is Script { - /// @notice Whether to use OPCM v2. - bool internal _useOPCMv2; - function run(InteropMigrationInput _imi, InteropMigrationOutput _imo) public { - // Determine OPCM version by checking the semver or if the OPCM address is set. OPCM v2 starts at version 7.0.0. - IOPContractsManager opcm = IOPContractsManager(_imi.opcm()); - require(address(opcm).code.length > 0, "InteropMigration: OPCM address has no code"); - _useOPCMv2 = SemverComp.gte(opcm.version(), "7.0.0"); + address opcm = _imi.opcm(); + require(opcm.code.length > 0, "InteropMigration: OPCM address has no code"); + require( + SemverComp.gte(ISemver(opcm).version(), "7.0.0"), + "InteropMigration: OPCM must be v7.0.0 or later (OPCMv2). OPCMv1 is no longer supported." + ); // 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 @@ -90,21 +79,15 @@ contract InteropMigration is Script { address prank = _imi.prank(); bytes memory code = type(DummyCaller).runtimeCode; vm.etch(prank, code); - vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(opcm))))); + vm.store(prank, bytes32(0), bytes32(uint256(uint160(opcm)))); vm.label(prank, "DummyCaller"); // Call into the DummyCaller. This will perform the delegatecall under the hood. // The DummyCaller uses a fallback that reverts on failure, so no need to check success. vm.startBroadcast(msg.sender); - if (_useOPCMv2) { - IOPContractsManagerMigrator(prank).migrate( - abi.decode(_imi.migrateInput(), (IOPContractsManagerMigrator.MigrateInput)) - ); - } else { - IOPContractsManagerInteropMigrator(prank).migrate( - abi.decode(_imi.migrateInput(), (IOPContractsManagerInteropMigrator.MigrateInput)) - ); - } + IOPContractsManagerMigrator(prank).migrate( + abi.decode(_imi.migrateInput(), (IOPContractsManagerMigrator.MigrateInput)) + ); vm.stopBroadcast(); // After migration all portals will have the same DGF @@ -113,48 +96,26 @@ contract InteropMigration is Script { checkOutput(_imi, _imo); } - /// @notice Helper function to set the dispute game factory in the output based on the OPCM version. + /// @notice Helper function to set the dispute game factory in the output. /// @param _imi The migration input. /// @param _imo The migration output. function _setDisputeGameFactory(InteropMigrationInput _imi, InteropMigrationOutput _imo) internal { - if (_useOPCMv2) { - IOPContractsManagerMigrator.MigrateInput memory inputV2 = - abi.decode(_imi.migrateInput(), (IOPContractsManagerMigrator.MigrateInput)); - IOptimismPortal portal = IOptimismPortal(payable(inputV2.chainSystemConfigs[0].optimismPortal())); - _imo.set(_imo.disputeGameFactory.selector, portal.disputeGameFactory()); - } else { - IOPContractsManagerInteropMigrator.MigrateInput memory inputV1 = - abi.decode(_imi.migrateInput(), (IOPContractsManagerInteropMigrator.MigrateInput)); - IOptimismPortal portal = - IOptimismPortal(payable(inputV1.opChainConfigs[0].systemConfigProxy.optimismPortal())); - _imo.set(_imo.disputeGameFactory.selector, portal.disputeGameFactory()); - } + IOPContractsManagerMigrator.MigrateInput memory migrateInput = + abi.decode(_imi.migrateInput(), (IOPContractsManagerMigrator.MigrateInput)); + IOptimismPortal portal = IOptimismPortal(payable(migrateInput.chainSystemConfigs[0].optimismPortal())); + _imo.set(_imo.disputeGameFactory.selector, portal.disputeGameFactory()); } function checkOutput(InteropMigrationInput _imi, InteropMigrationOutput _imo) public view { - if (_useOPCMv2) { - IOPContractsManagerMigrator.MigrateInput memory inputV2 = - abi.decode(_imi.migrateInput(), (IOPContractsManagerMigrator.MigrateInput)); - - for (uint256 i = 0; i < inputV2.chainSystemConfigs.length; i++) { - IOptimismPortal portal = IOptimismPortal(payable(inputV2.chainSystemConfigs[i].optimismPortal())); - require( - IDisputeGameFactory(portal.disputeGameFactory()) == _imo.disputeGameFactory(), - "InteropMigration: disputeGameFactory mismatch" - ); - } - } else { - IOPContractsManagerInteropMigrator.MigrateInput memory inputV1 = - abi.decode(_imi.migrateInput(), (IOPContractsManagerInteropMigrator.MigrateInput)); - - for (uint256 i = 0; i < inputV1.opChainConfigs.length; i++) { - IOptimismPortal portal = - IOptimismPortal(payable(inputV1.opChainConfigs[i].systemConfigProxy.optimismPortal())); - require( - IDisputeGameFactory(portal.disputeGameFactory()) == _imo.disputeGameFactory(), - "InteropMigration: disputeGameFactory mismatch" - ); - } + IOPContractsManagerMigrator.MigrateInput memory migrateInput = + abi.decode(_imi.migrateInput(), (IOPContractsManagerMigrator.MigrateInput)); + + for (uint256 i = 0; i < migrateInput.chainSystemConfigs.length; i++) { + IOptimismPortal portal = IOptimismPortal(payable(migrateInput.chainSystemConfigs[i].optimismPortal())); + require( + IDisputeGameFactory(portal.disputeGameFactory()) == _imo.disputeGameFactory(), + "InteropMigration: disputeGameFactory mismatch" + ); } } } diff --git a/packages/contracts-bedrock/scripts/deploy/ReadImplementationAddresses.s.sol b/packages/contracts-bedrock/scripts/deploy/ReadImplementationAddresses.s.sol index 75ab6d7d3cda9..9aa029b92d03c 100644 --- a/packages/contracts-bedrock/scripts/deploy/ReadImplementationAddresses.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/ReadImplementationAddresses.s.sol @@ -4,13 +4,10 @@ pragma solidity 0.8.15; import { IProxy } from "interfaces/universal/IProxy.sol"; import { Script } from "forge-std/Script.sol"; import { IMIPS64 } from "interfaces/cannon/IMIPS64.sol"; -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOPContractsManagerContainer } from "interfaces/L1/opcm/IOPContractsManagerContainer.sol"; import { IAddressManager } from "interfaces/legacy/IAddressManager.sol"; import { IStaticL1ChugSplashProxy } from "interfaces/legacy/IL1ChugSplashProxy.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; -import { Constants } from "src/libraries/Constants.sol"; contract ReadImplementationAddresses is Script { struct Input { @@ -61,53 +58,26 @@ contract ReadImplementationAddresses is Script { vm.prank(address(0)); output_.l1StandardBridge = IStaticL1ChugSplashProxy(_input.l1StandardBridgeProxy).getImplementation(); - // Check if OPCM v2 is being used require(address(_input.opcm).code.length > 0, "ReadImplementationAddresses: OPCM address has no code"); - bool isOPCMv2 = SemverComp.gte(IOPContractsManager(_input.opcm).version(), Constants.OPCM_V2_MIN_VERSION); + IOPContractsManagerV2 opcmV2 = IOPContractsManagerV2(_input.opcm); - if (isOPCMv2) { - // Get implementations from OPCM V2 - IOPContractsManagerV2 opcmV2 = IOPContractsManagerV2(_input.opcm); + output_.opcmGameTypeAdder = address(0); + output_.opcmDeployer = address(0); + output_.opcmUpgrader = address(0); - // These addresses are deprecated in OPCM V2 - output_.opcmGameTypeAdder = address(0); - output_.opcmDeployer = address(0); - output_.opcmUpgrader = address(0); + output_.opcmInteropMigrator = address(opcmV2.opcmMigrator()); + output_.opcmStandardValidator = address(opcmV2.opcmStandardValidator()); - // Get migrator and standard validator from OPCM V2 - output_.opcmInteropMigrator = address(opcmV2.opcmMigrator()); - output_.opcmStandardValidator = address(opcmV2.opcmStandardValidator()); - - IOPContractsManagerContainer.Implementations memory impls = opcmV2.implementations(); - output_.mipsSingleton = impls.mipsImpl; - output_.delayedWETH = impls.delayedWETHImpl; - output_.ethLockbox = impls.ethLockboxImpl; - output_.anchorStateRegistry = impls.anchorStateRegistryImpl; - output_.optimismPortalInterop = impls.optimismPortalInteropImpl; - output_.faultDisputeGame = impls.faultDisputeGameImpl; - output_.permissionedDisputeGame = impls.permissionedDisputeGameImpl; - output_.superFaultDisputeGame = impls.superFaultDisputeGameImpl; - output_.superPermissionedDisputeGame = impls.superPermissionedDisputeGameImpl; - } else { - // Get implementations from OPCM V1 - IOPContractsManager opcm = IOPContractsManager(_input.opcm); - output_.opcmGameTypeAdder = address(opcm.opcmGameTypeAdder()); - output_.opcmDeployer = address(opcm.opcmDeployer()); - output_.opcmUpgrader = address(opcm.opcmUpgrader()); - output_.opcmInteropMigrator = address(opcm.opcmInteropMigrator()); - output_.opcmStandardValidator = address(opcm.opcmStandardValidator()); - - IOPContractsManager.Implementations memory impls = opcm.implementations(); - output_.mipsSingleton = impls.mipsImpl; - output_.delayedWETH = impls.delayedWETHImpl; - output_.ethLockbox = impls.ethLockboxImpl; - output_.anchorStateRegistry = impls.anchorStateRegistryImpl; - output_.optimismPortalInterop = impls.optimismPortalInteropImpl; - output_.faultDisputeGame = impls.faultDisputeGameImpl; - output_.permissionedDisputeGame = impls.permissionedDisputeGameImpl; - output_.superFaultDisputeGame = impls.superFaultDisputeGameImpl; - output_.superPermissionedDisputeGame = impls.superPermissionedDisputeGameImpl; - } + IOPContractsManagerContainer.Implementations memory impls = opcmV2.implementations(); + output_.mipsSingleton = impls.mipsImpl; + output_.delayedWETH = impls.delayedWETHImpl; + output_.ethLockbox = impls.ethLockboxImpl; + output_.anchorStateRegistry = impls.anchorStateRegistryImpl; + output_.optimismPortalInterop = impls.optimismPortalInteropImpl; + output_.faultDisputeGame = impls.faultDisputeGameImpl; + output_.permissionedDisputeGame = impls.permissionedDisputeGameImpl; + output_.superFaultDisputeGame = impls.superFaultDisputeGameImpl; + output_.superPermissionedDisputeGame = impls.superPermissionedDisputeGameImpl; // Get L1CrossDomainMessenger from AddressManager IAddressManager am = IAddressManager(_input.addressManager); diff --git a/packages/contracts-bedrock/scripts/deploy/ReadSuperchainDeployment.s.sol b/packages/contracts-bedrock/scripts/deploy/ReadSuperchainDeployment.s.sol index 905118b907498..d73b7f48217ba 100644 --- a/packages/contracts-bedrock/scripts/deploy/ReadSuperchainDeployment.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/ReadSuperchainDeployment.s.sol @@ -4,28 +4,26 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; -import { IProtocolVersions, ProtocolVersion } from "interfaces/L1/IProtocolVersions.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IProxy } from "interfaces/universal/IProxy.sol"; -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; -import { Constants } from "src/libraries/Constants.sol"; contract ReadSuperchainDeployment is Script { struct Input { - IOPContractsManager opcmAddress; // TODO(#18612): Remove OPCMAddress field when OPCMv1 gets deprecated + // Deprecated v1 field — kept for Go ABI compatibility, ignored. + // Remove when Go op-deployer drops v1 struct fields. + address opcmAddress; ISuperchainConfig superchainConfigProxy; } struct Output { - // TODO(#18612): Remove ProtocolVersions fields when OPCMv1 gets deprecated - IProtocolVersions protocolVersionsImpl; - IProtocolVersions protocolVersionsProxy; + // Deprecated v1 ProtocolVersions fields — kept for Go ABI compatibility, always zero. + // Remove when Go op-deployer drops v1 struct fields. + address protocolVersionsImpl; + address protocolVersionsProxy; address protocolVersionsOwner; bytes32 recommendedProtocolVersion; bytes32 requiredProtocolVersion; - // Superchain config ISuperchainConfig superchainConfigImpl; ISuperchainConfig superchainConfigProxy; IProxyAdmin superchainProxyAdmin; @@ -34,58 +32,22 @@ contract ReadSuperchainDeployment is Script { } function run(Input memory _input) public returns (Output memory output_) { - // Determine OPCM version by checking the semver or if the OPCM address is set. OPCM v2 starts at version 7.0.0. - IOPContractsManager opcm = IOPContractsManager(_input.opcmAddress); - bool isOPCMV2; - if (address(opcm) == address(0)) { - isOPCMV2 = true; - } else { - require(address(opcm).code.length > 0, "ReadSuperchainDeployment: OPCM address has no code"); - isOPCMV2 = SemverComp.gte(opcm.version(), Constants.OPCM_V2_MIN_VERSION); - } + require( + address(_input.superchainConfigProxy).code.length > 0, + "ReadSuperchainDeployment: superchainConfigProxy has no code" + ); - if (isOPCMV2) { - require( - address(_input.superchainConfigProxy).code.length > 0, - "ReadSuperchainDeployment: superchainConfigProxy has no code for OPCM v2" - ); + output_.superchainConfigProxy = _input.superchainConfigProxy; + output_.superchainProxyAdmin = IProxyAdmin(EIP1967Helper.getAdmin(address(output_.superchainConfigProxy))); - // For OPCM v2, ProtocolVersions is being removed. Therefore, the ProtocolVersions-related fields - // (protocolVersionsImpl, protocolVersionsProxy, protocolVersionsOwner, recommendedProtocolVersion, - // requiredProtocolVersion) are intentionally left uninitialized. - output_.superchainConfigProxy = _input.superchainConfigProxy; - output_.superchainProxyAdmin = IProxyAdmin(EIP1967Helper.getAdmin(address(output_.superchainConfigProxy))); + IProxy superchainConfigProxy = IProxy(payable(address(output_.superchainConfigProxy))); - IProxy superchainConfigProxy = IProxy(payable(address(output_.superchainConfigProxy))); + vm.startPrank(address(0)); + output_.superchainConfigImpl = ISuperchainConfig(superchainConfigProxy.implementation()); + vm.stopPrank(); - vm.startPrank(address(0)); - output_.superchainConfigImpl = ISuperchainConfig(superchainConfigProxy.implementation()); - vm.stopPrank(); - - output_.guardian = output_.superchainConfigProxy.guardian(); - output_.superchainProxyAdminOwner = output_.superchainProxyAdmin.owner(); - } else { - // When running on OPCM v1, the OPCM address is used to read the ProtocolVersions contract and - // SuperchainConfig. - output_.protocolVersionsProxy = IProtocolVersions(opcm.protocolVersions()); - output_.superchainConfigProxy = ISuperchainConfig(opcm.superchainConfig()); - output_.superchainProxyAdmin = IProxyAdmin(EIP1967Helper.getAdmin(address(output_.superchainConfigProxy))); - - IProxy protocolVersionsProxy = IProxy(payable(address(output_.protocolVersionsProxy))); - IProxy superchainConfigProxy = IProxy(payable(address(output_.superchainConfigProxy))); - - vm.startPrank(address(0)); - output_.protocolVersionsImpl = IProtocolVersions(protocolVersionsProxy.implementation()); - output_.superchainConfigImpl = ISuperchainConfig(superchainConfigProxy.implementation()); - vm.stopPrank(); - - output_.guardian = output_.superchainConfigProxy.guardian(); - output_.protocolVersionsOwner = output_.protocolVersionsProxy.owner(); - output_.superchainProxyAdminOwner = output_.superchainProxyAdmin.owner(); - output_.recommendedProtocolVersion = - bytes32(ProtocolVersion.unwrap(output_.protocolVersionsProxy.recommended())); - output_.requiredProtocolVersion = bytes32(ProtocolVersion.unwrap(output_.protocolVersionsProxy.required())); - } + output_.guardian = output_.superchainConfigProxy.guardian(); + output_.superchainProxyAdminOwner = output_.superchainProxyAdmin.owner(); } function runWithBytes(bytes memory _input) public returns (bytes memory) { diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol index 1d18574c8dd0d..dd0f725a15701 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol @@ -2,12 +2,11 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; -import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { OPContractsManagerV2 } from "src/L1/opcm/OPContractsManagerV2.sol"; +import { ISemver } from "interfaces/universal/ISemver.sol"; +import { SemverComp } from "src/libraries/SemverComp.sol"; import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; import { DummyCaller } from "scripts/libraries/DummyCaller.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; -import { Constants } from "src/libraries/Constants.sol"; contract UpgradeOPChainInput is BaseDeployIO { address internal _prank; @@ -24,30 +23,12 @@ contract UpgradeOPChainInput is BaseDeployIO { else revert("UpgradeOPCMInput: unknown selector"); } - /// @notice Sets the upgrade input using the OPContractsManager.OpChainConfig[] type, - /// this is used when upgrading chains using OPCM v1. - /// @param _sel The selector of the field to set. - /// @param _value The value to set. - function set(bytes4 _sel, OPContractsManager.OpChainConfig[] memory _value) public { - if (SemverComp.gte(OPContractsManager(opcm()).version(), Constants.OPCM_V2_MIN_VERSION)) { - revert("UpgradeOPCMInput: cannot set OPCM v1 upgrade input when OPCM v2 is enabled"); - } - require(_value.length > 0, "UpgradeOPCMInput: cannot set empty array"); - - if (_sel == this.upgradeInput.selector) _upgradeInput = abi.encode(_value); - else revert("UpgradeOPCMInput: unknown selector"); - } - - /// @notice Sets the upgrade input using the OPContractsManagerV2.UpgradeInput type, - /// this is used when upgrading chains using OPCM v2. + /// @notice Sets the upgrade input using the OPContractsManagerV2.UpgradeInput type. /// Minimal validation is performed, relying on the OPCM v2 contract to perform the proper validation. /// This is done to avoid duplicating the validation logic in the script. /// @param _sel The selector of the field to set. /// @param _value The value to set. function set(bytes4 _sel, OPContractsManagerV2.UpgradeInput memory _value) public { - if (!SemverComp.gte(OPContractsManager(opcm()).version(), Constants.OPCM_V2_MIN_VERSION)) { - revert("UpgradeOPCMInput: cannot set OPCM v2 upgrade input when OPCM v1 is enabled"); - } require(address(_value.systemConfig) != address(0), "UpgradeOPCMInput: cannot set zero address"); require(_value.disputeGameConfigs.length > 0, "UpgradeOPCMInput: cannot set empty dispute game configs array"); @@ -74,9 +55,11 @@ contract UpgradeOPChainInput is BaseDeployIO { contract UpgradeOPChain is Script { function run(UpgradeOPChainInput _uoci) external { address opcm = _uoci.opcm(); - - // First, we need to check what version of OPCM is being used. - bool isOPCMv2 = SemverComp.gte(OPContractsManager(opcm).version(), Constants.OPCM_V2_MIN_VERSION); + require(opcm.code.length > 0, "UpgradeOPChain: OPCM address has no code"); + require( + SemverComp.gte(ISemver(opcm).version(), "7.0.0"), + "UpgradeOPChain: OPCM must be v7.0.0 or later (OPCMv2). OPCMv1 is no longer supported." + ); // 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 @@ -93,7 +76,7 @@ contract UpgradeOPChain is Script { // Call into the DummyCaller. This will perform the delegatecall under the hood. // The DummyCaller uses a fallback that reverts on failure, so no need to check success. vm.broadcast(msg.sender); - _upgrade(prank, isOPCMv2, upgradeInput); + _upgrade(prank, upgradeInput); } /// @notice Helper function to get the dummy caller code. @@ -102,22 +85,13 @@ contract UpgradeOPChain is Script { return type(DummyCaller).runtimeCode; } - /// @notice Helper function to upgrade the OPCM based on the OPCM version. Performs the decoding of the upgrade + /// @notice Helper function to upgrade the OPCM. Performs the decoding of the upgrade /// input and the delegatecall to the OPCM. /// @param _prank The address of the dummy caller contract. - /// @param _isOPCMv2 Whether to use OPCM v2. /// @param _upgradeInput The upgrade input. - function _upgrade(address _prank, bool _isOPCMv2, bytes memory _upgradeInput) internal { - bytes memory data; - if (_isOPCMv2) { - data = abi.encodeCall( - OPContractsManagerV2.upgrade, abi.decode(_upgradeInput, (OPContractsManagerV2.UpgradeInput)) - ); - } else { - data = abi.encodeCall( - OPContractsManager.upgrade, abi.decode(_upgradeInput, (OPContractsManager.OpChainConfig[])) - ); - } + function _upgrade(address _prank, bytes memory _upgradeInput) internal { + bytes memory data = + abi.encodeCall(OPContractsManagerV2.upgrade, abi.decode(_upgradeInput, (OPContractsManagerV2.UpgradeInput))); (bool success, bytes memory returnData) = _prank.call(data); if (!success) { assembly { diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol index c386c7e2c8ee6..fbad006b97aad 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeSuperchainConfig.s.sol @@ -2,13 +2,10 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { DummyCaller } from "scripts/libraries/DummyCaller.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; -import { Constants } from "src/libraries/Constants.sol"; contract UpgradeSuperchainConfig is Script { struct Input { @@ -25,8 +22,6 @@ contract UpgradeSuperchainConfig is Script { address opcm = _input.opcm; - bool isOPCMv2 = SemverComp.gte(IOPContractsManager(opcm).version(), Constants.OPCM_V2_MIN_VERSION); - // 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. @@ -41,7 +36,7 @@ contract UpgradeSuperchainConfig is Script { // Call into the DummyCaller. This will perform the delegatecall under the hood. // The DummyCaller uses a fallback that reverts on failure, so no need to check success. vm.broadcast(msg.sender); - _upgrade(prank, isOPCMv2, _input); + _upgrade(prank, _input); } /// @notice Asserts that the input is valid. @@ -59,24 +54,17 @@ contract UpgradeSuperchainConfig is Script { return type(DummyCaller).runtimeCode; } - /// @notice Helper function to upgrade the OPCM based on the OPCM version. Performs the decoding of the upgrade - /// input and the delegatecall to the OPCM. + /// @notice Helper function to upgrade the superchain config. Performs the delegatecall to the OPCM. /// @param _prank The address of the dummy caller contract. - /// @param _isOPCMv2 Whether to use OPCM v2. /// @param _input The input. - function _upgrade(address _prank, bool _isOPCMv2, Input memory _input) internal { - bytes memory data; - if (_isOPCMv2) { - data = abi.encodeCall( - IOPContractsManagerV2.upgradeSuperchain, - IOPContractsManagerV2.SuperchainUpgradeInput({ - superchainConfig: _input.superchainConfig, - extraInstructions: _input.extraInstructions - }) - ); - } else { - data = abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, _input.superchainConfig); - } + function _upgrade(address _prank, Input memory _input) internal { + bytes memory data = abi.encodeCall( + IOPContractsManagerV2.upgradeSuperchain, + IOPContractsManagerV2.SuperchainUpgradeInput({ + superchainConfig: _input.superchainConfig, + extraInstructions: _input.extraInstructions + }) + ); (bool success, bytes memory returnData) = _prank.call(data); if (!success) { assembly { diff --git a/packages/contracts-bedrock/scripts/deploy/VerifyOPCM.s.sol b/packages/contracts-bedrock/scripts/deploy/VerifyOPCM.s.sol index b5e6e92627248..27230d23e293d 100644 --- a/packages/contracts-bedrock/scripts/deploy/VerifyOPCM.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/VerifyOPCM.s.sol @@ -13,11 +13,10 @@ import { Process } from "scripts/libraries/Process.sol"; import { Config } from "scripts/libraries/Config.sol"; import { Bytes } from "src/libraries/Bytes.sol"; import { DevFeatures } from "src/libraries/DevFeatures.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; import { Constants } from "src/libraries/Constants.sol"; // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; import { IMIPS64 } from "interfaces/cannon/IMIPS64.sol"; @@ -202,13 +201,6 @@ contract VerifyOPCM is Script { fieldNameOverrides["opcmV2"] = "OPContractsManagerV2"; fieldNameOverrides["opcmUtils"] = "OPContractsManagerUtils"; - // Overrides for situations where contracts have differently named source files. - sourceNameOverrides["OPContractsManagerGameTypeAdder"] = "OPContractsManager"; - sourceNameOverrides["OPContractsManagerDeployer"] = "OPContractsManager"; - sourceNameOverrides["OPContractsManagerUpgrader"] = "OPContractsManager"; - sourceNameOverrides["OPContractsManagerInteropMigrator"] = "OPContractsManager"; - sourceNameOverrides["OPContractsManagerContractsContainer"] = "OPContractsManager"; - // Expected getter functions and their verification methods. // CRITICAL: Any getter in the ABI that's not in this list will cause verification to fail. // NEVER add a getter without understanding HOW it's being verified! @@ -297,7 +289,7 @@ contract VerifyOPCM is Script { // This function is used as part of the release checklist to verify new contracts. // Rather than requiring an opcm input parameter, just pass in an empty reference // as we really only need this for features that are in development. - IOPContractsManager emptyOpcm = IOPContractsManager(address(0)); + IOPContractsManagerV2 emptyOpcm = IOPContractsManagerV2(address(0)); _verifyOpcmContractRef( emptyOpcm, OpcmContractRef({ field: _name, name: _name, addr: _addr, blueprint: false }), @@ -322,7 +314,7 @@ contract VerifyOPCM is Script { } // Fetch Implementations & Blueprints from OPCM - IOPContractsManager opcm = IOPContractsManager(_opcmAddress); + IOPContractsManagerV2 opcm = IOPContractsManagerV2(_opcmAddress); // Validate that all ABI getters are accounted for. _validateAllGettersAccounted(); @@ -352,7 +344,7 @@ contract VerifyOPCM is Script { /// @notice Collects all the references from the OPCM contract. /// @param _opcm The live OPCM contract. /// @return Array of OpcmContractRef structs containing contract names/addresses. - function _collectOpcmContractRefs(IOPContractsManager _opcm) internal returns (OpcmContractRef[] memory) { + function _collectOpcmContractRefs(IOPContractsManagerV2 _opcm) internal returns (OpcmContractRef[] memory) { // Collect property references. OpcmContractRef[] memory propRefs = _getOpcmPropertyRefs(_opcm); if (propRefs.length == 0) { @@ -396,7 +388,7 @@ contract VerifyOPCM is Script { refs[0] = OpcmContractRef({ field: "opcm", name: _opcmContractName(), addr: address(_opcm), blueprint: false }); refs[1] = OpcmContractRef({ field: "contractsContainer", - name: _isOPCMV2() ? "OPContractsManagerContainer" : "OPContractsManagerContractsContainer", + name: "OPContractsManagerContainer", addr: contractsContainerAddr, blueprint: false }); @@ -587,7 +579,7 @@ contract VerifyOPCM is Script { /// @param _skipConstructorVerification Whether to skip constructor verification. /// @return True if the contract reference is verified, false otherwise. function _verifyOpcmContractRef( - IOPContractsManager _opcm, + IOPContractsManagerV2 _opcm, OpcmContractRef memory _target, bool _skipConstructorVerification ) @@ -696,7 +688,7 @@ contract VerifyOPCM is Script { // If this is the OPCM contract itself, verify the immutable variables as well. if (keccak256(bytes(_target.field)) == keccak256(bytes("opcm"))) { - success = _verifyOpcmImmutableVariables(IOPContractsManager(_target.addr)) && success; + success = _verifyOpcmImmutableVariables(IOPContractsManagerV2(_target.addr)) && success; } // Log final status for this field. @@ -746,7 +738,7 @@ contract VerifyOPCM is Script { /// @notice Checks if super dispute games feature is enabled in the dev feature bitmap. /// @param _opcm The OPContractsManager to check. /// @return True if super dispute games are enabled. - function _isSuperDisputeGamesEnabled(IOPContractsManager _opcm) internal view returns (bool) { + function _isSuperDisputeGamesEnabled(IOPContractsManagerV2 _opcm) internal view returns (bool) { bytes32 bitmap = _opcm.devFeatureBitmap(); return DevFeatures.isDevFeatureEnabled(bitmap, DevFeatures.OPTIMISM_PORTAL_INTEROP) || DevFeatures.isDevFeatureEnabled(bitmap, DevFeatures.SUPER_ROOT_GAMES_MIGRATION); @@ -763,7 +755,7 @@ contract VerifyOPCM is Script { /// @notice Verifies that the immutable variables in the OPCM contract match expected values. /// @param _opcm The OPCM contract to verify immutable variables for. /// @return True if all immutable variables are verified, false otherwise. - function _verifyOpcmImmutableVariables(IOPContractsManager _opcm) internal returns (bool) { + function _verifyOpcmImmutableVariables(IOPContractsManagerV2 _opcm) internal returns (bool) { console.log(" Verifying OPCM immutable variables..."); bool success = true; @@ -942,7 +934,7 @@ contract VerifyOPCM is Script { /// references to other OPCM contracts. /// @param _opcm The live OPCM contract. /// @return Array of OpcmContractRef structs containing contract names/addresses. - function _getOpcmPropertyRefs(IOPContractsManager _opcm) internal returns (OpcmContractRef[] memory) { + function _getOpcmPropertyRefs(IOPContractsManagerV2 _opcm) internal returns (OpcmContractRef[] memory) { // Find all functions that start with "opcm". string[] memory functionNames = abi.decode( vm.parseJson( @@ -991,7 +983,7 @@ contract VerifyOPCM is Script { /// @param _blueprint Whether this is a blueprint or an implementation. /// @return Array of OpcmContractRef structs containing contract names/addresses. function _getOpcmContractRefs( - IOPContractsManager _opcm, + IOPContractsManagerV2 _opcm, string memory _property, bool _blueprint ) @@ -1052,7 +1044,7 @@ contract VerifyOPCM is Script { /// @return The contract name. function _getContractNameFromFieldName(string memory _fieldName) internal view returns (string memory) { if (LibString.eq(_fieldName, "contractsContainer")) { - _fieldName = _isOPCMV2() ? "contractsContainerV2" : "contractsContainerV1"; + _fieldName = "contractsContainerV2"; } // Check for an explicit override @@ -1189,7 +1181,7 @@ contract VerifyOPCM is Script { /// @notice Validates that the dev feature bitmap is empty on mainnet. /// @param _opcm The OPCM contract. - function _validateDevFeatureBitmap(IOPContractsManager _opcm) internal view { + function _validateDevFeatureBitmap(IOPContractsManagerV2 _opcm) internal view { // Get the dev feature bitmap. bytes32 devFeatureBitmap = _opcm.devFeatureBitmap(); @@ -1233,26 +1225,10 @@ contract VerifyOPCM is Script { } } - /// @notice Returns the name of the OPCM contract depending on whether the OPCM is V2. + /// @notice Returns the name of the OPCM contract. /// @return The name of the OPCM contract. - function _opcmContractName() internal view returns (string memory) { - return _isOPCMV2() ? "OPContractsManagerV2" : "OPContractsManager"; - } - - /// @notice Checks if the OPCM is V2. - /// @dev If the OPCM address is not set, default to false. - /// @return True if the OPCM is V2, false otherwise. - function _isOPCMV2() internal view returns (bool) { - // Get the OPCM contract address from the environment variables. - address opcmAddress = _getOPCMAddress(); - - // If the OPCM contract address is not set, default to V1. - if (opcmAddress == address(0)) { - return false; - } - - // If the OPCM contract version is greater than or equal to 7.0.0, then it is OPCM V2. - return SemverComp.gte(IOPContractsManager(opcmAddress).version(), Constants.OPCM_V2_MIN_VERSION); + function _opcmContractName() internal pure returns (string memory) { + return "OPContractsManagerV2"; } /// @notice Gets the address of the OPCM contract from the environment variables. @@ -1269,7 +1245,7 @@ contract VerifyOPCM is Script { /// @param _artifact The artifact info for the contract. /// @return True if all security-critical values are correct. function _verifySecurityCriticalValues( - IOPContractsManager _opcm, + IOPContractsManagerV2 _opcm, OpcmContractRef memory _target, ArtifactInfo memory _artifact ) @@ -1371,7 +1347,7 @@ contract VerifyOPCM is Script { /// @param _opcm The OPCM contract. /// @param _validator The StandardValidator contract address. /// @return True if all getters are valid. - function _verifyStandardValidatorArgs(IOPContractsManager _opcm, address _validator) internal returns (bool) { + function _verifyStandardValidatorArgs(IOPContractsManagerV2 _opcm, address _validator) internal returns (bool) { bool success = true; console.log(" Verifying StandardValidator args..."); diff --git a/packages/contracts-bedrock/scripts/libraries/Config.sol b/packages/contracts-bedrock/scripts/libraries/Config.sol index 99a9b51f00dec..cb0207f8c3e86 100644 --- a/packages/contracts-bedrock/scripts/libraries/Config.sol +++ b/packages/contracts-bedrock/scripts/libraries/Config.sol @@ -313,11 +313,6 @@ library Config { return vm.envOr("DEV_FEATURE__OPTIMISM_PORTAL_INTEROP", false); } - /// @notice Returns true if the development feature opcm_v2 is enabled. - function devFeatureOpcmV2() internal view returns (bool) { - return vm.envOr("DEV_FEATURE__OPCM_V2", false); - } - /// @notice Returns true if the development feature l2cm is enabled. function devFeatureL2CM() internal view returns (bool) { return vm.envOr("DEV_FEATURE__L2CM", false); diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json deleted file mode 100644 index 3b5c00dccc228..0000000000000 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json +++ /dev/null @@ -1,1143 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract OPContractsManagerGameTypeAdder", - "name": "_opcmGameTypeAdder", - "type": "address" - }, - { - "internalType": "contract OPContractsManagerDeployer", - "name": "_opcmDeployer", - "type": "address" - }, - { - "internalType": "contract OPContractsManagerUpgrader", - "name": "_opcmUpgrader", - "type": "address" - }, - { - "internalType": "contract OPContractsManagerInteropMigrator", - "name": "_opcmInteropMigrator", - "type": "address" - }, - { - "internalType": "contract OPContractsManagerStandardValidator", - "name": "_opcmStandardValidator", - "type": "address" - }, - { - "internalType": "contract ISuperchainConfig", - "name": "_superchainConfig", - "type": "address" - }, - { - "internalType": "contract IProtocolVersions", - "name": "_protocolVersions", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "string", - "name": "saltMixer", - "type": "string" - }, - { - "internalType": "contract ISystemConfig", - "name": "systemConfig", - "type": "address" - }, - { - "internalType": "contract IDelayedWETH", - "name": "delayedWETH", - "type": "address" - }, - { - "internalType": "GameType", - "name": "disputeGameType", - "type": "uint32" - }, - { - "internalType": "Claim", - "name": "disputeAbsolutePrestate", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "disputeMaxGameDepth", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "disputeSplitDepth", - "type": "uint256" - }, - { - "internalType": "Duration", - "name": "disputeClockExtension", - "type": "uint64" - }, - { - "internalType": "Duration", - "name": "disputeMaxClockDuration", - "type": "uint64" - }, - { - "internalType": "uint256", - "name": "initialBond", - "type": "uint256" - }, - { - "internalType": "contract IBigStepper", - "name": "vm", - "type": "address" - }, - { - "internalType": "bool", - "name": "permissioned", - "type": "bool" - } - ], - "internalType": "struct OPContractsManager.AddGameInput[]", - "name": "_gameConfigs", - "type": "tuple[]" - } - ], - "name": "addGameType", - "outputs": [ - { - "components": [ - { - "internalType": "contract IDelayedWETH", - "name": "delayedWETH", - "type": "address" - }, - { - "internalType": "contract IFaultDisputeGame", - "name": "faultDisputeGame", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.AddGameOutput[]", - "name": "", - "type": "tuple[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "blueprints", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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": "struct OPContractsManager.Blueprints", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2ChainId", - "type": "uint256" - } - ], - "name": "chainIdToBatchInboxAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "components": [ - { - "internalType": "address", - "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": "struct OPContractsManager.Roles", - "name": "roles", - "type": "tuple" - }, - { - "internalType": "uint32", - "name": "basefeeScalar", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "blobBasefeeScalar", - "type": "uint32" - }, - { - "internalType": "uint256", - "name": "l2ChainId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "startingAnchorRoot", - "type": "bytes" - }, - { - "internalType": "string", - "name": "saltMixer", - "type": "string" - }, - { - "internalType": "uint64", - "name": "gasLimit", - "type": "uint64" - }, - { - "internalType": "GameType", - "name": "disputeGameType", - "type": "uint32" - }, - { - "internalType": "Claim", - "name": "disputeAbsolutePrestate", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "disputeMaxGameDepth", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "disputeSplitDepth", - "type": "uint256" - }, - { - "internalType": "Duration", - "name": "disputeClockExtension", - "type": "uint64" - }, - { - "internalType": "Duration", - "name": "disputeMaxClockDuration", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "useCustomGasToken", - "type": "bool" - } - ], - "internalType": "struct OPContractsManager.DeployInput", - "name": "_input", - "type": "tuple" - } - ], - "name": "deploy", - "outputs": [ - { - "components": [ - { - "internalType": "contract IProxyAdmin", - "name": "opChainProxyAdmin", - "type": "address" - }, - { - "internalType": "contract IAddressManager", - "name": "addressManager", - "type": "address" - }, - { - "internalType": "contract IL1ERC721Bridge", - "name": "l1ERC721BridgeProxy", - "type": "address" - }, - { - "internalType": "contract ISystemConfig", - "name": "systemConfigProxy", - "type": "address" - }, - { - "internalType": "contract IOptimismMintableERC20Factory", - "name": "optimismMintableERC20FactoryProxy", - "type": "address" - }, - { - "internalType": "contract IL1StandardBridge", - "name": "l1StandardBridgeProxy", - "type": "address" - }, - { - "internalType": "contract IL1CrossDomainMessenger", - "name": "l1CrossDomainMessengerProxy", - "type": "address" - }, - { - "internalType": "contract IETHLockbox", - "name": "ethLockboxProxy", - "type": "address" - }, - { - "internalType": "contract IOptimismPortal2", - "name": "optimismPortalProxy", - "type": "address" - }, - { - "internalType": "contract IDisputeGameFactory", - "name": "disputeGameFactoryProxy", - "type": "address" - }, - { - "internalType": "contract IAnchorStateRegistry", - "name": "anchorStateRegistryProxy", - "type": "address" - }, - { - "internalType": "contract IFaultDisputeGame", - "name": "faultDisputeGame", - "type": "address" - }, - { - "internalType": "contract IPermissionedDisputeGame", - "name": "permissionedDisputeGame", - "type": "address" - }, - { - "internalType": "contract IDelayedWETH", - "name": "delayedWETHPermissionedGameProxy", - "type": "address" - }, - { - "internalType": "contract IDelayedWETH", - "name": "delayedWETHPermissionlessGameProxy", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.DeployOutput", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "devFeatureBitmap", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "implementations", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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", - "name": "faultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "permissionedDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superFaultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superPermissionedDisputeGameImpl", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.Implementations", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_feature", - "type": "bytes32" - } - ], - "name": "isDevFeatureEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "usePermissionlessGame", - "type": "bool" - }, - { - "components": [ - { - "internalType": "Hash", - "name": "root", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "l2SequenceNumber", - "type": "uint256" - } - ], - "internalType": "struct Proposal", - "name": "startingAnchorRoot", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "proposer", - "type": "address" - }, - { - "internalType": "address", - "name": "challenger", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxGameDepth", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "splitDepth", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "initBond", - "type": "uint256" - }, - { - "internalType": "Duration", - "name": "clockExtension", - "type": "uint64" - }, - { - "internalType": "Duration", - "name": "maxClockDuration", - "type": "uint64" - } - ], - "internalType": "struct OPContractsManagerInteropMigrator.GameParameters", - "name": "gameParameters", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "systemConfigProxy", - "type": "address" - }, - { - "internalType": "Claim", - "name": "cannonPrestate", - "type": "bytes32" - }, - { - "internalType": "Claim", - "name": "cannonKonaPrestate", - "type": "bytes32" - } - ], - "internalType": "struct OPContractsManager.OpChainConfig[]", - "name": "opChainConfigs", - "type": "tuple[]" - } - ], - "internalType": "struct OPContractsManagerInteropMigrator.MigrateInput", - "name": "_input", - "type": "tuple" - } - ], - "name": "migrate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "opcmDeployer", - "outputs": [ - { - "internalType": "contract OPContractsManagerDeployer", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "opcmGameTypeAdder", - "outputs": [ - { - "internalType": "contract OPContractsManagerGameTypeAdder", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "opcmInteropMigrator", - "outputs": [ - { - "internalType": "contract OPContractsManagerInteropMigrator", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "opcmStandardValidator", - "outputs": [ - { - "internalType": "contract OPContractsManagerStandardValidator", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "opcmUpgrader", - "outputs": [ - { - "internalType": "contract OPContractsManagerUpgrader", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "protocolVersions", - "outputs": [ - { - "internalType": "contract IProtocolVersions", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "superchainConfig", - "outputs": [ - { - "internalType": "contract ISuperchainConfig", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "systemConfigProxy", - "type": "address" - }, - { - "internalType": "Claim", - "name": "cannonPrestate", - "type": "bytes32" - }, - { - "internalType": "Claim", - "name": "cannonKonaPrestate", - "type": "bytes32" - } - ], - "internalType": "struct OPContractsManager.UpdatePrestateInput[]", - "name": "_prestateUpdateInputs", - "type": "tuple[]" - } - ], - "name": "updatePrestate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "systemConfigProxy", - "type": "address" - }, - { - "internalType": "Claim", - "name": "cannonPrestate", - "type": "bytes32" - }, - { - "internalType": "Claim", - "name": "cannonKonaPrestate", - "type": "bytes32" - } - ], - "internalType": "struct OPContractsManager.OpChainConfig[]", - "name": "_opChainConfigs", - "type": "tuple[]" - } - ], - "name": "upgrade", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISuperchainConfig", - "name": "_superchainConfig", - "type": "address" - } - ], - "name": "upgradeSuperchainConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "sysCfg", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "absolutePrestate", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "l2ChainID", - "type": "uint256" - }, - { - "internalType": "address", - "name": "proposer", - "type": "address" - } - ], - "internalType": "struct OPContractsManagerStandardValidator.ValidationInput", - "name": "_input", - "type": "tuple" - }, - { - "internalType": "bool", - "name": "_allowFailure", - "type": "bool" - } - ], - "name": "validate", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "sysCfg", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "cannonPrestate", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "cannonKonaPrestate", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "l2ChainID", - "type": "uint256" - }, - { - "internalType": "address", - "name": "proposer", - "type": "address" - } - ], - "internalType": "struct OPContractsManagerStandardValidator.ValidationInputDev", - "name": "_input", - "type": "tuple" - }, - { - "internalType": "bool", - "name": "_allowFailure", - "type": "bool" - } - ], - "name": "validate", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "sysCfg", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "absolutePrestate", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "l2ChainID", - "type": "uint256" - }, - { - "internalType": "address", - "name": "proposer", - "type": "address" - } - ], - "internalType": "struct OPContractsManagerStandardValidator.ValidationInput", - "name": "_input", - "type": "tuple" - }, - { - "internalType": "bool", - "name": "_allowFailure", - "type": "bool" - }, - { - "components": [ - { - "internalType": "address", - "name": "l1PAOMultisig", - "type": "address" - }, - { - "internalType": "address", - "name": "challenger", - "type": "address" - } - ], - "internalType": "struct OPContractsManagerStandardValidator.ValidationOverrides", - "name": "_overrides", - "type": "tuple" - } - ], - "name": "validateWithOverrides", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "sysCfg", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "cannonPrestate", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "cannonKonaPrestate", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "l2ChainID", - "type": "uint256" - }, - { - "internalType": "address", - "name": "proposer", - "type": "address" - } - ], - "internalType": "struct OPContractsManagerStandardValidator.ValidationInputDev", - "name": "_input", - "type": "tuple" - }, - { - "internalType": "bool", - "name": "_allowFailure", - "type": "bool" - }, - { - "components": [ - { - "internalType": "address", - "name": "l1PAOMultisig", - "type": "address" - }, - { - "internalType": "address", - "name": "challenger", - "type": "address" - } - ], - "internalType": "struct OPContractsManagerStandardValidator.ValidationOverrides", - "name": "_overrides", - "type": "tuple" - } - ], - "name": "validateWithOverrides", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "who", - "type": "address" - } - ], - "name": "AddressHasNoCode", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "who", - "type": "address" - } - ], - "name": "AddressNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "AlreadyReleased", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidChainId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "devFeature", - "type": "bytes32" - } - ], - "name": "InvalidDevFeatureAccess", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidGameConfigs", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "role", - "type": "string" - } - ], - "name": "InvalidRoleAddress", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidStartingAnchorRoot", - "type": "error" - }, - { - "inputs": [], - "name": "LatestReleaseNotSet", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManager_V2Enabled", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyDelegatecall", - "type": "error" - }, - { - "inputs": [], - "name": "PrestateNotSet", - "type": "error" - }, - { - "inputs": [], - "name": "PrestateRequired", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "contract ISystemConfig", - "name": "systemConfig", - "type": "address" - } - ], - "name": "SuperchainConfigMismatch", - "type": "error" - }, - { - "inputs": [], - "name": "SuperchainProxyAdminMismatch", - "type": "error" - } -] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerContractsContainer.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerContractsContainer.json deleted file mode 100644 index f6732e88a1f6a..0000000000000 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerContractsContainer.json +++ /dev/null @@ -1,337 +0,0 @@ -[ - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "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": "struct OPContractsManager.Blueprints", - "name": "_blueprints", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "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", - "name": "faultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "permissionedDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superFaultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superPermissionedDisputeGameImpl", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.Implementations", - "name": "_implementations", - "type": "tuple" - }, - { - "internalType": "bytes32", - "name": "_devFeatureBitmap", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "_isTestingEnvironment", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "blueprints", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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": "struct OPContractsManager.Blueprints", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "devFeatureBitmap", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "implementations", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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", - "name": "faultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "permissionedDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superFaultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superPermissionedDisputeGameImpl", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.Implementations", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_feature", - "type": "bytes32" - } - ], - "name": "isDevFeatureEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPContractsManagerContractsContainer_DevFeatureInProd", - "type": "error" - } -] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerDeployer.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerDeployer.json deleted file mode 100644 index f7813afc55c83..0000000000000 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerDeployer.json +++ /dev/null @@ -1,559 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract OPContractsManagerContractsContainer", - "name": "_contractsContainer", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_who", - "type": "address" - } - ], - "name": "assertValidContractAddress", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "blueprints", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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": "struct OPContractsManager.Blueprints", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2ChainId", - "type": "uint256" - } - ], - "name": "chainIdToBatchInboxAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "contractsContainer", - "outputs": [ - { - "internalType": "contract OPContractsManagerContractsContainer", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "components": [ - { - "internalType": "address", - "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": "struct OPContractsManager.Roles", - "name": "roles", - "type": "tuple" - }, - { - "internalType": "uint32", - "name": "basefeeScalar", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "blobBasefeeScalar", - "type": "uint32" - }, - { - "internalType": "uint256", - "name": "l2ChainId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "startingAnchorRoot", - "type": "bytes" - }, - { - "internalType": "string", - "name": "saltMixer", - "type": "string" - }, - { - "internalType": "uint64", - "name": "gasLimit", - "type": "uint64" - }, - { - "internalType": "GameType", - "name": "disputeGameType", - "type": "uint32" - }, - { - "internalType": "Claim", - "name": "disputeAbsolutePrestate", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "disputeMaxGameDepth", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "disputeSplitDepth", - "type": "uint256" - }, - { - "internalType": "Duration", - "name": "disputeClockExtension", - "type": "uint64" - }, - { - "internalType": "Duration", - "name": "disputeMaxClockDuration", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "useCustomGasToken", - "type": "bool" - } - ], - "internalType": "struct OPContractsManager.DeployInput", - "name": "_input", - "type": "tuple" - }, - { - "internalType": "contract ISuperchainConfig", - "name": "_superchainConfig", - "type": "address" - }, - { - "internalType": "address", - "name": "_deployer", - "type": "address" - } - ], - "name": "deploy", - "outputs": [ - { - "components": [ - { - "internalType": "contract IProxyAdmin", - "name": "opChainProxyAdmin", - "type": "address" - }, - { - "internalType": "contract IAddressManager", - "name": "addressManager", - "type": "address" - }, - { - "internalType": "contract IL1ERC721Bridge", - "name": "l1ERC721BridgeProxy", - "type": "address" - }, - { - "internalType": "contract ISystemConfig", - "name": "systemConfigProxy", - "type": "address" - }, - { - "internalType": "contract IOptimismMintableERC20Factory", - "name": "optimismMintableERC20FactoryProxy", - "type": "address" - }, - { - "internalType": "contract IL1StandardBridge", - "name": "l1StandardBridgeProxy", - "type": "address" - }, - { - "internalType": "contract IL1CrossDomainMessenger", - "name": "l1CrossDomainMessengerProxy", - "type": "address" - }, - { - "internalType": "contract IETHLockbox", - "name": "ethLockboxProxy", - "type": "address" - }, - { - "internalType": "contract IOptimismPortal2", - "name": "optimismPortalProxy", - "type": "address" - }, - { - "internalType": "contract IDisputeGameFactory", - "name": "disputeGameFactoryProxy", - "type": "address" - }, - { - "internalType": "contract IAnchorStateRegistry", - "name": "anchorStateRegistryProxy", - "type": "address" - }, - { - "internalType": "contract IFaultDisputeGame", - "name": "faultDisputeGame", - "type": "address" - }, - { - "internalType": "contract IPermissionedDisputeGame", - "name": "permissionedDisputeGame", - "type": "address" - }, - { - "internalType": "contract IDelayedWETH", - "name": "delayedWETHPermissionedGameProxy", - "type": "address" - }, - { - "internalType": "contract IDelayedWETH", - "name": "delayedWETHPermissionlessGameProxy", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.DeployOutput", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "devFeatureBitmap", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "implementations", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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", - "name": "faultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "permissionedDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superFaultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superPermissionedDisputeGameImpl", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.Implementations", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_feature", - "type": "bytes32" - } - ], - "name": "isDevFeatureEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "l2ChainId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "deployer", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "deployOutput", - "type": "bytes" - } - ], - "name": "Deployed", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "who", - "type": "address" - } - ], - "name": "AddressHasNoCode", - "type": "error" - }, - { - "inputs": [], - "name": "BytesArrayTooLong", - "type": "error" - }, - { - "inputs": [], - "name": "DeploymentFailed", - "type": "error" - }, - { - "inputs": [], - "name": "EmptyInitcode", - "type": "error" - }, - { - "inputs": [], - "name": "IdentityPrecompileCallFailed", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidChainId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "role", - "type": "string" - } - ], - "name": "InvalidRoleAddress", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidStartingAnchorRoot", - "type": "error" - }, - { - "inputs": [], - "name": "NotABlueprint", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManager_InvalidGameType", - "type": "error" - }, - { - "inputs": [], - "name": "ReservedBitsSet", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "UnexpectedPreambleData", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "UnsupportedERCVersion", - "type": "error" - } -] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerGameTypeAdder.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerGameTypeAdder.json deleted file mode 100644 index 4aec132f13168..0000000000000 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerGameTypeAdder.json +++ /dev/null @@ -1,482 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract OPContractsManagerContractsContainer", - "name": "_contractsContainer", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "string", - "name": "saltMixer", - "type": "string" - }, - { - "internalType": "contract ISystemConfig", - "name": "systemConfig", - "type": "address" - }, - { - "internalType": "contract IDelayedWETH", - "name": "delayedWETH", - "type": "address" - }, - { - "internalType": "GameType", - "name": "disputeGameType", - "type": "uint32" - }, - { - "internalType": "Claim", - "name": "disputeAbsolutePrestate", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "disputeMaxGameDepth", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "disputeSplitDepth", - "type": "uint256" - }, - { - "internalType": "Duration", - "name": "disputeClockExtension", - "type": "uint64" - }, - { - "internalType": "Duration", - "name": "disputeMaxClockDuration", - "type": "uint64" - }, - { - "internalType": "uint256", - "name": "initialBond", - "type": "uint256" - }, - { - "internalType": "contract IBigStepper", - "name": "vm", - "type": "address" - }, - { - "internalType": "bool", - "name": "permissioned", - "type": "bool" - } - ], - "internalType": "struct OPContractsManager.AddGameInput[]", - "name": "_gameConfigs", - "type": "tuple[]" - } - ], - "name": "addGameType", - "outputs": [ - { - "components": [ - { - "internalType": "contract IDelayedWETH", - "name": "delayedWETH", - "type": "address" - }, - { - "internalType": "contract IFaultDisputeGame", - "name": "faultDisputeGame", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.AddGameOutput[]", - "name": "", - "type": "tuple[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_who", - "type": "address" - } - ], - "name": "assertValidContractAddress", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "blueprints", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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": "struct OPContractsManager.Blueprints", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2ChainId", - "type": "uint256" - } - ], - "name": "chainIdToBatchInboxAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "contractsContainer", - "outputs": [ - { - "internalType": "contract OPContractsManagerContractsContainer", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "devFeatureBitmap", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "implementations", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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", - "name": "faultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "permissionedDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superFaultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superPermissionedDisputeGameImpl", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.Implementations", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_feature", - "type": "bytes32" - } - ], - "name": "isDevFeatureEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "systemConfigProxy", - "type": "address" - }, - { - "internalType": "Claim", - "name": "cannonPrestate", - "type": "bytes32" - }, - { - "internalType": "Claim", - "name": "cannonKonaPrestate", - "type": "bytes32" - } - ], - "internalType": "struct OPContractsManager.UpdatePrestateInput[]", - "name": "_prestateUpdateInputs", - "type": "tuple[]" - } - ], - "name": "updatePrestate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "l2ChainId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "GameType", - "name": "gameType", - "type": "uint32" - }, - { - "indexed": false, - "internalType": "contract IDisputeGame", - "name": "newDisputeGame", - "type": "address" - }, - { - "indexed": false, - "internalType": "contract IDisputeGame", - "name": "oldDisputeGame", - "type": "address" - } - ], - "name": "GameTypeAdded", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "who", - "type": "address" - } - ], - "name": "AddressHasNoCode", - "type": "error" - }, - { - "inputs": [], - "name": "BytesArrayTooLong", - "type": "error" - }, - { - "inputs": [], - "name": "DeploymentFailed", - "type": "error" - }, - { - "inputs": [], - "name": "EmptyInitcode", - "type": "error" - }, - { - "inputs": [], - "name": "IdentityPrecompileCallFailed", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidGameArgsLength", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidGameConfigs", - "type": "error" - }, - { - "inputs": [], - "name": "NotABlueprint", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManagerGameTypeAdder_MixedGameTypes", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManagerGameTypeAdder_UnsupportedGameType", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManager_InvalidGameType", - "type": "error" - }, - { - "inputs": [], - "name": "PrestateRequired", - "type": "error" - }, - { - "inputs": [], - "name": "ReservedBitsSet", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "UnexpectedPreambleData", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "UnsupportedERCVersion", - "type": "error" - } -] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInteropMigrator.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInteropMigrator.json deleted file mode 100644 index fcc2d4ad2f680..0000000000000 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerInteropMigrator.json +++ /dev/null @@ -1,424 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract OPContractsManagerContractsContainer", - "name": "_contractsContainer", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_who", - "type": "address" - } - ], - "name": "assertValidContractAddress", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "blueprints", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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": "struct OPContractsManager.Blueprints", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2ChainId", - "type": "uint256" - } - ], - "name": "chainIdToBatchInboxAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "contractsContainer", - "outputs": [ - { - "internalType": "contract OPContractsManagerContractsContainer", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "devFeatureBitmap", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "implementations", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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", - "name": "faultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "permissionedDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superFaultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superPermissionedDisputeGameImpl", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.Implementations", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_feature", - "type": "bytes32" - } - ], - "name": "isDevFeatureEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "usePermissionlessGame", - "type": "bool" - }, - { - "components": [ - { - "internalType": "Hash", - "name": "root", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "l2SequenceNumber", - "type": "uint256" - } - ], - "internalType": "struct Proposal", - "name": "startingAnchorRoot", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "proposer", - "type": "address" - }, - { - "internalType": "address", - "name": "challenger", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxGameDepth", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "splitDepth", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "initBond", - "type": "uint256" - }, - { - "internalType": "Duration", - "name": "clockExtension", - "type": "uint64" - }, - { - "internalType": "Duration", - "name": "maxClockDuration", - "type": "uint64" - } - ], - "internalType": "struct OPContractsManagerInteropMigrator.GameParameters", - "name": "gameParameters", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "systemConfigProxy", - "type": "address" - }, - { - "internalType": "Claim", - "name": "cannonPrestate", - "type": "bytes32" - }, - { - "internalType": "Claim", - "name": "cannonKonaPrestate", - "type": "bytes32" - } - ], - "internalType": "struct OPContractsManager.OpChainConfig[]", - "name": "opChainConfigs", - "type": "tuple[]" - } - ], - "internalType": "struct OPContractsManagerInteropMigrator.MigrateInput", - "name": "_input", - "type": "tuple" - } - ], - "name": "migrate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "who", - "type": "address" - } - ], - "name": "AddressHasNoCode", - "type": "error" - }, - { - "inputs": [], - "name": "BytesArrayTooLong", - "type": "error" - }, - { - "inputs": [], - "name": "DeploymentFailed", - "type": "error" - }, - { - "inputs": [], - "name": "EmptyInitcode", - "type": "error" - }, - { - "inputs": [], - "name": "IdentityPrecompileCallFailed", - "type": "error" - }, - { - "inputs": [], - "name": "NotABlueprint", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManagerInteropMigrator_AbsolutePrestateMismatch", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManagerInteropMigrator_ProxyAdminOwnerMismatch", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManagerInteropMigrator_SuperchainConfigMismatch", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManager_InvalidGameType", - "type": "error" - }, - { - "inputs": [], - "name": "PrestateNotSet", - "type": "error" - }, - { - "inputs": [], - "name": "ReservedBitsSet", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "UnexpectedPreambleData", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "UnsupportedERCVersion", - "type": "error" - } -] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUpgrader.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUpgrader.json deleted file mode 100644 index b232081b693d0..0000000000000 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerUpgrader.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract OPContractsManagerContractsContainer", - "name": "_contractsContainer", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_who", - "type": "address" - } - ], - "name": "assertValidContractAddress", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "blueprints", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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": "struct OPContractsManager.Blueprints", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2ChainId", - "type": "uint256" - } - ], - "name": "chainIdToBatchInboxAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "contractsContainer", - "outputs": [ - { - "internalType": "contract OPContractsManagerContractsContainer", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "devFeatureBitmap", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "implementations", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "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", - "name": "faultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "permissionedDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superFaultDisputeGameImpl", - "type": "address" - }, - { - "internalType": "address", - "name": "superPermissionedDisputeGameImpl", - "type": "address" - } - ], - "internalType": "struct OPContractsManager.Implementations", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_feature", - "type": "bytes32" - } - ], - "name": "isDevFeatureEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract ISystemConfig", - "name": "systemConfigProxy", - "type": "address" - }, - { - "internalType": "Claim", - "name": "cannonPrestate", - "type": "bytes32" - }, - { - "internalType": "Claim", - "name": "cannonKonaPrestate", - "type": "bytes32" - } - ], - "internalType": "struct OPContractsManager.OpChainConfig[]", - "name": "_opChainConfigs", - "type": "tuple[]" - } - ], - "name": "upgrade", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISuperchainConfig", - "name": "_superchainConfig", - "type": "address" - } - ], - "name": "upgradeSuperchainConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "l2ChainId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "contract ISystemConfig", - "name": "systemConfig", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "upgrader", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "who", - "type": "address" - } - ], - "name": "AddressHasNoCode", - "type": "error" - }, - { - "inputs": [], - "name": "BytesArrayTooLong", - "type": "error" - }, - { - "inputs": [], - "name": "DeploymentFailed", - "type": "error" - }, - { - "inputs": [], - "name": "EmptyInitcode", - "type": "error" - }, - { - "inputs": [], - "name": "IdentityPrecompileCallFailed", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidGameArgsLength", - "type": "error" - }, - { - "inputs": [], - "name": "NotABlueprint", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManagerUpgrader_SuperchainConfigAlreadyUpToDate", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManagerUpgrader_SuperchainConfigMismatch", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "OPContractsManagerUpgrader_SuperchainConfigNeedsUpgrade", - "type": "error" - }, - { - "inputs": [], - "name": "OPContractsManager_InvalidGameType", - "type": "error" - }, - { - "inputs": [], - "name": "PrestateNotSet", - "type": "error" - }, - { - "inputs": [], - "name": "ReservedBitsSet", - "type": "error" - }, - { - "inputs": [], - "name": "SemverComp_InvalidSemverParts", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "UnexpectedPreambleData", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "UnsupportedERCVersion", - "type": "error" - } -] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index fd36e74fa98d8..e0490008eb99c 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -23,10 +23,6 @@ "initCodeHash": "0x9367896a99f843fd56024e5f45a7b435a9fa8591cd4a37ffd529e8becf1b0305", "sourceCodeHash": "0x9d16e900a764cd7f19db3656cf7a9e555b23b9c7e018641ed21566657847a314" }, - "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0xd59648acb50002957cfd952a0cc14a4d6c2a2f6cd3a0f7d485e61f633d4873f3", - "sourceCodeHash": "0x6d4ffaaa57441dec3c3ee8fd9ac59f95229defec405347af853e265bfd749235" - }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { "initCodeHash": "0x233f5f4b424bc2aabe170cf758c9ff80841ceab4c78e37edfe3a7bc660c5577d", "sourceCodeHash": "0x7c0cb663f82b07da8dec8a7497cf2fa56a335fb5bdc57b612c86462f8527d4d5" diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManager.json b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManager.json deleted file mode 100644 index 0637a088a01e8..0000000000000 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManager.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerContractsContainer.json b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerContractsContainer.json deleted file mode 100644 index a6f0bb30b8c12..0000000000000 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerContractsContainer.json +++ /dev/null @@ -1,16 +0,0 @@ -[ - { - "bytes": "160", - "label": "blueprint", - "offset": 0, - "slot": "0", - "type": "struct OPContractsManager.Blueprints" - }, - { - "bytes": "576", - "label": "implementation", - "offset": 0, - "slot": "5", - "type": "struct OPContractsManager.Implementations" - } -] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerDeployer.json b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerDeployer.json deleted file mode 100644 index 0637a088a01e8..0000000000000 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerDeployer.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerGameTypeAdder.json b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerGameTypeAdder.json deleted file mode 100644 index 0637a088a01e8..0000000000000 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerGameTypeAdder.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerInteropMigrator.json b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerInteropMigrator.json deleted file mode 100644 index 0637a088a01e8..0000000000000 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerInteropMigrator.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerUpgrader.json b/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerUpgrader.json deleted file mode 100644 index 0637a088a01e8..0000000000000 --- a/packages/contracts-bedrock/snapshots/storageLayout/OPContractsManagerUpgrader.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol deleted file mode 100644 index e3e8f1b77b8e8..0000000000000 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ /dev/null @@ -1,2202 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Contracts -import { OPContractsManagerStandardValidator } from "src/L1/OPContractsManagerStandardValidator.sol"; - -// Libraries -import { Blueprint } from "src/libraries/Blueprint.sol"; -import { Constants } from "src/libraries/Constants.sol"; -import { Bytes } from "src/libraries/Bytes.sol"; -import { Claim, Duration, GameType, GameTypes, Proposal } from "src/dispute/lib/Types.sol"; -import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { SemverComp } from "src/libraries/SemverComp.sol"; -import { Features } from "src/libraries/Features.sol"; -import { DevFeatures } from "src/libraries/DevFeatures.sol"; -import { LibGameArgs } from "src/dispute/lib/LibGameArgs.sol"; - -// Interfaces -import { ISemver } from "interfaces/universal/ISemver.sol"; -import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; -import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; -import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; -import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; -import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; -import { IAddressManager } from "interfaces/legacy/IAddressManager.sol"; -import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; -import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; -import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol"; -import { ISuperFaultDisputeGame } from "interfaces/dispute/ISuperFaultDisputeGame.sol"; -import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; -import { IProtocolVersions } from "interfaces/L1/IProtocolVersions.sol"; -import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPortal2.sol"; -import { IOptimismPortalInterop } from "interfaces/L1/IOptimismPortalInterop.sol"; -import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol"; -import { IL1ERC721Bridge } from "interfaces/L1/IL1ERC721Bridge.sol"; -import { IL1StandardBridge } from "interfaces/L1/IL1StandardBridge.sol"; -import { IOptimismMintableERC20Factory } from "interfaces/universal/IOptimismMintableERC20Factory.sol"; -import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; -import { ISystemConfig } from "../../interfaces/L1/ISystemConfig.sol"; - -contract OPContractsManagerContractsContainer { - /// @notice Addresses of the Blueprint contracts. - /// This is internal because if public the autogenerated getter method would return a tuple of - /// addresses, but we want it to return a struct. - OPContractsManager.Blueprints internal blueprint; - - /// @notice Addresses of the latest implementation contracts. - OPContractsManager.Implementations internal implementation; - - /// @notice Bitmap of development features that are enabled. We keep the development feature - /// bitmap here rather than in the actual OPCM because other contracts always get a - /// reference to this but not to the OPCM itself. - bytes32 public immutable devFeatureBitmap; - - /// @notice Thrown when a development feature is enabled in production. - error OPContractsManagerContractsContainer_DevFeatureInProd(); - - /// @param _blueprints The blueprint contract addresses. - /// @param _implementations The implementation contract addresses. - /// @param _devFeatureBitmap The bitmap of development features that are enabled. - constructor( - OPContractsManager.Blueprints memory _blueprints, - OPContractsManager.Implementations memory _implementations, - bytes32 _devFeatureBitmap - ) { - blueprint = _blueprints; - implementation = _implementations; - devFeatureBitmap = _devFeatureBitmap; - - // Development features MUST NOT be enabled on Mainnet. - if (block.chainid == 1 && !_isTestingEnvironment() && uint256(_devFeatureBitmap) != 0) { - revert OPContractsManagerContractsContainer_DevFeatureInProd(); - } - } - - function blueprints() public view returns (OPContractsManager.Blueprints memory) { - return blueprint; - } - - function implementations() public view returns (OPContractsManager.Implementations memory) { - return implementation; - } - - /// @notice Returns the status of a development feature. Note that this function does not check - /// that the input feature represents a single feature and the bitwise AND operation - /// allows for multiple features to be enabled at once. Users should generally check - /// for only a single feature at a time. - /// @param _feature The feature to check. - /// @return True if the feature is enabled, false otherwise. - function isDevFeatureEnabled(bytes32 _feature) public view returns (bool) { - return DevFeatures.isDevFeatureEnabled(devFeatureBitmap, _feature); - } - - /// @notice Returns true if the contract is running in a testing environment. Checks that the - /// code for the address 0xbeefcafe is not zero, which is an address that should never - /// have any code in production environments but can be made to have code in tests. - /// @return True if the contract is running in a testing environment, false otherwise. - function _isTestingEnvironment() public view returns (bool) { - return address(0xbeefcafe).code.length > 0; - } -} - -abstract contract OPContractsManagerBase { - /// @notice Thrown when an invalid game type is used. - error OPContractsManager_InvalidGameType(); - - /// @notice The blueprint contract addresses contract. - OPContractsManagerContractsContainer public immutable contractsContainer; - - /// @notice The OPContractsManager contract that is currently being used. - OPContractsManagerBase internal immutable thisOPCM; - - /// @notice Constructor to initialize the immutable thisOPCM variable and contract addresses - /// @param _contractsContainer The blueprint contract addresses and implementation contract addresses - constructor(OPContractsManagerContractsContainer _contractsContainer) { - contractsContainer = _contractsContainer; - thisOPCM = this; - } - - /// @notice Retrieves the implementation addresses stored in this OPCM contract - function getImplementations() internal view returns (OPContractsManager.Implementations memory) { - return thisOPCM.implementations(); - } - - /// @notice Retrieves the blueprint addresses stored in this OPCM contract - function getBlueprints() internal view returns (OPContractsManager.Blueprints memory) { - return thisOPCM.blueprints(); - } - - /// @notice Retrieves the implementation addresses stored in this OPCM contract - function implementations() public view returns (OPContractsManager.Implementations memory) { - return contractsContainer.implementations(); - } - - /// @notice Retrieves the blueprint addresses stored in this OPCM contract - function blueprints() public view returns (OPContractsManager.Blueprints memory) { - return contractsContainer.blueprints(); - } - - /// @notice Retrieves the development feature bitmap stored in this OPCM contract - function devFeatureBitmap() public view returns (bytes32) { - return contractsContainer.devFeatureBitmap(); - } - - /// @notice Retrieves the status of a development feature. Note that this function does not check - /// that the input feature represents a single feature and the bitwise AND operation - /// allows for multiple features to be enabled at once. Users should generally check - /// for only a single feature at a time. - /// @param _feature The feature to check. - /// @return True if the feature is enabled, false otherwise. - function isDevFeatureEnabled(bytes32 _feature) public view returns (bool) { - return contractsContainer.isDevFeatureEnabled(_feature); - } - - /// @notice Maps an L2 chain ID to an L1 batch inbox address as defined by the standard - /// configuration's convention. This convention is `versionByte || keccak256(bytes32(chainId))[:19]`, - /// where || denotes concatenation`, versionByte is 0x00, and chainId is a uint256. - /// https://specs.optimism.io/protocol/configurability.html#consensus-parameters - function chainIdToBatchInboxAddress(uint256 _l2ChainId) public pure returns (address) { - bytes1 versionByte = 0x00; - bytes32 hashedChainId = keccak256(bytes.concat(bytes32(_l2ChainId))); - bytes19 first19Bytes = bytes19(hashedChainId); - return address(uint160(bytes20(bytes.concat(versionByte, first19Bytes)))); - } - - /// @notice Helper method for computing a salt that's used in CREATE2 deployments. - /// Including the contract name ensures that the resultant address from CREATE2 is unique - /// across our smart contract system. For example, we deploy multiple proxy contracts - /// with the same bytecode from this contract, so they each require a unique salt for determinism. - function computeSalt( - uint256 _l2ChainId, - string memory _saltMixer, - string memory _contractName - ) - internal - pure - returns (bytes32) - { - return keccak256(abi.encode(_l2ChainId, _saltMixer, _contractName)); - } - - /// @notice Helper method for computing a reusable salt mixer - /// This method should be used as the salt mixer when deploying contracts when there is no user - /// provided salt mixer. This protects against a situation where multiple chains with the same - /// L2 chain ID exist, which would otherwise result in address collisions. - /// @param _systemConfigProxy The SystemConfig contract found in the OpChainConfig of the chain being deployed to. - function reusableSaltMixer(ISystemConfig _systemConfigProxy) internal pure returns (string memory) { - return string(bytes.concat(bytes32(uint256(uint160(address(_systemConfigProxy)))))); - } - - /// @notice Deterministically deploys a new proxy contract owned by the provided ProxyAdmin. - /// The salt is computed as a function of the L2 chain ID, the salt mixer and the contract name. - /// This is required because we deploy many identical proxies, so they each require a unique salt for determinism. - function deployProxy( - uint256 _l2ChainId, - IProxyAdmin _proxyAdmin, - string memory _saltMixer, - string memory _contractName - ) - internal - returns (address) - { - bytes32 salt = computeSalt(_l2ChainId, _saltMixer, _contractName); - return Blueprint.deployFrom(getBlueprints().proxy, salt, abi.encode(_proxyAdmin)); - } - - /// @notice Makes an internal call to the target to initialize the proxy with the specified data. - /// First performs safety checks to ensure the target, implementation, and proxy admin are valid. - function upgradeToAndCall( - IProxyAdmin _proxyAdmin, - address _target, - address _implementation, - bytes memory _data - ) - internal - { - assertValidContractAddress(_implementation); - - _proxyAdmin.upgradeAndCall(payable(address(_target)), _implementation, _data); - } - - function assertValidContractAddress(address _who) public view { - if (_who.code.length == 0) revert OPContractsManager.AddressHasNoCode(_who); - } - - function encodePermissionlessSuperFDGConstructor(ISuperFaultDisputeGame.GameConstructorParams memory _params) - internal - view - virtual - returns (bytes memory) - { - bytes memory dataWithSelector = abi.encodeCall(ISuperFaultDisputeGame.__constructor__, (_params)); - return Bytes.slice(dataWithSelector, 4); - } - - /// @notice Returns the implementation contract address for a given game type. - function getGameImplementation( - IDisputeGameFactory _disputeGameFactory, - GameType _gameType - ) - internal - view - returns (IDisputeGame) - { - return _disputeGameFactory.gameImpls(_gameType); - } - - /// @notice Retrieves the Anchor State Registry for a given game - function getAnchorStateRegistry( - IDisputeGameFactory _disputeGameFactory, - IDisputeGame _disputeGame, - GameType _gameType - ) - internal - view - returns (IAnchorStateRegistry) - { - bytes memory gameArgsBytes = _disputeGameFactory.gameArgs(_gameType); - if (gameArgsBytes.length == 0) { - return IFaultDisputeGame(address(_disputeGame)).anchorStateRegistry(); - } else { - return IAnchorStateRegistry(LibGameArgs.decode(gameArgsBytes).anchorStateRegistry); - } - } - - /// @notice Retrieves the L2 chain ID for a given game - function getL2ChainId(IFaultDisputeGame _disputeGame) internal view returns (uint256) { - return _disputeGame.l2ChainId(); - } - - /// @notice Retrieves the proposer address for a given game - function getProposer( - IDisputeGameFactory _disputeGameFactory, - IDisputeGame _disputeGame, - GameType _gameType - ) - internal - view - returns (address) - { - bytes memory gameArgsBytes = _disputeGameFactory.gameArgs(_gameType); - if (gameArgsBytes.length == 0) { - return IPermissionedDisputeGame(address(_disputeGame)).proposer(); - } else { - return LibGameArgs.decode(gameArgsBytes).proposer; - } - } - - /// @notice Retrieves the challenger address of a given game - function getChallenger( - IDisputeGameFactory _disputeGameFactory, - IDisputeGame _disputeGame, - GameType _gameType - ) - internal - view - returns (address) - { - bytes memory gameArgsBytes = _disputeGameFactory.gameArgs(_gameType); - if (gameArgsBytes.length == 0) { - return IPermissionedDisputeGame(address(_disputeGame)).challenger(); - } else { - return LibGameArgs.decode(gameArgsBytes).challenger; - } - } - - /// @notice Helper function to register permissioned game V2 implementation - /// @dev Extracted to avoid stack too deep error - /// @param _input The deployment input data containing all necessary parameters - /// @param _implementation The implementation addresses struct - /// @param _output The deployment output containing proxy addresses - function _registerPermissionedGame( - OPContractsManager.DeployInput calldata _input, - OPContractsManager.Implementations memory _implementation, - OPContractsManager.DeployOutput memory _output - ) - internal - { - bytes memory gameArgs = abi.encodePacked( - _input.disputeAbsolutePrestate, // 32 bytes - _implementation.mipsImpl, // 20 bytes - address(_output.anchorStateRegistryProxy), // 20 bytes - address(_output.delayedWETHPermissionedGameProxy), // 20 bytes - _input.l2ChainId, // 32 bytes - _input.roles.proposer, // 20 bytes - _input.roles.challenger // 20 bytes - ); - setDGFImplementation( - _output.disputeGameFactoryProxy, - GameTypes.PERMISSIONED_CANNON, - IDisputeGame(_implementation.permissionedDisputeGameImpl), - gameArgs - ); - } - - /// @notice Retrieves the DisputeGameFactory address for a given SystemConfig - function getDisputeGameFactory(ISystemConfig _systemConfig) internal view returns (IDisputeGameFactory) { - return IDisputeGameFactory(_systemConfig.disputeGameFactory()); - } - - /// @notice Retrieves the AnchorStateRegistry address for a given SystemConfig - function getAnchorStateRegistry(ISystemConfig _systemConfig) internal view returns (IAnchorStateRegistry) { - return IAnchorStateRegistry(IOptimismPortal(payable(_systemConfig.optimismPortal())).anchorStateRegistry()); - } - - /// @notice Retrieves the DelayedWETH for a given game - function getWETH( - IDisputeGameFactory _disputeGameFactory, - IDisputeGame _disputeGame, - GameType _gameType - ) - internal - view - returns (IDelayedWETH) - { - bytes memory gameArgsBytes = _disputeGameFactory.gameArgs(_gameType); - if (gameArgsBytes.length == 0) { - return IFaultDisputeGame(address(_disputeGame)).weth(); - } else { - return IDelayedWETH(payable(LibGameArgs.decode(gameArgsBytes).weth)); - } - } - - /// @notice Retrieves the BigStepper VM for a given game - function getVM( - IDisputeGameFactory _disputeGameFactory, - IDisputeGame _disputeGame, - GameType _gameType - ) - internal - view - returns (IBigStepper) - { - bytes memory gameArgsBytes = _disputeGameFactory.gameArgs(_gameType); - if (gameArgsBytes.length == 0) { - return IFaultDisputeGame(address(_disputeGame)).vm(); - } else { - return IBigStepper(LibGameArgs.decode(gameArgsBytes).vm); - } - } - - /// @notice Sets a game implementation on the dispute game factory - /// @param _dgf The dispute game factory - /// @param _gameType The game type - /// @param _newGame The new game implementation - function setDGFImplementation(IDisputeGameFactory _dgf, GameType _gameType, IDisputeGame _newGame) internal { - _dgf.setImplementation(_gameType, _newGame); - } - - /// @notice Sets a game implementation on the dispute game factory - /// @param _dgf The dispute game factory - /// @param _gameType The game type - /// @param _newGame The new game implementation - /// @param _gameArgs Game arguments for this game type - function setDGFImplementation( - IDisputeGameFactory _dgf, - GameType _gameType, - IDisputeGame _newGame, - bytes memory _gameArgs - ) - internal - { - _dgf.setImplementation(_gameType, _newGame, _gameArgs); - } - - /// @notice Returns true iff the game type is CANNON or SUPER_CANNON - function isCannonGameVariant(GameType _gameType) internal pure returns (bool) { - return _gameType.raw() == GameTypes.CANNON.raw() || _gameType.raw() == GameTypes.SUPER_CANNON.raw(); - } - - /// @notice Returns true iff the game type is CANNON_KONA or SUPER_CANNON_KONA - function isKonaGameVariant(GameType _gameType) internal pure returns (bool) { - return _gameType.raw() == GameTypes.CANNON_KONA.raw() || _gameType.raw() == GameTypes.SUPER_CANNON_KONA.raw(); - } - - /// @notice Returns true iff the game type uses super roots - function isSuperGameVariant(GameType _gameType) internal pure returns (bool) { - return GameTypes.isSuperGame(_gameType); - } - - /// @notice Returns the dispute game implementation address in opcm for the specified game type - function getDisputeGameImplementation(GameType _gameType) internal view returns (address) { - if (_gameType.raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw()) { - return getImplementations().superPermissionedDisputeGameImpl; - } else if (_gameType.raw() == GameTypes.PERMISSIONED_CANNON.raw()) { - return getImplementations().permissionedDisputeGameImpl; - } else if ( - _gameType.raw() == GameTypes.SUPER_CANNON.raw() || _gameType.raw() == GameTypes.SUPER_CANNON_KONA.raw() - ) { - return getImplementations().superFaultDisputeGameImpl; - } else if (_gameType.raw() == GameTypes.CANNON.raw() || _gameType.raw() == GameTypes.CANNON_KONA.raw()) { - return getImplementations().faultDisputeGameImpl; - } else { - revert OPContractsManager_InvalidGameType(); - } - } -} - -contract OPContractsManagerGameTypeAdder is OPContractsManagerBase { - /// @notice Thrown when an unsupported game type is provided to the addGameType function. - error OPContractsManagerGameTypeAdder_UnsupportedGameType(); - - /// @notice Thrown when a mix of legacy and super games are found in updatePrestate. - error OPContractsManagerGameTypeAdder_MixedGameTypes(); - - /// @notice Emitted when a new game type is added to a chain - /// @param l2ChainId Chain ID of the chain - /// @param gameType Type of the game being - /// @param newDisputeGame Address of the deployed dispute game - /// @param oldDisputeGame Address of the old dispute game - event GameTypeAdded( - uint256 indexed l2ChainId, GameType indexed gameType, IDisputeGame newDisputeGame, IDisputeGame oldDisputeGame - ); - - /// @notice Constructor to initialize the immutable thisOPCM variable and contract addresses - /// @param _contractsContainer The blueprint contract addresses and implementation contract addresses - constructor(OPContractsManagerContractsContainer _contractsContainer) OPContractsManagerBase(_contractsContainer) { } - - /// @notice Deploys a new dispute game and installs it into the DisputeGameFactory. Inputted - /// game configs must be added in ascending GameType order. - /// @param _gameConfigs Game configs to add. - /// @return Array of results for the operations performed. - function addGameType(OPContractsManager.AddGameInput[] memory _gameConfigs) - public - virtual - returns (OPContractsManager.AddGameOutput[] memory) - { - // Ensure we have at least one game config to add. - if (_gameConfigs.length == 0) revert OPContractsManager.InvalidGameConfigs(); - - // We'll have one output per game config. - OPContractsManager.AddGameOutput[] memory outputs = new OPContractsManager.AddGameOutput[](_gameConfigs.length); - - // Store last game config as an int256 so that we can ensure that the same game config is - // not added twice. Using int256 generates cheaper, simpler bytecode. - int256 lastGameConfig = -1; - - // Loop through each game config and add the game type. - for (uint256 i = 0; i < _gameConfigs.length; i++) { - OPContractsManager.AddGameInput memory gameConfig = _gameConfigs[i]; - - // This conversion is safe because the GameType is a uint32, which will always fit in - // an int256. - int256 gameTypeInt = int256(uint256(gameConfig.disputeGameType.raw())); - - // Ensure that the game configs are added in ascending order, and not duplicated. - if (lastGameConfig >= gameTypeInt) revert OPContractsManager.InvalidGameConfigs(); - lastGameConfig = gameTypeInt; - - // Grab the L2 chain ID from the SystemConfig. - uint256 l2ChainId = gameConfig.systemConfig.l2ChainId(); - - // Deploy a new DelayedWETH proxy for this game if one hasn't already been specified. - // Leaving gameConfig.delayedWETH as the zero address will cause a new DelayedWETH to - // be deployed for this game. - if (address(gameConfig.delayedWETH) == address(0)) { - // Deploy the DelayedWETH proxy. We use the chain ID and the game type in the - // contract name to ensure that the contract is unique across chains. - outputs[i].delayedWETH = IDelayedWETH( - payable( - deployProxy( - l2ChainId, - gameConfig.systemConfig.proxyAdmin(), - gameConfig.saltMixer, - string.concat("DelayedWETH-", Strings.toString(uint256(gameTypeInt))) - ) - ) - ); - - // Initialize the proxy. - upgradeToAndCall( - gameConfig.systemConfig.proxyAdmin(), - address(outputs[i].delayedWETH), - getImplementations().delayedWETHImpl, - abi.encodeCall(IDelayedWETH.initialize, (gameConfig.systemConfig)) - ); - } else { - outputs[i].delayedWETH = gameConfig.delayedWETH; - } - - // Grab the DisputeGameFactory and AnchorStateRegistry for the chain. - IDisputeGameFactory dgf = getDisputeGameFactory(gameConfig.systemConfig); - - // Grab the existing game implementation from the DisputeGameFactory. - IFaultDisputeGame existingGame = - IFaultDisputeGame(address(getGameImplementation(dgf, gameConfig.disputeGameType))); - - if (isCannonGameVariant(gameConfig.disputeGameType) || isKonaGameVariant(gameConfig.disputeGameType)) { - address impl = getDisputeGameImplementation(gameConfig.disputeGameType); - bytes memory gameArgs = LibGameArgs.encode( - LibGameArgs.GameArgs({ - absolutePrestate: gameConfig.disputeAbsolutePrestate.raw(), - vm: address(gameConfig.vm), - anchorStateRegistry: address(getAnchorStateRegistry(ISystemConfig(gameConfig.systemConfig))), - weth: address(outputs[i].delayedWETH), - // must be zero for SUPER game types - l2ChainId: isSuperGameVariant(gameConfig.disputeGameType) ? 0 : l2ChainId, - proposer: address(0), - challenger: address(0) - }) - ); - - setDGFImplementation(dgf, gameConfig.disputeGameType, IDisputeGame(impl), gameArgs); - outputs[i].faultDisputeGame = IFaultDisputeGame(impl); - } else if ( - gameConfig.disputeGameType.raw() == GameTypes.PERMISSIONED_CANNON.raw() - || gameConfig.disputeGameType.raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw() - ) { - address impl = getDisputeGameImplementation(gameConfig.disputeGameType); - bytes memory gameArgs = LibGameArgs.encode( - LibGameArgs.GameArgs({ - absolutePrestate: gameConfig.disputeAbsolutePrestate.raw(), - vm: address(gameConfig.vm), - anchorStateRegistry: address(getAnchorStateRegistry(ISystemConfig(gameConfig.systemConfig))), - weth: address(outputs[i].delayedWETH), - l2ChainId: gameConfig.disputeGameType.raw() == GameTypes.PERMISSIONED_CANNON.raw() ? l2ChainId : 0, // must - // be zero for SUPER gam types - proposer: getProposer( - dgf, IPermissionedDisputeGame(address(existingGame)), gameConfig.disputeGameType - ), - challenger: getChallenger( - dgf, IPermissionedDisputeGame(address(existingGame)), gameConfig.disputeGameType - ) - }) - ); - setDGFImplementation(dgf, gameConfig.disputeGameType, IDisputeGame(impl), gameArgs); - outputs[i].faultDisputeGame = IFaultDisputeGame(payable(impl)); - } else { - revert OPContractsManagerGameTypeAdder_UnsupportedGameType(); - } - - dgf.setInitBond(gameConfig.disputeGameType, gameConfig.initialBond); - - // Emit event for the newly added game type with the new and old implementations. - emit GameTypeAdded( - l2ChainId, gameConfig.disputeGameType, outputs[i].faultDisputeGame, IDisputeGame(address(existingGame)) - ); - } - - return outputs; - } - - /// @notice Updates the prestate hash for all deployed dispute games while keeping all other game - /// parameters exactly the same. Currently requires deploying a new implementation - /// as there is no way to update the prestate on an existing implementation. - /// @param _prestateUpdateInputs The new prestate hash to use. - function updatePrestate(OPContractsManager.UpdatePrestateInput[] memory _prestateUpdateInputs) public { - // Loop through each chain and prestate hash - for (uint256 i = 0; i < _prestateUpdateInputs.length; i++) { - // Grab the DisputeGameFactory. - IDisputeGameFactory dgf = - IDisputeGameFactory(_prestateUpdateInputs[i].systemConfigProxy.disputeGameFactory()); - - // Create an array of all of the potential game types to update. - GameType[] memory gameTypes = new GameType[](6); - gameTypes[0] = GameTypes.CANNON; - gameTypes[1] = GameTypes.PERMISSIONED_CANNON; - gameTypes[2] = GameTypes.SUPER_CANNON; - gameTypes[3] = GameTypes.SUPER_PERMISSIONED_CANNON; - gameTypes[4] = GameTypes.CANNON_KONA; - gameTypes[5] = GameTypes.SUPER_CANNON_KONA; - - // Track if we have a legacy game, super game, or both. We will revert if this function - // is ever called with a mix of legacy and super games. Should never happen in - // production if you follow the standard upgrade process, but you never know. - bool hasLegacyGame = false; - bool hasSuperGame = false; - - // Iterate over each game type and update the prestate. - for (uint256 j = 0; j < gameTypes.length; j++) { - GameType gameType = gameTypes[j]; - - // Get the existing game implementation. - IFaultDisputeGame existingGame = IFaultDisputeGame(address(getGameImplementation(dgf, gameType))); - - // If no implementation exists, skip. - if (address(existingGame) == address(0)) { - continue; - } - - // Track the game types that we've seen so far. - if ( - gameType.raw() == GameTypes.SUPER_CANNON.raw() - || gameType.raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw() - || gameType.raw() == GameTypes.SUPER_CANNON_KONA.raw() - ) { - hasSuperGame = true; - } else { - hasLegacyGame = true; - } - - // If we have a mix of legacy and super games, revert. - if (hasLegacyGame && hasSuperGame) { - revert OPContractsManagerGameTypeAdder_MixedGameTypes(); - } - - // Select the prestate to use - Claim prestate = gameType.raw() == GameTypes.CANNON_KONA.raw() - || gameType.raw() == GameTypes.SUPER_CANNON_KONA.raw() - ? _prestateUpdateInputs[i].cannonKonaPrestate - : _prestateUpdateInputs[i].cannonPrestate; - - // Ensure that the prestate is not the zero hash. - if (Claim.unwrap(prestate) == bytes32(0)) { - revert OPContractsManager.PrestateRequired(); - } - - // Create a new game input with the updated prestate. - OPContractsManager.AddGameInput memory input = OPContractsManager.AddGameInput({ - disputeAbsolutePrestate: prestate, - saltMixer: reusableSaltMixer(_prestateUpdateInputs[i].systemConfigProxy), - systemConfig: _prestateUpdateInputs[i].systemConfigProxy, - delayedWETH: getWETH(dgf, existingGame, gameType), - disputeGameType: gameType, - disputeMaxGameDepth: existingGame.maxGameDepth(), - disputeSplitDepth: existingGame.splitDepth(), - disputeClockExtension: existingGame.clockExtension(), - disputeMaxClockDuration: existingGame.maxClockDuration(), - initialBond: dgf.initBonds(gameType), - vm: getVM(dgf, existingGame, gameType), - permissioned: gameType.raw() == GameTypes.PERMISSIONED_CANNON.raw() - || gameType.raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw() - }); - - // Add the new game type with updated prestate - OPContractsManager.AddGameInput[] memory inputs = new OPContractsManager.AddGameInput[](1); - inputs[0] = input; - addGameType(inputs); - } - } - } -} - -contract OPContractsManagerUpgrader is OPContractsManagerBase { - /// @notice Emitted when a chain is upgraded - /// @param systemConfig Address of the chain's SystemConfig contract - /// @param upgrader Address that initiated the upgrade - event Upgraded(uint256 indexed l2ChainId, ISystemConfig indexed systemConfig, address indexed upgrader); - - /// @notice Thrown when the SuperchainConfig contract does not match the unified config. - error OPContractsManagerUpgrader_SuperchainConfigMismatch(); - - /// @notice Thrown when upgrade is called with a chain whose superchainConfig is not upgraded. - error OPContractsManagerUpgrader_SuperchainConfigNeedsUpgrade(uint256 index); - - /// @notice Thrown when upgradeSuperchainConfig is called with a superchainConfig that is already up to date. - error OPContractsManagerUpgrader_SuperchainConfigAlreadyUpToDate(); - - /// @param _contractsContainer The OPContractsManagerContractsContainer to use. - constructor(OPContractsManagerContractsContainer _contractsContainer) OPContractsManagerBase(_contractsContainer) { } - - /// @notice Upgrades a set of chains to the latest implementation contracts - /// @param _opChainConfigs Array of OpChain structs, one per chain to upgrade - /// @dev This function is intended to be DELEGATECALLed by an address that is the common owner of every chain in - /// `_opChainConfigs`'s ProxyAdmin. - /// @dev This function requires that each chain's superchainConfig is already upgraded. - function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs) external virtual { - // Grab the implementations. - OPContractsManager.Implementations memory impls = getImplementations(); - - // Loop through each chain and upgrade. - for (uint256 i = 0; i < _opChainConfigs.length; i++) { - assertValidOpChainConfig(_opChainConfigs[i]); - uint256 l2ChainId = _opChainConfigs[i].systemConfigProxy.l2ChainId(); - - // Grab the SuperchainConfig. - ISuperchainConfig superchainConfig = _opChainConfigs[i].systemConfigProxy.superchainConfig(); - - // If the SuperchainConfig is not already upgraded, revert. - if (SemverComp.lt(superchainConfig.version(), ISuperchainConfig(impls.superchainConfigImpl).version())) { - revert OPContractsManagerUpgrader_SuperchainConfigNeedsUpgrade(i); - } - - // Do the chain upgrade. - // All of your updates should be done in this internal function unless you're making a - // change to how upgrades work in general. - _doChainUpgrade(impls, _opChainConfigs[i], l2ChainId); - - // Emit the upgraded event with the address of the caller. Since this will be a delegatecall, - // the caller will be the value of the ADDRESS opcode. - emit Upgraded(l2ChainId, _opChainConfigs[i].systemConfigProxy, address(this)); - } - } - - /// @notice Performs an upgrade for a specific chain. - /// @param _impls The implementations of the contracts. - /// @param _opChainConfig The configuration of the chain to upgrade. - /// @param _l2ChainId The L2 chain ID of the chain to upgrade. - function _doChainUpgrade( - OPContractsManager.Implementations memory _impls, - OPContractsManager.OpChainConfig memory _opChainConfig, - uint256 _l2ChainId - ) - internal - { - // Get the proxyAdmin from the systemConfig. - IProxyAdmin proxyAdmin = _opChainConfig.systemConfigProxy.proxyAdmin(); - - // Upgrade the SystemConfig first. - upgradeTo(proxyAdmin, address(_opChainConfig.systemConfigProxy), _impls.systemConfigImpl); - - // Grab the OptimismPortal contract. - IOptimismPortal optimismPortal = IOptimismPortal(payable(_opChainConfig.systemConfigProxy.optimismPortal())); - - // Upgrade the OptimismPortal contract. - if (isDevFeatureEnabled(DevFeatures.OPTIMISM_PORTAL_INTEROP)) { - // This does NOT run in production. - // Upgrade the OptimismPortal contract implementation. - upgradeTo(proxyAdmin, address(optimismPortal), _impls.optimismPortalInteropImpl); - - // If we don't already have an ETHLockbox, deploy and initialize it. - IETHLockbox ethLockbox = optimismPortal.ethLockbox(); - if (address(ethLockbox) == address(0)) { - // Deploy the ETHLockbox proxy. - ethLockbox = IETHLockbox( - deployProxy({ - _l2ChainId: _l2ChainId, - _proxyAdmin: proxyAdmin, - _saltMixer: reusableSaltMixer(_opChainConfig.systemConfigProxy), - _contractName: "ETHLockbox-U16a" - }) - ); - - // Initialize the ETHLockbox setting the OptimismPortal as an authorized portal. - IOptimismPortal[] memory portals = new IOptimismPortal[](1); - portals[0] = optimismPortal; - upgradeToAndCall( - proxyAdmin, - address(ethLockbox), - _impls.ethLockboxImpl, - abi.encodeCall(IETHLockbox.initialize, (_opChainConfig.systemConfigProxy, portals)) - ); - - // Migrate liquidity from the OptimismPortal to the ETHLockbox. - IOptimismPortalInterop(payable(optimismPortal)).migrateLiquidity(); - } - - // Use the existing AnchorStateRegistry reference. - IAnchorStateRegistry anchorStateRegistry = optimismPortal.anchorStateRegistry(); - - // Upgrade the OptimismPortal contract first so that the SystemConfig will have - // the SuperchainConfig reference required in the ETHLockbox. - IOptimismPortalInterop(payable(optimismPortal)).upgrade(anchorStateRegistry, ethLockbox); - } else { - // This runs in production. - upgradeTo(proxyAdmin, address(optimismPortal), _impls.optimismPortalImpl); - } - - // Upgrade the AnchorStateRegistry contract. No upgrade/initializer needed, just updating - // the implementation to latest. - upgradeTo(proxyAdmin, address(optimismPortal.anchorStateRegistry()), _impls.anchorStateRegistryImpl); - - // Upgrade the OptimismMintableERC20Factory contract. - upgradeTo( - proxyAdmin, - _opChainConfig.systemConfigProxy.optimismMintableERC20Factory(), - _impls.optimismMintableERC20FactoryImpl - ); - - // Use the SystemConfig to grab the DisputeGameFactory address. - IDisputeGameFactory dgf = IDisputeGameFactory(_opChainConfig.systemConfigProxy.disputeGameFactory()); - - // Need to upgrade the DisputeGameFactory implementation, no internal upgrade call. - upgradeTo(proxyAdmin, address(dgf), _impls.disputeGameFactoryImpl); - - // Separate context to avoid stack too deep. - { - // Grab chain addresses here. We need to do this after the SystemConfig upgrade or - // the addresses will be incorrect. - ISystemConfig.Addresses memory opChainAddrs = _opChainConfig.systemConfigProxy.getAddresses(); - - // Upgrade the L1CrossDomainMessenger contract. - upgradeTo( - proxyAdmin, - address(IL1CrossDomainMessenger(opChainAddrs.l1CrossDomainMessenger)), - _impls.l1CrossDomainMessengerImpl - ); - - // Upgrade the L1StandardBridge contract. - upgradeTo( - proxyAdmin, - address(IL1StandardBridge(payable(opChainAddrs.l1StandardBridge))), - _impls.l1StandardBridgeImpl - ); - - // Upgrade the L1ERC721Bridge contract. - upgradeTo(proxyAdmin, address(IL1ERC721Bridge(opChainAddrs.l1ERC721Bridge)), _impls.l1ERC721BridgeImpl); - } - - // All chains have the PermissionedDisputeGame, grab that. - IDisputeGame permissionedDisputeGame = getGameImplementation(dgf, GameTypes.PERMISSIONED_CANNON); - - setNewPermissionedGameImpl({ - _impls: _impls, - _l2ChainId: _l2ChainId, - _disputeGame: permissionedDisputeGame, - _newDelayedWeth: getWETH(dgf, permissionedDisputeGame, GameTypes.PERMISSIONED_CANNON), - _newAnchorStateRegistryProxy: getAnchorStateRegistry( - dgf, permissionedDisputeGame, GameTypes.PERMISSIONED_CANNON - ), - _opChainConfig: _opChainConfig - }); - - IDisputeGame permissionlessDisputeGame = getGameImplementation(dgf, GameTypes.CANNON); - - // If it exists, replace its implementation. - // We're reusing the same DelayedWETH and ASR contracts. - if (address(permissionlessDisputeGame) != address(0)) { - IDisputeGameFactory disputeGameFactory = - IDisputeGameFactory(_opChainConfig.systemConfigProxy.disputeGameFactory()); - Claim cannonPrestate = _opChainConfig.cannonPrestate.raw() != bytes32(0) - ? _opChainConfig.cannonPrestate - : getAbsolutePrestate(disputeGameFactory, address(permissionlessDisputeGame), GameTypes.CANNON); - setNewPermissionlessGameImpl({ - _impls: _impls, - _l2ChainId: _l2ChainId, - _newAbsolutePrestate: cannonPrestate, - _newDelayedWeth: getWETH(dgf, permissionlessDisputeGame, GameTypes.CANNON), - _newAnchorStateRegistryProxy: getAnchorStateRegistry(dgf, permissionlessDisputeGame, GameTypes.CANNON), - _gameType: GameTypes.CANNON, - _disputeGameFactory: disputeGameFactory - }); - - // Get the actual CANNON_KONA implementation to determine if it exists and to read its prestate - IDisputeGame cannonKonaGame = getGameImplementation(dgf, GameTypes.CANNON_KONA); - - // Only upgrade CANNON_KONA if prestate is explicitly provided OR if CANNON_KONA already exists. - // This avoids silently enabling CANNON_KONA with an unintended prestate. - if (_opChainConfig.cannonKonaPrestate.raw() != bytes32(0) || address(cannonKonaGame) != address(0)) { - Claim cannonKonaPrestate = _opChainConfig.cannonKonaPrestate.raw() != bytes32(0) - ? _opChainConfig.cannonKonaPrestate - : getAbsolutePrestate(disputeGameFactory, address(cannonKonaGame), GameTypes.CANNON_KONA); - setNewPermissionlessGameImpl({ - _impls: _impls, - _l2ChainId: _l2ChainId, - _newAbsolutePrestate: cannonKonaPrestate, - // CANNON and CANNON_KONA use the same weth and asr proxy addresses - _newDelayedWeth: getWETH(dgf, permissionlessDisputeGame, GameTypes.CANNON), - _newAnchorStateRegistryProxy: getAnchorStateRegistry(dgf, permissionlessDisputeGame, GameTypes.CANNON), - _gameType: GameTypes.CANNON_KONA, - _disputeGameFactory: disputeGameFactory - }); - uint256 initialCannonGameBond = disputeGameFactory.initBonds(GameTypes.CANNON); - disputeGameFactory.setInitBond(GameTypes.CANNON_KONA, initialCannonGameBond); - } - } - } - - /// @notice Upgrades the SuperchainConfig contract. - /// @param _superchainConfig The SuperchainConfig contract to upgrade. - /// @dev This function is intended to be DELEGATECALLed by the superchainConfig's ProxyAdminOwner. - /// @dev This function will revert if the SuperchainConfig is already at or above the target version. - function upgradeSuperchainConfig(ISuperchainConfig _superchainConfig) external { - // Only upgrade the superchainConfig if the current version is less than the target version. - if ( - SemverComp.gte( - _superchainConfig.version(), ISuperchainConfig(getImplementations().superchainConfigImpl).version() - ) - ) { - revert OPContractsManagerUpgrader_SuperchainConfigAlreadyUpToDate(); - } - - // Grab the implementations. - OPContractsManager.Implementations memory impls = getImplementations(); - // Grab the superchainConfig's proxyAdmin. - IProxyAdmin _superchainProxyAdmin = IProxyAdmin(_superchainConfig.proxyAdmin()); - - // Attempt to upgrade. If the ProxyAdmin is not the SuperchainConfig's admin, this will revert. - upgradeTo(_superchainProxyAdmin, address(_superchainConfig), impls.superchainConfigImpl); - } - - /// @notice Updates the implementation of a proxy without calling the initializer. - /// First performs safety checks to ensure the target, implementation, and proxy admin are valid. - function upgradeTo(IProxyAdmin _proxyAdmin, address _target, address _implementation) internal { - assertValidContractAddress(_implementation); - - _proxyAdmin.upgrade(payable(address(_target)), _implementation); - } - - /// @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)); - } - - /// @notice Sets the latest permissioned dispute game v2 implementation - /// @param _impls The container for the new dispute game implementations. - /// @param _l2ChainId The L2 chain ID - /// @param _disputeGame The current dispute game implementation in the dispute game factory - /// @param _newDelayedWeth The new delayed WETH implementation - /// @param _newAnchorStateRegistryProxy The new anchor state registry proxy - /// @param _opChainConfig The OP chain configuration - function setNewPermissionedGameImpl( - OPContractsManager.Implementations memory _impls, - uint256 _l2ChainId, - IDisputeGame _disputeGame, - IDelayedWETH _newDelayedWeth, - IAnchorStateRegistry _newAnchorStateRegistryProxy, - OPContractsManager.OpChainConfig memory _opChainConfig - ) - internal - { - IDisputeGameFactory disputeGameFactory = - IDisputeGameFactory(_opChainConfig.systemConfigProxy.disputeGameFactory()); - // If the prestate is set in the config, use it. If not set, we'll try to use the prestate - // that already exists on the current dispute game. - Claim absolutePrestate; - if (Claim.unwrap(_opChainConfig.cannonPrestate) == bytes32(0)) { - absolutePrestate = - getAbsolutePrestate(disputeGameFactory, address(_disputeGame), GameTypes.PERMISSIONED_CANNON); - } else { - absolutePrestate = _opChainConfig.cannonPrestate; - } - - // As a sanity check, if the prestate is zero here, revert. - if (absolutePrestate.raw() == bytes32(0)) { - revert OPContractsManager.PrestateNotSet(); - } - - IDisputeGame newGame = IDisputeGame(_impls.permissionedDisputeGameImpl); - bytes memory gameArgs = LibGameArgs.encode( - LibGameArgs.GameArgs({ - absolutePrestate: absolutePrestate.raw(), - vm: address(_impls.mipsImpl), - anchorStateRegistry: address(_newAnchorStateRegistryProxy), - weth: address(_newDelayedWeth), - l2ChainId: _l2ChainId, - proposer: getProposer( - disputeGameFactory, IPermissionedDisputeGame(address(_disputeGame)), GameTypes.PERMISSIONED_CANNON - ), - challenger: getChallenger( - disputeGameFactory, IPermissionedDisputeGame(address(_disputeGame)), GameTypes.PERMISSIONED_CANNON - ) - }) - ); - - setDGFImplementation(disputeGameFactory, GameTypes.PERMISSIONED_CANNON, IDisputeGame(newGame), gameArgs); - } - - /// @notice Sets the latest permissionless dispute game v2 implementations - /// @param _impls The container for the new dispute game implementations. - /// @param _l2ChainId The L2 chain ID - /// @param _newAbsolutePrestate The new absolute prestate for the dispute game - /// @param _newDelayedWeth The new delayed WETH implementation - /// @param _newAnchorStateRegistryProxy The new anchor state registry proxy - /// @param _disputeGameFactory The dispute game factory proxy - function setNewPermissionlessGameImpl( - OPContractsManager.Implementations memory _impls, - uint256 _l2ChainId, - Claim _newAbsolutePrestate, - IDelayedWETH _newDelayedWeth, - IAnchorStateRegistry _newAnchorStateRegistryProxy, - GameType _gameType, - IDisputeGameFactory _disputeGameFactory - ) - internal - { - // As a sanity check, if the prestate is zero here, revert. - if (_newAbsolutePrestate.raw() == bytes32(0)) { - revert OPContractsManager.PrestateNotSet(); - } - - IDisputeGame newGame = IDisputeGame(_impls.faultDisputeGameImpl); - bytes memory gameArgs = LibGameArgs.encode( - LibGameArgs.GameArgs({ - absolutePrestate: _newAbsolutePrestate.raw(), - vm: address(_impls.mipsImpl), - anchorStateRegistry: address(_newAnchorStateRegistryProxy), - weth: address(_newDelayedWeth), - l2ChainId: _l2ChainId, - proposer: address(0), - challenger: address(0) - }) - ); - setDGFImplementation(_disputeGameFactory, _gameType, IDisputeGame(newGame), gameArgs); - } - - /// @notice Retrieves the absolute prestate for a dispute game, handling both V1 and V2 games. - function getAbsolutePrestate( - IDisputeGameFactory _dgf, - address _disputeGame, - GameType _gameType - ) - internal - view - returns (Claim) - { - bytes memory gameArgsBytes = _dgf.gameArgs(_gameType); - if (gameArgsBytes.length == 0) { - // Game without CWIA args - read directly from contract - return IFaultDisputeGame(_disputeGame).absolutePrestate(); - } else { - // Game with CWIA args - decode from game args - LibGameArgs.GameArgs memory gameArgs = LibGameArgs.decode(gameArgsBytes); - return Claim.wrap(gameArgs.absolutePrestate); - } - } -} - -contract OPContractsManagerDeployer is OPContractsManagerBase { - /// @notice Emitted when a new OP Stack chain is deployed. - /// @param l2ChainId Chain ID of the new chain. - /// @param deployer Address that deployed the chain. - /// @param deployOutput ABI-encoded output of the deployment. - event Deployed(uint256 indexed l2ChainId, address indexed deployer, bytes deployOutput); - - constructor(OPContractsManagerContractsContainer _contractsContainer) OPContractsManagerBase(_contractsContainer) { } - - /// @notice Deploys a new OP Stack chain. - /// @param _input The deploy input parameters for the deployment. - /// @param _superchainConfig The superchain config for the chain. - /// @param _deployer The address to emit as the deployer address. - /// @return The deploy output values of the deployment. - function deploy( - OPContractsManager.DeployInput calldata _input, - ISuperchainConfig _superchainConfig, - address _deployer - ) - external - virtual - returns (OPContractsManager.DeployOutput memory) - { - assertValidInputs(_input); - OPContractsManager.DeployOutput memory output; - OPContractsManager.Blueprints memory blueprint = getBlueprints(); - OPContractsManager.Implementations memory implementation = getImplementations(); - - // -------- Deploy Chain Singletons -------- - - // The AddressManager is used to store the implementation for the L1CrossDomainMessenger - // due to it's usage of the legacy ResolvedDelegateProxy. - output.addressManager = IAddressManager( - Blueprint.deployFrom( - blueprint.addressManager, - computeSalt(_input.l2ChainId, _input.saltMixer, "AddressManager"), - abi.encode() - ) - ); - // The ProxyAdmin is the owner of all proxies for the chain. We temporarily set the owner to - // this contract, and then transfer ownership to the specified owner at the end of deployment. - output.opChainProxyAdmin = IProxyAdmin( - Blueprint.deployFrom( - blueprint.proxyAdmin, - computeSalt(_input.l2ChainId, _input.saltMixer, "ProxyAdmin"), - abi.encode(address(this)) - ) - ); - // Set the AddressManager on the ProxyAdmin. - output.opChainProxyAdmin.setAddressManager(output.addressManager); - // Transfer ownership of the AddressManager to the ProxyAdmin. - transferOwnership(address(output.addressManager), address(output.opChainProxyAdmin)); - - // -------- Deploy Proxy Contracts -------- - - // Deploy ERC-1967 proxied contracts. - output.l1ERC721BridgeProxy = - IL1ERC721Bridge(deployProxy(_input.l2ChainId, output.opChainProxyAdmin, _input.saltMixer, "L1ERC721Bridge")); - output.optimismPortalProxy = IOptimismPortal( - payable(deployProxy(_input.l2ChainId, output.opChainProxyAdmin, _input.saltMixer, "OptimismPortal")) - ); - output.ethLockboxProxy = - IETHLockbox(deployProxy(_input.l2ChainId, output.opChainProxyAdmin, _input.saltMixer, "ETHLockbox")); - output.systemConfigProxy = - ISystemConfig(deployProxy(_input.l2ChainId, output.opChainProxyAdmin, _input.saltMixer, "SystemConfig")); - output.optimismMintableERC20FactoryProxy = IOptimismMintableERC20Factory( - deployProxy(_input.l2ChainId, output.opChainProxyAdmin, _input.saltMixer, "OptimismMintableERC20Factory") - ); - output.disputeGameFactoryProxy = IDisputeGameFactory( - deployProxy(_input.l2ChainId, output.opChainProxyAdmin, _input.saltMixer, "DisputeGameFactory") - ); - output.anchorStateRegistryProxy = IAnchorStateRegistry( - deployProxy(_input.l2ChainId, output.opChainProxyAdmin, _input.saltMixer, "AnchorStateRegistry") - ); - - // Deploy legacy proxied contracts. - output.l1StandardBridgeProxy = IL1StandardBridge( - payable( - Blueprint.deployFrom( - blueprint.l1ChugSplashProxy, - computeSalt(_input.l2ChainId, _input.saltMixer, "L1StandardBridge"), - abi.encode(output.opChainProxyAdmin) - ) - ) - ); - output.opChainProxyAdmin.setProxyType(address(output.l1StandardBridgeProxy), IProxyAdmin.ProxyType.CHUGSPLASH); - string memory contractName = "OVM_L1CrossDomainMessenger"; - output.l1CrossDomainMessengerProxy = IL1CrossDomainMessenger( - Blueprint.deployFrom( - blueprint.resolvedDelegateProxy, - computeSalt(_input.l2ChainId, _input.saltMixer, "L1CrossDomainMessenger"), - abi.encode(output.addressManager, contractName) - ) - ); - output.opChainProxyAdmin.setProxyType( - address(output.l1CrossDomainMessengerProxy), IProxyAdmin.ProxyType.RESOLVED - ); - output.opChainProxyAdmin.setImplementationName(address(output.l1CrossDomainMessengerProxy), contractName); - - // Eventually we will switch from DelayedWETHPermissionedGameProxy to DelayedWETHPermissionlessGameProxy. - output.delayedWETHPermissionedGameProxy = IDelayedWETH( - payable( - deployProxy(_input.l2ChainId, output.opChainProxyAdmin, _input.saltMixer, "DelayedWETHPermissionedGame") - ) - ); - - // -------- Set and Initialize Proxy Implementations -------- - bytes memory data; - - data = encodeL1ERC721BridgeInitializer(output); - upgradeToAndCall( - output.opChainProxyAdmin, address(output.l1ERC721BridgeProxy), implementation.l1ERC721BridgeImpl, data - ); - - // Initialize the SystemConfig before the ETHLockbox, required because the ETHLockbox will - // try to get the SuperchainConfig from the SystemConfig inside of its initializer. Also - // need to initialize before OptimismPortal because OptimismPortal does some sanity checks - // based on the ETHLockbox feature flag. - data = encodeSystemConfigInitializer(_input, output, _superchainConfig); - upgradeToAndCall( - output.opChainProxyAdmin, address(output.systemConfigProxy), implementation.systemConfigImpl, data - ); - - // If the custom gas token feature was requested, enable the custom gas token feature in the SystemConfig - // contract. - if (_input.useCustomGasToken) { - output.systemConfigProxy.setFeature(Features.CUSTOM_GAS_TOKEN, true); - } - - // If the interop feature was requested, enable the ETHLockbox feature in the SystemConfig - // contract. Only other way to get the ETHLockbox feature as of u16a is to have already had - // the ETHLockbox in U16 and then upgrade to U16a. - if (isDevFeatureEnabled(DevFeatures.OPTIMISM_PORTAL_INTEROP)) { - output.systemConfigProxy.setFeature(Features.ETH_LOCKBOX, true); - } - - // Initialize the OptimismPortal. - if (isDevFeatureEnabled(DevFeatures.OPTIMISM_PORTAL_INTEROP)) { - data = encodeOptimismPortalInteropInitializer(output); - upgradeToAndCall( - output.opChainProxyAdmin, - address(output.optimismPortalProxy), - implementation.optimismPortalInteropImpl, - data - ); - } else { - data = encodeOptimismPortalInitializer(output); - upgradeToAndCall( - output.opChainProxyAdmin, address(output.optimismPortalProxy), implementation.optimismPortalImpl, data - ); - } - - // Initialize the ETHLockbox. - IOptimismPortal[] memory portals = new IOptimismPortal[](1); - portals[0] = output.optimismPortalProxy; - data = encodeETHLockboxInitializer(output, portals); - upgradeToAndCall(output.opChainProxyAdmin, address(output.ethLockboxProxy), implementation.ethLockboxImpl, data); - - data = encodeOptimismMintableERC20FactoryInitializer(output); - upgradeToAndCall( - output.opChainProxyAdmin, - address(output.optimismMintableERC20FactoryProxy), - implementation.optimismMintableERC20FactoryImpl, - data - ); - - data = encodeL1CrossDomainMessengerInitializer(output); - upgradeToAndCall( - output.opChainProxyAdmin, - address(output.l1CrossDomainMessengerProxy), - implementation.l1CrossDomainMessengerImpl, - data - ); - - data = encodeL1StandardBridgeInitializer(output); - upgradeToAndCall( - output.opChainProxyAdmin, address(output.l1StandardBridgeProxy), implementation.l1StandardBridgeImpl, data - ); - - // Eventually we will switch from DelayedWETHPermissionedGameProxy to DelayedWETHPermissionlessGameProxy. - data = encodeDelayedWETHInitializer(output); - upgradeToAndCall( - output.opChainProxyAdmin, - address(output.delayedWETHPermissionedGameProxy), - implementation.delayedWETHImpl, - data - ); - - // We set the initial owner to this contract, set game implementations, then transfer ownership. - data = encodeDisputeGameFactoryInitializer(); - upgradeToAndCall( - output.opChainProxyAdmin, - address(output.disputeGameFactoryProxy), - implementation.disputeGameFactoryImpl, - data - ); - // Extracted to helper function to avoid stack too deep error - _registerPermissionedGame(_input, implementation, output); - - transferOwnership(address(output.disputeGameFactoryProxy), address(_input.roles.opChainProxyAdminOwner)); - - data = encodeAnchorStateRegistryInitializer(_input, output); - upgradeToAndCall( - output.opChainProxyAdmin, - address(output.anchorStateRegistryProxy), - implementation.anchorStateRegistryImpl, - data - ); - - // -------- Finalize Deployment -------- - // Transfer ownership of the ProxyAdmin from this contract to the specified owner. - transferOwnership(address(output.opChainProxyAdmin), _input.roles.opChainProxyAdminOwner); - - emit Deployed(_input.l2ChainId, _deployer, abi.encode(output)); - return output; - } - - /// @notice Returns default, standard config arguments for the SystemConfig initializer. - /// This is used by subclasses to reduce code duplication. - function defaultSystemConfigParams( - OPContractsManager.DeployInput memory, /* _input */ - OPContractsManager.DeployOutput memory _output - ) - internal - view - virtual - returns (IResourceMetering.ResourceConfig memory resourceConfig_, ISystemConfig.Addresses memory opChainAddrs_) - { - resourceConfig_ = Constants.DEFAULT_RESOURCE_CONFIG(); - - opChainAddrs_ = ISystemConfig.Addresses({ - l1CrossDomainMessenger: address(_output.l1CrossDomainMessengerProxy), - l1ERC721Bridge: address(_output.l1ERC721BridgeProxy), - l1StandardBridge: address(_output.l1StandardBridgeProxy), - optimismPortal: address(_output.optimismPortalProxy), - optimismMintableERC20Factory: address(_output.optimismMintableERC20FactoryProxy), - delayedWETH: address(0), // Will be used in OPCMv2. - opcm: address(0) // Unsupported for V1. - }); - - assertValidContractAddress(opChainAddrs_.l1CrossDomainMessenger); - assertValidContractAddress(opChainAddrs_.l1ERC721Bridge); - assertValidContractAddress(opChainAddrs_.l1StandardBridge); - assertValidContractAddress(opChainAddrs_.optimismPortal); - assertValidContractAddress(opChainAddrs_.optimismMintableERC20Factory); - } - - // -------- Utilities -------- - - /// @notice Verifies that all inputs are valid and reverts if any are invalid. - /// Typically the proxy admin owner is expected to have code, but this is not enforced here. - function assertValidInputs(OPContractsManager.DeployInput calldata _input) internal view { - if (_input.l2ChainId == 0 || _input.l2ChainId == block.chainid) revert OPContractsManager.InvalidChainId(); - - if (_input.roles.opChainProxyAdminOwner == address(0)) { - revert OPContractsManager.InvalidRoleAddress("opChainProxyAdminOwner"); - } - if (_input.roles.systemConfigOwner == address(0)) { - revert OPContractsManager.InvalidRoleAddress("systemConfigOwner"); - } - if (_input.roles.batcher == address(0)) revert OPContractsManager.InvalidRoleAddress("batcher"); - if (_input.roles.unsafeBlockSigner == address(0)) { - revert OPContractsManager.InvalidRoleAddress("unsafeBlockSigner"); - } - if (_input.roles.proposer == address(0)) revert OPContractsManager.InvalidRoleAddress("proposer"); - if (_input.roles.challenger == address(0)) revert OPContractsManager.InvalidRoleAddress("challenger"); - - if (_input.startingAnchorRoot.length == 0) revert OPContractsManager.InvalidStartingAnchorRoot(); - if (bytes32(_input.startingAnchorRoot) == bytes32(0)) revert OPContractsManager.InvalidStartingAnchorRoot(); - } - - /// @notice Transfers ownership - function transferOwnership(address _target, address _newOwner) internal { - // All transferOwnership targets have the same selector, so we just use IAddressManager - IAddressManager(_target).transferOwnership(_newOwner); - } - - // -------- Initializer Encoding -------- - - /// @notice Helper method for encoding the L1ERC721Bridge initializer data. - function encodeL1ERC721BridgeInitializer(OPContractsManager.DeployOutput memory _output) - internal - view - virtual - returns (bytes memory) - { - return - abi.encodeCall(IL1ERC721Bridge.initialize, (_output.l1CrossDomainMessengerProxy, _output.systemConfigProxy)); - } - - /// @notice Helper method for encoding the OptimismPortal initializer data. - function encodeOptimismPortalInitializer(OPContractsManager.DeployOutput memory _output) - internal - view - virtual - returns (bytes memory) - { - return abi.encodeCall(IOptimismPortal.initialize, (_output.systemConfigProxy, _output.anchorStateRegistryProxy)); - } - - /// @notice Helper method for encoding the OptimismPortalInterop initializer data. - function encodeOptimismPortalInteropInitializer(OPContractsManager.DeployOutput memory _output) - internal - view - virtual - returns (bytes memory) - { - return abi.encodeCall( - IOptimismPortalInterop.initialize, - (_output.systemConfigProxy, _output.anchorStateRegistryProxy, _output.ethLockboxProxy) - ); - } - - /// @notice Helper method for encoding the ETHLockbox initializer data. - function encodeETHLockboxInitializer( - OPContractsManager.DeployOutput memory _output, - IOptimismPortal[] memory _portals - ) - internal - view - virtual - returns (bytes memory) - { - return abi.encodeCall(IETHLockbox.initialize, (_output.systemConfigProxy, _portals)); - } - - /// @notice Helper method for encoding the SystemConfig initializer data. - function encodeSystemConfigInitializer( - OPContractsManager.DeployInput memory _input, - OPContractsManager.DeployOutput memory _output, - ISuperchainConfig _superchainConfig - ) - internal - view - virtual - returns (bytes memory) - { - (IResourceMetering.ResourceConfig memory referenceResourceConfig, ISystemConfig.Addresses memory opChainAddrs) = - defaultSystemConfigParams(_input, _output); - - return systemConfigInitializerData(_input, _superchainConfig, referenceResourceConfig, opChainAddrs); - } - - /// @notice Helper method for encoding the call data for the SystemConfig initializer. - function systemConfigInitializerData( - OPContractsManager.DeployInput memory _input, - ISuperchainConfig _superchainConfig, - IResourceMetering.ResourceConfig memory _referenceResourceConfig, - ISystemConfig.Addresses memory _opChainAddrs - ) - internal - view - virtual - returns (bytes memory) - { - return abi.encodeCall( - ISystemConfig.initialize, - ( - _input.roles.systemConfigOwner, - _input.basefeeScalar, - _input.blobBasefeeScalar, - bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash - _input.gasLimit, - _input.roles.unsafeBlockSigner, - _referenceResourceConfig, - chainIdToBatchInboxAddress(_input.l2ChainId), - _opChainAddrs, - _input.l2ChainId, - _superchainConfig - ) - ); - } - - /// @notice Helper method for encoding the OptimismMintableERC20Factory initializer data. - function encodeOptimismMintableERC20FactoryInitializer(OPContractsManager.DeployOutput memory _output) - internal - pure - virtual - returns (bytes memory) - { - return abi.encodeCall(IOptimismMintableERC20Factory.initialize, (address(_output.l1StandardBridgeProxy))); - } - - /// @notice Helper method for encoding the L1CrossDomainMessenger initializer data. - function encodeL1CrossDomainMessengerInitializer(OPContractsManager.DeployOutput memory _output) - internal - view - virtual - returns (bytes memory) - { - return - abi.encodeCall(IL1CrossDomainMessenger.initialize, (_output.systemConfigProxy, _output.optimismPortalProxy)); - } - - /// @notice Helper method for encoding the L1StandardBridge initializer data. - function encodeL1StandardBridgeInitializer(OPContractsManager.DeployOutput memory _output) - internal - view - virtual - returns (bytes memory) - { - return abi.encodeCall( - IL1StandardBridge.initialize, (_output.l1CrossDomainMessengerProxy, _output.systemConfigProxy) - ); - } - - function encodeDisputeGameFactoryInitializer() internal view virtual returns (bytes memory) { - // This contract must be the initial owner so we can set game implementations, then - // ownership is transferred after. - return abi.encodeCall(IDisputeGameFactory.initialize, (address(this))); - } - - function encodeAnchorStateRegistryInitializer( - OPContractsManager.DeployInput memory _input, - OPContractsManager.DeployOutput memory _output - ) - internal - view - virtual - returns (bytes memory) - { - Proposal memory startingAnchorRoot = abi.decode(_input.startingAnchorRoot, (Proposal)); - return abi.encodeCall( - IAnchorStateRegistry.initialize, - ( - _output.systemConfigProxy, - _output.disputeGameFactoryProxy, - startingAnchorRoot, - GameTypes.PERMISSIONED_CANNON - ) - ); - } - - function encodeDelayedWETHInitializer(OPContractsManager.DeployOutput memory _output) - internal - view - virtual - returns (bytes memory) - { - return abi.encodeCall(IDelayedWETH.initialize, (_output.systemConfigProxy)); - } -} - -/// @title OPContractsManagerInteropMigrator -/// @notice This contract is used to migrate one or more OP Stack chains to use the Super Root dispute -/// games and shared dispute game contracts. -contract OPContractsManagerInteropMigrator is OPContractsManagerBase { - /// @notice Thrown when the ProxyAdmin owner of one or more of the provided OP Stack chains - /// being migrated does not match the ProxyAdmin owner of the first provided chain. - error OPContractsManagerInteropMigrator_ProxyAdminOwnerMismatch(); - - /// @notice Thrown when the SuperchainConfig of one or more of the provided OP Stack chains - /// being migrated does not match the SuperchainConfig of the first provided chain. - error OPContractsManagerInteropMigrator_SuperchainConfigMismatch(); - - /// @notice Thrown when the absolute prestate of one or more of the provided OP Stack chains - /// being migrated does not match the absolute prestate of the first provided chain. - error OPContractsManagerInteropMigrator_AbsolutePrestateMismatch(); - - /// @notice Parameters for creating the new Super Root dispute games that must be provided by - /// the caller. Other parameters are selected automatically. - struct GameParameters { - address proposer; - address challenger; - uint256 maxGameDepth; - uint256 splitDepth; - uint256 initBond; - Duration clockExtension; - Duration maxClockDuration; - } - - /// @notice Input parameters for the migration. - struct MigrateInput { - bool usePermissionlessGame; - Proposal startingAnchorRoot; - GameParameters gameParameters; - OPContractsManager.OpChainConfig[] opChainConfigs; - } - - /// @param _contractsContainer Container of blueprints and implementations. - constructor(OPContractsManagerContractsContainer _contractsContainer) OPContractsManagerBase(_contractsContainer) { } - - /// @notice Migrates one or more OP Stack chains to use the Super Root dispute games and shared - /// dispute game contracts. - /// @dev WARNING: This is a one-way operation. You cannot easily undo this operation without a - /// smart contract upgrade. Do not call this function unless you are 100% confident that - /// 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 prestates. - 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].systemConfigProxy.proxyAdmin().owner() != proxyAdmin.owner()) { - revert OPContractsManagerInteropMigrator_ProxyAdminOwnerMismatch(); - } - if (_input.opChainConfigs[i].cannonPrestate.raw() != _input.opChainConfigs[0].cannonPrestate.raw()) { - revert OPContractsManagerInteropMigrator_AbsolutePrestateMismatch(); - } - if (_input.opChainConfigs[i].cannonKonaPrestate.raw() != _input.opChainConfigs[0].cannonKonaPrestate.raw()) - { - revert OPContractsManagerInteropMigrator_AbsolutePrestateMismatch(); - } - } - - // Check that cannon prestate is non-empty - if (_input.opChainConfigs[0].cannonPrestate.raw() == bytes32(0)) { - revert OPContractsManager.PrestateNotSet(); - } - - // Grab an array of portals from the configs. - IOptimismPortalInterop[] memory portals = new IOptimismPortalInterop[](_input.opChainConfigs.length); - for (uint256 i = 0; i < _input.opChainConfigs.length; i++) { - portals[i] = IOptimismPortalInterop(payable(_input.opChainConfigs[i].systemConfigProxy.optimismPortal())); - } - - // Check that the portals have the same SuperchainConfig. - for (uint256 i = 0; i < portals.length; i++) { - if (portals[i].superchainConfig() != portals[0].superchainConfig()) { - revert OPContractsManagerInteropMigrator_SuperchainConfigMismatch(); - } - } - - // NOTE that here and in the rest of this function, we are using the first provided chain's - // 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 = proxyAdmin.owner(); - - // Deploy the new ETHLockbox. - // NOTE that here and in the rest of this function we use block.timestamp as a fake chain - // id for any new contracts that are deployed. The L2 chain id is not used for anything - // except the salt mixer, so making it the same as the block timestamp means that new - // contracts will be generated every time this function is called. This is totally fine for - // our purposes here, there's no strong need to have deterministic addresses ahead of time. - IETHLockbox newEthLockbox = IETHLockbox( - deployProxy({ - _l2ChainId: block.timestamp, - _proxyAdmin: proxyAdmin, - _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), - _contractName: "ETHLockbox-Interop" - }) - ); - - // Separate context to avoid stack too deep. - { - // Lockbox requires standard portal interfaces, need to cast to IOptimismPortal. - IOptimismPortal[] memory castedPortals; - assembly ("memory-safe") { - castedPortals := portals - } - - // Initialize the new ETHLockbox. - // Note that this authorizes the portals to use the ETHLockbox. - upgradeToAndCall( - proxyAdmin, - address(newEthLockbox), - getImplementations().ethLockboxImpl, - abi.encodeCall(IETHLockbox.initialize, (portals[0].systemConfig(), castedPortals)) - ); - } - - // Deploy the new DisputeGameFactory. - IDisputeGameFactory newDisputeGameFactory = IDisputeGameFactory( - deployProxy({ - _l2ChainId: block.timestamp, - _proxyAdmin: proxyAdmin, - _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), - _contractName: "DisputeGameFactory-Interop" - }) - ); - - // Initialize the new DisputeGameFactory. - upgradeToAndCall( - proxyAdmin, - address(newDisputeGameFactory), - getImplementations().disputeGameFactoryImpl, - abi.encodeCall(IDisputeGameFactory.initialize, (proxyAdminOwner)) - ); - - // Deploy the new AnchorStateRegistry. - IAnchorStateRegistry newAnchorStateRegistry = IAnchorStateRegistry( - deployProxy({ - _l2ChainId: block.timestamp, - _proxyAdmin: proxyAdmin, - _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), - _contractName: "AnchorStateRegistry-Interop" - }) - ); - - // Select the correct game type based on the input. - GameType newGameType; - if (_input.usePermissionlessGame) { - newGameType = GameTypes.SUPER_CANNON; - } else { - newGameType = GameTypes.SUPER_PERMISSIONED_CANNON; - } - - // We can use portals[0].systemConfig() as they are members of the same superchain cluster (shared lockbox) - // Initialize the new AnchorStateRegistry. - upgradeToAndCall( - proxyAdmin, - address(newAnchorStateRegistry), - getImplementations().anchorStateRegistryImpl, - abi.encodeCall( - IAnchorStateRegistry.initialize, - (portals[0].systemConfig(), newDisputeGameFactory, _input.startingAnchorRoot, newGameType) - ) - ); - - // Migrate each portal to the new ETHLockbox and AnchorStateRegistry. - for (uint256 i = 0; i < portals.length; i++) { - // Authorize the existing ETHLockboxes to use the new ETHLockbox. - IETHLockbox existingLockbox = IETHLockbox(payable(address(portals[i].ethLockbox()))); - newEthLockbox.authorizeLockbox(existingLockbox); - - // Migrate the existing ETHLockbox to the new ETHLockbox. - existingLockbox.migrateLiquidity(newEthLockbox); - - // Before migrating the portal, clear out any implementations that might exist in the - // old DisputeGameFactory proxy. We clear out all potential game types to be safe. - IDisputeGameFactory oldDisputeGameFactory = - IDisputeGameFactory(payable(address(portals[i].disputeGameFactory()))); - clearGameImplementation(oldDisputeGameFactory, GameTypes.CANNON); - clearGameImplementation(oldDisputeGameFactory, GameTypes.SUPER_CANNON); - clearGameImplementation(oldDisputeGameFactory, GameTypes.PERMISSIONED_CANNON); - clearGameImplementation(oldDisputeGameFactory, GameTypes.SUPER_PERMISSIONED_CANNON); - clearGameImplementation(oldDisputeGameFactory, GameTypes.CANNON_KONA); - clearGameImplementation(oldDisputeGameFactory, GameTypes.SUPER_CANNON_KONA); - - // Migrate the portal to the new ETHLockbox and AnchorStateRegistry. - portals[i].migrateToSuperRoots(newEthLockbox, newAnchorStateRegistry); - } - - // Separate context to avoid stack too deep. - { - // Deploy a new DelayedWETH proxy for the permissioned game. - IDelayedWETH newPermissionedDelayedWETHProxy = IDelayedWETH( - payable( - deployProxy({ - _l2ChainId: block.timestamp, - _proxyAdmin: proxyAdmin, - _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), - _contractName: "DelayedWETH-Interop-Permissioned" - }) - ) - ); - - // Initialize the new DelayedWETH proxy. - upgradeToAndCall( - proxyAdmin, - address(newPermissionedDelayedWETHProxy), - getImplementations().delayedWETHImpl, - abi.encodeCall(IDelayedWETH.initialize, (portals[0].systemConfig())) - ); - - // 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 - // dispute game contracts. Since these are Super dispute games and involve multiple - // chains, the contracts enforce that the chain id is zero. - bytes memory gameArgs = LibGameArgs.encode( - LibGameArgs.GameArgs({ - absolutePrestate: _input.opChainConfigs[0].cannonPrestate.raw(), - vm: address(getImplementations().mipsImpl), - anchorStateRegistry: address(newAnchorStateRegistry), - weth: address(newPermissionedDelayedWETHProxy), - l2ChainId: uint256(0), - proposer: _input.gameParameters.proposer, - challenger: _input.gameParameters.challenger - }) - ); - // Register the new SuperPermissionedDisputeGame. - newDisputeGameFactory.setImplementation( - GameTypes.SUPER_PERMISSIONED_CANNON, - IDisputeGame(implementations().superPermissionedDisputeGameImpl), - gameArgs - ); - newDisputeGameFactory.setInitBond(GameTypes.SUPER_PERMISSIONED_CANNON, _input.gameParameters.initBond); - } - - // If the permissionless game is being used, set that up too. - if (_input.usePermissionlessGame) { - // Deploy a new DelayedWETH proxy for the permissionless game. - IDelayedWETH newPermissionlessDelayedWETHProxy = IDelayedWETH( - payable( - deployProxy({ - _l2ChainId: block.timestamp, - _proxyAdmin: proxyAdmin, - _saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy), - _contractName: "DelayedWETH-Interop-Permissionless" - }) - ) - ); - - // Initialize the new DelayedWETH proxy. - upgradeToAndCall( - proxyAdmin, - address(newPermissionlessDelayedWETHProxy), - getImplementations().delayedWETHImpl, - abi.encodeCall(IDelayedWETH.initialize, (portals[0].systemConfig())) - ); - - // Register the new SuperFaultDisputeGame. - bytes memory gameArgs = LibGameArgs.encode( - LibGameArgs.GameArgs({ - absolutePrestate: _input.opChainConfigs[0].cannonPrestate.raw(), - vm: address(getImplementations().mipsImpl), - anchorStateRegistry: address(newAnchorStateRegistry), - weth: address(newPermissionlessDelayedWETHProxy), - l2ChainId: uint256(0), - proposer: address(0), - challenger: address(0) - }) - ); - newDisputeGameFactory.setImplementation( - GameTypes.SUPER_CANNON, IDisputeGame(implementations().superFaultDisputeGameImpl), gameArgs - ); - newDisputeGameFactory.setInitBond(GameTypes.SUPER_CANNON, _input.gameParameters.initBond); - - // If the cannon-kona game is being used, set that up too. - bytes32 cannonKonaPrestate = _input.opChainConfigs[0].cannonKonaPrestate.raw(); - if (cannonKonaPrestate != bytes32(0)) { - gameArgs = LibGameArgs.encode( - LibGameArgs.GameArgs({ - absolutePrestate: cannonKonaPrestate, - vm: address(getImplementations().mipsImpl), - anchorStateRegistry: address(newAnchorStateRegistry), - weth: address(newPermissionlessDelayedWETHProxy), - l2ChainId: uint256(0), - proposer: address(0), - challenger: address(0) - }) - ); - newDisputeGameFactory.setImplementation( - GameTypes.SUPER_CANNON_KONA, IDisputeGame(implementations().superFaultDisputeGameImpl), gameArgs - ); - newDisputeGameFactory.setInitBond(GameTypes.SUPER_CANNON_KONA, _input.gameParameters.initBond); - } - } - } - - function clearGameImplementation(IDisputeGameFactory _dgf, GameType _gameType) internal { - _dgf.setImplementation(_gameType, IDisputeGame(address(0)), hex""); - } -} - -contract OPContractsManager is ISemver { - // -------- Structs -------- - - /// @notice Represents the roles that can be set when deploying a standard OP Stack chain. - struct Roles { - address opChainProxyAdminOwner; - address systemConfigOwner; - address batcher; - address unsafeBlockSigner; - address proposer; - address challenger; - } - - /// @notice The full set of inputs to deploy a new OP Stack chain. - struct DeployInput { - Roles roles; - uint32 basefeeScalar; - uint32 blobBasefeeScalar; - uint256 l2ChainId; - // The correct type is Proposal memory but OP Deployer does not yet support structs. - bytes startingAnchorRoot; - // The salt mixer is used as part of making the resulting salt unique. - string saltMixer; - uint64 gasLimit; - // Configurable dispute game parameters. - GameType disputeGameType; - Claim disputeAbsolutePrestate; - uint256 disputeMaxGameDepth; - uint256 disputeSplitDepth; - Duration disputeClockExtension; - Duration disputeMaxClockDuration; - // Whether to use the custom gas token. - bool useCustomGasToken; - } - - /// @notice The full set of outputs from deploying a new OP Stack chain. - struct DeployOutput { - IProxyAdmin opChainProxyAdmin; - IAddressManager addressManager; - IL1ERC721Bridge l1ERC721BridgeProxy; - ISystemConfig systemConfigProxy; - IOptimismMintableERC20Factory optimismMintableERC20FactoryProxy; - IL1StandardBridge l1StandardBridgeProxy; - IL1CrossDomainMessenger l1CrossDomainMessengerProxy; - IETHLockbox ethLockboxProxy; - // Fault proof contracts below. - IOptimismPortal optimismPortalProxy; - IDisputeGameFactory disputeGameFactoryProxy; - IAnchorStateRegistry anchorStateRegistryProxy; - IFaultDisputeGame faultDisputeGame; - IPermissionedDisputeGame permissionedDisputeGame; - IDelayedWETH delayedWETHPermissionedGameProxy; - IDelayedWETH delayedWETHPermissionlessGameProxy; - } - - /// @notice Addresses of ERC-5202 Blueprint contracts. There are used for deploying full size - /// contracts, to reduce the code size of this factory contract. If it deployed full contracts - /// using the `new Proxy()` syntax, the code size would get large fast, since this contract would - /// contain the bytecode of every contract it deploys. Therefore we instead use Blueprints to - /// reduce the code size of this contract. - struct Blueprints { - address addressManager; - address proxy; - address proxyAdmin; - address l1ChugSplashProxy; - address resolvedDelegateProxy; - } - - /// @notice The latest implementation contracts for the OP Stack. - struct Implementations { - address superchainConfigImpl; - address protocolVersionsImpl; - address l1ERC721BridgeImpl; - address optimismPortalImpl; - address optimismPortalInteropImpl; - address ethLockboxImpl; - address systemConfigImpl; - address optimismMintableERC20FactoryImpl; - address l1CrossDomainMessengerImpl; - address l1StandardBridgeImpl; - address disputeGameFactoryImpl; - address anchorStateRegistryImpl; - address delayedWETHImpl; - address mipsImpl; - address faultDisputeGameImpl; - address permissionedDisputeGameImpl; - address superFaultDisputeGameImpl; - address superPermissionedDisputeGameImpl; - } - - /// @notice The input required to identify a chain for upgrading, along with new prestate hashes - struct OpChainConfig { - ISystemConfig systemConfigProxy; - Claim cannonPrestate; - Claim cannonKonaPrestate; - } - - /// @notice The input required to identify a chain for updating prestates - struct UpdatePrestateInput { - ISystemConfig systemConfigProxy; - Claim cannonPrestate; - Claim cannonKonaPrestate; - } - - struct AddGameInput { - string saltMixer; - ISystemConfig systemConfig; - 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; - } - - // -------- Constants and Variables -------- - - /// @dev This needs to stay at 6.x.x because the next release will ship OPCMv2. Since we are - /// not actually planning to release a 7.x.x of OPCMv1, it needs to stay at 6.x.x to avoid - /// errors in the versioning rules of OPCMv2. - /// @custom:semver 6.0.5 - function version() public pure virtual returns (string memory) { - return "6.0.5"; - } - - OPContractsManagerGameTypeAdder public immutable opcmGameTypeAdder; - - OPContractsManagerDeployer public immutable opcmDeployer; - - OPContractsManagerUpgrader public immutable opcmUpgrader; - - OPContractsManagerInteropMigrator public immutable opcmInteropMigrator; - - OPContractsManagerStandardValidator public immutable opcmStandardValidator; - - /// @notice Address of the SuperchainConfig contract shared by all chains. - ISuperchainConfig public immutable superchainConfig; - - /// @notice Address of the ProtocolVersions contract shared by all chains. - IProtocolVersions public immutable protocolVersions; - - /// @notice The OPContractsManager contract that is currently being used. This is needed in the upgrade function - /// which is intended to be DELEGATECALLed. - OPContractsManager internal immutable thisOPCM; - - // -------- Errors -------- - - /// @notice Thrown when an address is the zero address. - error AddressNotFound(address who); - - /// @notice Throw when a contract address has no code. - error AddressHasNoCode(address who); - - /// @notice Thrown when a release version is already set. - error AlreadyReleased(); - - /// @notice Thrown when an invalid `l2ChainId` is provided to `deploy`. - error InvalidChainId(); - - /// @notice Thrown when a role's address is not valid. - error InvalidRoleAddress(string role); - - /// @notice Thrown when the latest release is not set upon initialization. - error LatestReleaseNotSet(); - - /// @notice Thrown when the starting anchor root is not provided. - error InvalidStartingAnchorRoot(); - - /// @notice Thrown when certain methods are called outside of a DELEGATECALL. - error OnlyDelegatecall(); - - /// @notice Thrown when game configs passed to addGameType are invalid. - error InvalidGameConfigs(); - - /// @notice Thrown when the SuperchainConfig of the chain does not match the SuperchainConfig of this OPCM. - error SuperchainConfigMismatch(ISystemConfig systemConfig); - - /// @notice Thrown when the SuperchainProxyAdmin does not match the SuperchainConfig's admin. - error SuperchainProxyAdminMismatch(); - - /// @notice Thrown when a prestate is not set for a game. - error PrestateNotSet(); - - /// @notice Thrown when the prestate of a permissioned disputed game is 0. - error PrestateRequired(); - - /// @notice Thrown if logic gated by a dev feature flag is incorrectly accessed. - error InvalidDevFeatureAccess(bytes32 devFeature); - - /// @notice Thrown when OPCM v2 is enabled via dev feature flag. - error OPContractsManager_V2Enabled(); - - // -------- Methods -------- - - constructor( - OPContractsManagerGameTypeAdder _opcmGameTypeAdder, - OPContractsManagerDeployer _opcmDeployer, - OPContractsManagerUpgrader _opcmUpgrader, - OPContractsManagerInteropMigrator _opcmInteropMigrator, - OPContractsManagerStandardValidator _opcmStandardValidator, - ISuperchainConfig _superchainConfig, - IProtocolVersions _protocolVersions - ) { - _opcmDeployer.assertValidContractAddress(address(_superchainConfig)); - _opcmDeployer.assertValidContractAddress(address(_protocolVersions)); - _opcmDeployer.assertValidContractAddress(address(_opcmGameTypeAdder)); - _opcmDeployer.assertValidContractAddress(address(_opcmDeployer)); - _opcmDeployer.assertValidContractAddress(address(_opcmUpgrader)); - _opcmDeployer.assertValidContractAddress(address(_opcmInteropMigrator)); - _opcmDeployer.assertValidContractAddress(address(_opcmStandardValidator)); - opcmGameTypeAdder = _opcmGameTypeAdder; - opcmDeployer = _opcmDeployer; - opcmUpgrader = _opcmUpgrader; - opcmInteropMigrator = _opcmInteropMigrator; - opcmStandardValidator = _opcmStandardValidator; - superchainConfig = _superchainConfig; - protocolVersions = _protocolVersions; - thisOPCM = this; - } - - /// @notice Validates the configuration of the L1 contracts. - function validate( - OPContractsManagerStandardValidator.ValidationInput memory _input, - bool _allowFailure - ) - public - view - returns (string memory) - { - return opcmStandardValidator.validate(_input, _allowFailure); - } - - /// @notice Validates the configuration of the L1 contracts. - /// @notice Supports overrides of certain storage values denoted in the ValidationOverrides struct. - function validateWithOverrides( - OPContractsManagerStandardValidator.ValidationInput memory _input, - bool _allowFailure, - OPContractsManagerStandardValidator.ValidationOverrides memory _overrides - ) - public - view - returns (string memory) - { - return opcmStandardValidator.validateWithOverrides(_input, _allowFailure, _overrides); - } - - /// @notice Validates the configuration of the L1 contracts. - function validate( - OPContractsManagerStandardValidator.ValidationInputDev memory _input, - bool _allowFailure - ) - public - view - returns (string memory) - { - return opcmStandardValidator.validate(_input, _allowFailure); - } - - /// @notice Validates the configuration of the L1 contracts. - /// @notice Supports overrides of certain storage values denoted in the ValidationOverrides struct. - function validateWithOverrides( - OPContractsManagerStandardValidator.ValidationInputDev memory _input, - bool _allowFailure, - OPContractsManagerStandardValidator.ValidationOverrides memory _overrides - ) - public - view - returns (string memory) - { - return opcmStandardValidator.validateWithOverrides(_input, _allowFailure, _overrides); - } - - /// @notice Deploys a new OP Stack chain. - /// @param _input The deploy input parameters for the deployment. - /// @return The deploy output values of the deployment. - function deploy(DeployInput calldata _input) external virtual returns (DeployOutput memory) { - _assertV2NotEnabled(); - - return opcmDeployer.deploy(_input, superchainConfig, msg.sender); - } - - /// @notice Upgrades a set of chains to the latest implementation contracts - /// @param _opChainConfigs Array of OpChain structs, one per chain to upgrade - /// @dev This function is intended to be DELEGATECALLed by an address that is the common owner of every chain in - /// `_opChainConfigs`'s ProxyAdmin. - /// @dev This function requires that each chain's superchainConfig is already upgraded. - function upgrade(OpChainConfig[] memory _opChainConfigs) external virtual { - _assertV2NotEnabled(); - - if (address(this) == address(thisOPCM)) revert OnlyDelegatecall(); - - bytes memory data = abi.encodeCall(OPContractsManagerUpgrader.upgrade, (_opChainConfigs)); - _performDelegateCall(address(opcmUpgrader), data); - } - - /// @notice Upgrades the SuperchainConfig contract. - /// @param _superchainConfig The SuperchainConfig contract to upgrade. - /// @dev This function is intended to be DELEGATECALLed by the superchainConfig's ProxyAdminOwner. - /// @dev This function will revert if the SuperchainConfig is already at or above the target version. - function upgradeSuperchainConfig(ISuperchainConfig _superchainConfig) external { - _assertV2NotEnabled(); - - if (address(this) == address(thisOPCM)) revert OnlyDelegatecall(); - - bytes memory data = abi.encodeCall(OPContractsManagerUpgrader.upgradeSuperchainConfig, (_superchainConfig)); - _performDelegateCall(address(opcmUpgrader), data); - } - - /// @notice addGameType deploys a new dispute game and links it to the DisputeGameFactory. The inputted _gameConfigs - /// must be added in ascending GameType order. - function addGameType(AddGameInput[] memory _gameConfigs) public virtual returns (AddGameOutput[] memory) { - _assertV2NotEnabled(); - - if (address(this) == address(thisOPCM)) revert OnlyDelegatecall(); - - bytes memory data = abi.encodeCall(OPContractsManagerGameTypeAdder.addGameType, (_gameConfigs)); - - bytes memory returnData = _performDelegateCall(address(opcmGameTypeAdder), data); - return abi.decode(returnData, (AddGameOutput[])); - } - - /// @notice Updates the prestate hash for dispute games while keeping all other parameters the same - /// @param _prestateUpdateInputs The new prestate hashes to use - function updatePrestate(UpdatePrestateInput[] memory _prestateUpdateInputs) public { - _assertV2NotEnabled(); - - if (address(this) == address(thisOPCM)) revert OnlyDelegatecall(); - - bytes memory data = abi.encodeCall(OPContractsManagerGameTypeAdder.updatePrestate, (_prestateUpdateInputs)); - - _performDelegateCall(address(opcmGameTypeAdder), data); - } - - /// @notice Migrates the Optimism contracts to the latest version. - /// @param _input Input parameters for the migration. - function migrate(OPContractsManagerInteropMigrator.MigrateInput calldata _input) external virtual { - _assertV2NotEnabled(); - - if (address(this) == address(thisOPCM)) revert OnlyDelegatecall(); - - bytes memory data = abi.encodeCall(OPContractsManagerInteropMigrator.migrate, (_input)); - _performDelegateCall(address(opcmInteropMigrator), data); - } - - /// @notice Maps an L2 chain ID to an L1 batch inbox address as defined by the standard - /// configuration's convention. This convention is `versionByte || keccak256(bytes32(chainId))[:19]`, - /// where || denotes concatenation`, versionByte is 0x00, and chainId is a uint256. - /// https://specs.optimism.io/protocol/configurability.html#consensus-parameters - function chainIdToBatchInboxAddress(uint256 _l2ChainId) public view returns (address) { - return opcmDeployer.chainIdToBatchInboxAddress(_l2ChainId); - } - - /// @notice Returns the blueprint contract addresses. - function blueprints() public view returns (Blueprints memory) { - return opcmDeployer.blueprints(); - } - - /// @notice Returns the implementation contract addresses. - function implementations() public view returns (Implementations memory) { - return opcmDeployer.implementations(); - } - - /// @notice Retrieves the development feature bitmap stored in this OPCM contract - /// @return The development feature bitmap. - function devFeatureBitmap() public view returns (bytes32) { - return opcmDeployer.devFeatureBitmap(); - } - - /// @notice Returns the status of a development feature. Note that this function does not check - /// that the input feature represents a single feature and the bitwise AND operation - /// allows for multiple features to be enabled at once. Users should generally check - /// for only a single feature at a time. - /// @param _feature The feature to check. - /// @return True if the feature is enabled, false otherwise. - function isDevFeatureEnabled(bytes32 _feature) public view returns (bool) { - return opcmDeployer.isDevFeatureEnabled(_feature); - } - - /// @notice Reverts if the dev feature flag for OPCM v2 is enabled. - function _assertV2NotEnabled() internal view { - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - revert OPContractsManager_V2Enabled(); - } - } - - /// @notice Helper function to perform a delegatecall to a target contract - /// @param _target The target contract address - /// @param _data The calldata to send to the target - /// @return bytes The return data from the delegatecall - function _performDelegateCall(address _target, bytes memory _data) internal returns (bytes memory) { - // Perform the delegatecall - (bool success, bytes memory returnData) = _target.delegatecall(_data); - - // Check if the delegatecall was successful - if (!success) { - // If there was a revert message, bubble it up - assembly { - revert(add(returnData, 32), mload(returnData)) - } - } - - return returnData; - } -} diff --git a/packages/contracts-bedrock/src/libraries/Constants.sol b/packages/contracts-bedrock/src/libraries/Constants.sol index a3526f8ead5c6..da3e689f84059 100644 --- a/packages/contracts-bedrock/src/libraries/Constants.sol +++ b/packages/contracts-bedrock/src/libraries/Constants.sol @@ -54,9 +54,6 @@ library Constants { /// contracts to be deployed. Used for both initial deployments and migrations. bytes internal constant PERMIT_ALL_CONTRACTS_INSTRUCTION = bytes("ALL"); - /// @notice The minimum OPCM version considered to support OPCM v2. - string internal constant OPCM_V2_MIN_VERSION = "7.0.0"; - /// @notice Current bundle artifact path for Network Upgrade Transaction bundles. string internal constant CURRENT_BUNDLE_PATH = "snapshots/upgrades/current-upgrade-bundle.json"; diff --git a/packages/contracts-bedrock/src/libraries/DevFeatures.sol b/packages/contracts-bedrock/src/libraries/DevFeatures.sol index 8f4b0dd960c95..b91b29f7bda4a 100644 --- a/packages/contracts-bedrock/src/libraries/DevFeatures.sol +++ b/packages/contracts-bedrock/src/libraries/DevFeatures.sol @@ -23,9 +23,6 @@ library DevFeatures { bytes32 public constant DEPLOY_V2_DISPUTE_GAMES = bytes32(0x0000000000000000000000000000000000000000000000000000000000000100); - /// @notice The feature that enables the OPContractsManagerV2 contract. - bytes32 public constant OPCM_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000010000); - /// @notice The feature that enables L2CM. bytes32 public constant L2CM = bytes32(0x0000000000000000000000000000000000000000000000000000000000100000); diff --git a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol deleted file mode 100644 index 5cbaad95b4a64..0000000000000 --- a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol +++ /dev/null @@ -1,2417 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing -import { Test } from "test/setup/Test.sol"; -import { stdStorage, StdStorage } from "forge-std/StdStorage.sol"; -import { VmSafe } from "forge-std/Vm.sol"; -import { CommonTest } from "test/setup/CommonTest.sol"; -import { FeatureFlags } from "test/setup/FeatureFlags.sol"; -import { DeployOPChain_TestBase } from "test/opcm/DeployOPChain.t.sol"; - -// Scripts -import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; -import { Deploy } from "scripts/deploy/Deploy.s.sol"; -import { VerifyOPCM } from "scripts/deploy/VerifyOPCM.s.sol"; -import { DeployOPChain } from "scripts/deploy/DeployOPChain.s.sol"; -import { DisputeGames } from "test/setup/DisputeGames.sol"; -import { PastUpgrades } from "test/setup/PastUpgrades.sol"; - -// Libraries -import { Config } from "scripts/libraries/Config.sol"; -import { Types } from "scripts/libraries/Types.sol"; -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 { LibGameArgs } from "src/dispute/lib/LibGameArgs.sol"; -import { DevFeatures } from "src/libraries/DevFeatures.sol"; -import { Types as LibTypes } from "src/libraries/Types.sol"; -import { Encoding } from "src/libraries/Encoding.sol"; -import { Hashing } from "src/libraries/Hashing.sol"; -// Interfaces -import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; -import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; -import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; -import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; -import { IProtocolVersions } from "interfaces/L1/IProtocolVersions.sol"; - -import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; -import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; -import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; -import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { - IOPContractsManager, - IOPContractsManagerGameTypeAdder, - IOPContractsManagerInteropMigrator, - IOPContractsManagerUpgrader, - IOPContractsManagerStandardValidator -} from "interfaces/L1/IOPContractsManager.sol"; -import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; -import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; -import { ISuperFaultDisputeGame } from "interfaces/dispute/ISuperFaultDisputeGame.sol"; -import { ISuperPermissionedDisputeGame } from "interfaces/dispute/ISuperPermissionedDisputeGame.sol"; -import { IFaultDisputeGame } from "../../interfaces/dispute/IFaultDisputeGame.sol"; - -// Contracts -import { - OPContractsManager, - OPContractsManagerGameTypeAdder, - OPContractsManagerDeployer, - OPContractsManagerUpgrader, - OPContractsManagerContractsContainer, - OPContractsManagerInteropMigrator, - OPContractsManagerStandardValidator -} from "src/L1/OPContractsManager.sol"; -import { IPermissionedDisputeGame } from "../../interfaces/dispute/IPermissionedDisputeGame.sol"; -import { IProxy } from "../../interfaces/universal/IProxy.sol"; -import { IDelayedWETH } from "../../interfaces/dispute/IDelayedWETH.sol"; - -/// @title OPContractsManager_Harness -/// @notice Exposes internal functions for testing. -contract OPContractsManager_Harness is OPContractsManager { - constructor( - OPContractsManagerGameTypeAdder _opcmGameTypeAdder, - OPContractsManagerDeployer _opcmDeployer, - OPContractsManagerUpgrader _opcmUpgrader, - OPContractsManagerInteropMigrator _opcmInteropMigrator, - OPContractsManagerStandardValidator _opcmStandardValidator, - ISuperchainConfig _superchainConfig, - IProtocolVersions _protocolVersions - ) - OPContractsManager( - _opcmGameTypeAdder, - _opcmDeployer, - _opcmUpgrader, - _opcmInteropMigrator, - _opcmStandardValidator, - _superchainConfig, - _protocolVersions - ) - { } - - function chainIdToBatchInboxAddress_exposed(uint256 l2ChainId) public view returns (address) { - return super.chainIdToBatchInboxAddress(l2ChainId); - } -} - -/// @title OPContractsManager_Upgrade_Harness -/// @notice Exposes internal functions for testing. -contract OPContractsManager_Upgrade_Harness is CommonTest { - // The Upgraded event emitted by the Proxy contract. - event Upgraded(address indexed implementation); - - // The Upgraded event emitted by the OPContractsManager contract. - event Upgraded(uint256 indexed l2ChainId, ISystemConfig indexed systemConfig, address indexed upgrader); - - // The AddressSet event emitted by the AddressManager contract. - event AddressSet(string indexed name, address newAddress, address oldAddress); - - // The AdminChanged event emitted by the Proxy contract at init time or when the admin is - // changed. - event AdminChanged(address previousAdmin, address newAdmin); - - // The ImplementationSet event emitted by the DisputeGameFactory contract. - event ImplementationSet(address indexed impl, GameType indexed gameType); - - struct PreUpgradeState { - Claim cannonAbsolutePrestate; - Claim permissionedAbsolutePrestate; - Claim cannonKonaAbsolutePrestate; - IDelayedWETH permissionlessWethProxy; - IDelayedWETH permissionedCannonWethProxy; - } - - uint256 l2ChainId; - address upgrader; - IOPContractsManager.OpChainConfig[] opChainConfigs; - Claim cannonPrestate; - Claim cannonKonaPrestate; - string public opChain = Config.forkOpChain(); - PreUpgradeState preUpgradeState; - uint256 smokeTestNonce; // Counter to ensure unique l2BlockNumbers in smoke tests - - function setUp() public virtual override { - super.disableUpgradedFork(); - super.setUp(); - if (!isL1ForkTest()) { - // This test is only supported in forked tests, as we are testing the upgrade. - vm.skip(true); - } - - // All V1 upgrade tests can safely be skipped for V2. - skipIfDevFeatureEnabled(DevFeatures.OPCM_V2); - - skipIfOpsRepoTest( - "OPContractsManager_Upgrade_Harness: cannot test upgrade on superchain ops repo upgrade tests" - ); - - cannonPrestate = Claim.wrap(bytes32(keccak256("cannonPrestate"))); - cannonKonaPrestate = Claim.wrap(bytes32(keccak256("cannonKonaPrestate"))); - upgrader = proxyAdmin.owner(); - vm.label(upgrader, "ProxyAdmin Owner"); - - opChainConfigs.push( - IOPContractsManager.OpChainConfig({ - systemConfigProxy: systemConfig, - cannonPrestate: cannonPrestate, - cannonKonaPrestate: cannonKonaPrestate - }) - ); - - // Retrieve the l2ChainId, which was read from the superchain-registry, and saved in - // Artifacts encoded as an address. - l2ChainId = uint256(uint160(address(artifacts.mustGetAddress("L2ChainId")))); - - IDisputeGameFactory dgf = IDisputeGameFactory(address(artifacts.mustGetAddress("DisputeGameFactoryProxy"))); - - // Grab the pre-upgrade state. Use getGameImplPrestate to handle both v1 and v2 - // dispute games (v1 stores prestate on game impl, v2 stores it in gameArgs). - preUpgradeState = PreUpgradeState({ - cannonAbsolutePrestate: DisputeGames.getGameImplPrestate(dgf, GameTypes.CANNON), - permissionedAbsolutePrestate: DisputeGames.getGameImplPrestate(dgf, GameTypes.PERMISSIONED_CANNON), - cannonKonaAbsolutePrestate: DisputeGames.getGameImplPrestate(dgf, GameTypes.CANNON_KONA), - permissionlessWethProxy: DisputeGames.getGameImplDelayedWeth(dgf, GameTypes.CANNON), - permissionedCannonWethProxy: DisputeGames.getGameImplDelayedWeth(dgf, GameTypes.PERMISSIONED_CANNON) - }); - - // Since this superchainConfig is already at the expected reinitializer version... - // We do this to pass the reinitializer check when trying to upgrade the superchainConfig contract. - - // Get the value of the 0th storage slot of the superchainConfig contract. - bytes32 slot0 = vm.load(address(superchainConfig), bytes32(0)); - // Remove the value of initialized slot. - slot0 = slot0 & bytes32(~uint256(0xff)); - // Store 1 there. - slot0 = bytes32(uint256(slot0) + 1); - // Store the new value. - vm.store(address(superchainConfig), bytes32(0), slot0); - } - - /// @notice Helper function that runs an OPCM upgrade, asserts that the upgrade was successful, - /// asserts that it fits within a certain amount of gas, and runs the StandardValidator - /// over the result. - /// @param _opcm The OPCM contract to upgrade with. - /// @param _delegateCaller The address of the delegate caller to use for the upgrade. - /// @param _revertBytes The bytes of the revert to expect. - function _runOpcmUpgradeAndChecks( - IOPContractsManager _opcm, - address _delegateCaller, - bytes memory _revertBytes - ) - internal - { - // Grab some values before we upgrade, to be checked later - address initialChallenger = DisputeGames.permissionedGameChallenger(disputeGameFactory); - address initialProposer = DisputeGames.permissionedGameProposer(disputeGameFactory); - - // Always start by upgrading the SuperchainConfig contract. - address superchainPAO = IProxyAdmin(EIP1967Helper.getAdmin(address(superchainConfig))).owner(); - - // Execute the SuperchainConfig upgrade. - prankDelegateCall(superchainPAO); - (bool success, bytes memory reason) = - address(_opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig))); - if (success == false) { - // Only acceptable revert reason is the SuperchainConfig already being up to date. This - // try/catch is better than checking the version via the implementations struct because - // the implementations struct interface can change between OPCM versions which would - // cause the test to break and be a pain to resolve. - assertTrue( - bytes4(reason) - == IOPContractsManagerUpgrader.OPContractsManagerUpgrader_SuperchainConfigAlreadyUpToDate.selector, - "Revert reason other than SuperchainConfigAlreadyUpToDate" - ); - } - - // Expect the revert if one is specified. - if (_revertBytes.length > 0) { - vm.expectRevert(_revertBytes); - } - - // Execute the chain upgrade. - prankDelegateCall(_delegateCaller); - (bool upgradeSuccess,) = - address(_opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs))); - assertTrue(upgradeSuccess, "upgrade failed"); - - // Return early if a revert was expected. Otherwise we'll get errors below. - if (_revertBytes.length > 0) { - return; - } - - // Less than 90% of the gas target of 2**24 (EIP-7825) to account for the gas used by - // using Safe. - uint256 fusakaLimit = 2 ** 24; - VmSafe.Gas memory gas = vm.lastCallGas(); - assertLt(gas.gasTotalUsed, fusakaLimit * 9 / 10, "Upgrade exceeds gas target of 90% of 2**24 (EIP-7825)"); - - // We expect there to only be one chain config for these tests, you will have to rework - // this test if you add more. - assertEq(opChainConfigs.length, 1); - - // Coverage changes bytecode, so we get various errors. We can safely ignore the result of - // the standard validator in the coverage case, if the validator is failing in coverage - // then it will also fail in other CI tests (unless it's the expected issues, in which case - // we can safely skip). - if (vm.isContext(VmSafe.ForgeContext.Coverage)) { - return; - } - - // Create validationOverrides - IOPContractsManagerStandardValidator.ValidationOverrides memory validationOverrides = - IOPContractsManagerStandardValidator.ValidationOverrides({ - l1PAOMultisig: opChainConfigs[0].systemConfigProxy.proxyAdmin().owner(), - challenger: initialChallenger - }); - - // Grab the validator before we do the error assertion because otherwise the assertion will - // try to apply to this function call instead. - IOPContractsManagerStandardValidator validator = _opcm.opcmStandardValidator(); - - // Mock getProxyImplementation for DelayedWETH and ETHLockbox proxies when running - // with an unoptimized Foundry profile. See Setup.mockUnoptimizedProxyImplementations. - mockUnoptimizedProxyImplementations( - disputeGameFactory, - proxyAdmin, - address(optimismPortal2.ethLockbox()), - validator.delayedWETHImpl(), - validator.ethLockboxImpl() - ); - - // 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 - // the prestate from the actual contracts, but that doesn't actually give us any valuable - // checks. Easier to just expect the error in this case. - // We add the prefix of OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER because we use validationOverrides. - // Note: The expected error for CANNON_KONA depends on whether it was set up by past upgrades. - bool cannonKonaExists = address(disputeGameFactory.gameImpls(GameTypes.CANNON_KONA)) != address(0); - if (opChainConfigs[0].cannonPrestate.raw() == bytes32(0)) { - if (opChainConfigs[0].cannonKonaPrestate.raw() == bytes32(0)) { - if (cannonKonaExists) { - // CANNON_KONA was set up by past upgrades, validator checks it against zero prestate input - vm.expectRevert( - "OPContractsManagerStandardValidator: OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,PDDG-40,PLDG-40,CKDG-40" - ); - } else { - // CANNON_KONA doesn't exist - vm.expectRevert( - "OPContractsManagerStandardValidator: OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,PDDG-40,PLDG-40,CKDG-10" - ); - } - } else { - vm.expectRevert( - "OPContractsManagerStandardValidator: OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,PDDG-40,PLDG-40" - ); - } - } else if (opChainConfigs[0].cannonKonaPrestate.raw() == bytes32(0)) { - if (cannonKonaExists) { - vm.expectRevert( - "OPContractsManagerStandardValidator: OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,CKDG-40" - ); - } else { - vm.expectRevert( - "OPContractsManagerStandardValidator: OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,CKDG-10" - ); - } - } - - // Run the StandardValidator checks. - validator.validateWithOverrides( - IOPContractsManagerStandardValidator.ValidationInputDev({ - sysCfg: opChainConfigs[0].systemConfigProxy, - cannonPrestate: opChainConfigs[0].cannonPrestate.raw(), - cannonKonaPrestate: opChainConfigs[0].cannonKonaPrestate.raw(), - l2ChainID: l2ChainId, - proposer: initialProposer - }), - false, - validationOverrides - ); - _runPostUpgradeSmokeTests(_opcm, opChainConfigs[0], initialChallenger, initialProposer); - } - - /// @notice Runs some smoke tests after an upgrade - function _runPostUpgradeSmokeTests( - IOPContractsManager _opcm, - IOPContractsManager.OpChainConfig memory _opChainConfig, - address _challenger, - address _proposer - ) - internal - { - address expectedVm = address(_opcm.implementations().mipsImpl); - - Claim claim = Claim.wrap(bytes32(uint256(1))); - uint256 bondAmount = disputeGameFactory.initBonds(GameTypes.PERMISSIONED_CANNON); - vm.deal(address(_challenger), bondAmount); - (, uint256 rootBlockNumber) = optimismPortal2.anchorStateRegistry().getAnchorRoot(); - // Use nonce to ensure unique l2BlockNumber across multiple smoke test runs (e.g., runPastUpgrades + - // runCurrentUpgrade) - uint256 l2BlockNumber = rootBlockNumber + 1 + smokeTestNonce; - smokeTestNonce++; - - // Cannon Kona expected to be set if the cannon kona prestate is not zero AND the existing - // prestate for Cannon Kona is not - bool isCannonKonaSet = - DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON_KONA).raw() != bytes32(0); - - // Deploy live games and ensure they're configured correctly - GameType[] memory gameTypes = new GameType[](isCannonKonaSet ? 3 : 2); - gameTypes[0] = GameTypes.PERMISSIONED_CANNON; - gameTypes[1] = GameTypes.CANNON; - if (isCannonKonaSet) { - gameTypes[2] = GameTypes.CANNON_KONA; - } - for (uint256 i = 0; i < gameTypes.length; i++) { - GameType gt = gameTypes[i]; - - bytes32 expectedAbsolutePrestate = _opChainConfig.cannonPrestate.raw(); - if (expectedAbsolutePrestate == bytes32(0)) { - expectedAbsolutePrestate = preUpgradeState.permissionedAbsolutePrestate.raw(); - } - if (isCannonKonaSet && gt.raw() == GameTypes.CANNON_KONA.raw()) { - expectedAbsolutePrestate = _opChainConfig.cannonKonaPrestate.raw(); - if (expectedAbsolutePrestate == bytes32(0)) { - expectedAbsolutePrestate = preUpgradeState.cannonKonaAbsolutePrestate.raw(); - } - } - assertEq(bondAmount, disputeGameFactory.initBonds(gt)); - - vm.prank(_proposer, _proposer); - IPermissionedDisputeGame game = IPermissionedDisputeGame( - address(disputeGameFactory.create{ value: bondAmount }(gt, claim, abi.encode(l2BlockNumber))) - ); - (,,,, Claim rootClaim,,) = game.claimData(0); - - vm.assertEq(gt.raw(), game.gameType().raw()); - vm.assertEq(expectedAbsolutePrestate, game.absolutePrestate().raw()); - vm.assertEq(address(optimismPortal2.anchorStateRegistry()), address(game.anchorStateRegistry())); - vm.assertEq(l2ChainId, game.l2ChainId()); - vm.assertEq(302400, game.maxClockDuration().raw()); - vm.assertEq(10800, game.clockExtension().raw()); - vm.assertEq(73, game.maxGameDepth()); - vm.assertEq(30, game.splitDepth()); - vm.assertEq(l2BlockNumber, game.l2BlockNumber()); - vm.assertEq(expectedVm, address(game.vm())); - vm.assertEq(_proposer, game.gameCreator()); - vm.assertEq(claim.raw(), rootClaim.raw()); - vm.assertEq(blockhash(block.number - 1), game.l1Head().raw()); - - if (gt.raw() == GameTypes.PERMISSIONED_CANNON.raw()) { - vm.assertEq( - address(preUpgradeState.permissionedCannonWethProxy), - address(game.weth()), - "Incorrect permissioned WETH" - ); - vm.assertEq(_challenger, game.challenger()); - vm.assertEq(_proposer, game.proposer()); - } else { - vm.assertEq( - address(preUpgradeState.permissionlessWethProxy), - address(game.weth()), - "Incorrect permissionless WETH" - ); - } - } - - if (!isCannonKonaSet) { - assertEq(address(0), address(disputeGameFactory.gameImpls(GameTypes.CANNON_KONA))); - assertEq(0, disputeGameFactory.initBonds(GameTypes.CANNON_KONA)); - assertEq(0, disputeGameFactory.gameArgs(GameTypes.CANNON_KONA).length); - } - } - - /// @notice Executes all past upgrades that have not yet been executed on mainnet as of the - /// current simulation block defined in the justfile for this package. This function - /// might be empty if there are no previous upgrades to execute. You should remove - /// 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 { - PastUpgrades.runPastUpgrades(_delegateCaller, systemConfig, superchainConfig, disputeGameFactory); - } - - /// @notice Executes the current upgrade and checks the results. - /// @param _delegateCaller The address of the delegate caller to use for the upgrade. - function runCurrentUpgrade(address _delegateCaller) public { - _runOpcmUpgradeAndChecks(opcm, _delegateCaller, bytes("")); - } - - /// @notice Executes the current upgrade and expects reverts. - /// @param _delegateCaller The address of the delegate caller to use for the upgrade. - /// @param _revertBytes The bytes of the revert to expect. - function runCurrentUpgrade(address _delegateCaller, bytes memory _revertBytes) public { - _runOpcmUpgradeAndChecks(opcm, _delegateCaller, _revertBytes); - } -} - -/// @title OPContractsManager_TestInit -/// @notice Reusable test initialization for `OPContractsManager` tests. -abstract contract OPContractsManager_TestInit is CommonTest { - using DisputeGames for *; - - event GameTypeAdded( - uint256 indexed l2ChainId, GameType indexed gameType, IDisputeGame newDisputeGame, IDisputeGame oldDisputeGame - ); - - address proposer; - address challenger; - - uint256 chain1L2ChainId; - uint256 chain2L2ChainId; - - IOPContractsManager.DeployOutput internal chainDeployOutput1; - IOPContractsManager.DeployOutput internal chainDeployOutput2; - - function setUp() public virtual override { - super.setUp(); - - // TODO(#18332): Remove this once we support all existing OPCM functions. - skipIfDevFeatureEnabled(DevFeatures.OPCM_V2); - - proposer = address(this); - challenger = address(this); - chain1L2ChainId = 100; - chain2L2ChainId = 101; - - chainDeployOutput1 = createChainContracts(chain1L2ChainId); - chainDeployOutput2 = createChainContracts(chain2L2ChainId); - - vm.deal(address(chainDeployOutput1.ethLockboxProxy), 100 ether); - vm.deal(address(chainDeployOutput2.ethLockboxProxy), 100 ether); - } - - /// @notice Sets up the environment variables for the VerifyOPCM test. - function setupEnvVars() public { - vm.setEnv("EXPECTED_SUPERCHAIN_CONFIG", vm.toString(address(opcm.superchainConfig()))); - vm.setEnv("EXPECTED_PROTOCOL_VERSIONS", vm.toString(address(opcm.protocolVersions()))); - } - - /// @notice Helper function to deploy a new set of L1 contracts via OPCM. - /// @param _l2ChainId The L2 chain ID to deploy the contracts for. - /// @return The deployed contracts. - function createChainContracts(uint256 _l2ChainId) internal returns (IOPContractsManager.DeployOutput memory) { - return opcm.deploy( - IOPContractsManager.DeployInput({ - roles: IOPContractsManager.Roles({ - opChainProxyAdminOwner: address(this), - systemConfigOwner: address(this), - batcher: address(this), - unsafeBlockSigner: address(this), - proposer: proposer, - challenger: challenger - }), - basefeeScalar: 1, - blobBasefeeScalar: 1, - startingAnchorRoot: abi.encode( - Proposal({ - root: Hash.wrap(0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef), - l2SequenceNumber: 0 - }) - ), - l2ChainId: _l2ChainId, - saltMixer: "hello", - gasLimit: 30_000_000, - disputeGameType: GameType.wrap(1), - disputeAbsolutePrestate: Claim.wrap( - bytes32(hex"038512e02c4c3f7bdaec27d00edf55b7155e0905301e1a88083e4e0a6764d54c") - ), - disputeMaxGameDepth: 73, - disputeSplitDepth: 30, - disputeClockExtension: Duration.wrap(10800), - disputeMaxClockDuration: Duration.wrap(302400), - useCustomGasToken: false - }) - ); - } - - function addGameType(IOPContractsManager.AddGameInput memory input) - internal - returns (IOPContractsManager.AddGameOutput memory) - { - IOPContractsManager.AddGameInput[] memory inputs = new IOPContractsManager.AddGameInput[](1); - inputs[0] = input; - - uint256 l2ChainId = input.systemConfig.l2ChainId(); - - // Expect the GameTypeAdded event to be emitted. - vm.expectEmit(true, true, true, false, address(this)); - emit GameTypeAdded( - l2ChainId, input.disputeGameType, IDisputeGame(payable(address(0))), IDisputeGame(payable(address(0))) - ); - (bool success, bytes memory rawGameOut) = - address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.addGameType, (inputs))); - assertTrue(success, "addGameType failed"); - - IOPContractsManager.AddGameOutput[] memory addGameOutAll = - abi.decode(rawGameOut, (IOPContractsManager.AddGameOutput[])); - return addGameOutAll[0]; - } - - function newGameInputFactory(GameType _gameType) internal view returns (IOPContractsManager.AddGameInput memory) { - return IOPContractsManager.AddGameInput({ - saltMixer: "hello", - systemConfig: chainDeployOutput1.systemConfigProxy, - delayedWETH: IDelayedWETH(payable(address(0))), - disputeGameType: _gameType, - disputeAbsolutePrestate: Claim.wrap(bytes32(hex"deadbeef1234")), - disputeMaxGameDepth: 73, - disputeSplitDepth: 30, - disputeClockExtension: Duration.wrap(10800), - disputeMaxClockDuration: Duration.wrap(302400), - initialBond: 1 ether, - vm: IBigStepper(address(opcm.implementations().mipsImpl)), - permissioned: _gameType.raw() == GameTypes.PERMISSIONED_CANNON.raw() - || _gameType.raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw() - }); - } -} - -/// @title OPContractsManager_ChainIdToBatchInboxAddress_Test -/// @notice Tests the `chainIdToBatchInboxAddress` function of the `OPContractsManager` contract. -/// @dev These tests use the harness which exposes internal functions for testing. -contract OPContractsManager_ChainIdToBatchInboxAddress_Test is Test, FeatureFlags { - OPContractsManager_Harness opcmHarness; - address challenger = makeAddr("challenger"); - - function setUp() public { - ISuperchainConfig superchainConfigProxy = ISuperchainConfig(makeAddr("superchainConfig")); - IProtocolVersions protocolVersionsProxy = IProtocolVersions(makeAddr("protocolVersions")); - IProxyAdmin superchainProxyAdmin = IProxyAdmin(makeAddr("superchainProxyAdmin")); - OPContractsManager.Blueprints memory emptyBlueprints; - OPContractsManager.Implementations memory emptyImpls; - vm.etch(address(superchainConfigProxy), hex"01"); - vm.etch(address(protocolVersionsProxy), hex"01"); - - resolveFeaturesFromEnv(); - OPContractsManagerContractsContainer container = - new OPContractsManagerContractsContainer(emptyBlueprints, emptyImpls, devFeatureBitmap); - - OPContractsManager.Implementations memory __opcmImplementations = container.implementations(); - OPContractsManagerStandardValidator.Implementations memory opcmImplementations; - assembly { - opcmImplementations := __opcmImplementations - } - - opcmHarness = new OPContractsManager_Harness({ - _opcmGameTypeAdder: new OPContractsManagerGameTypeAdder(container), - _opcmDeployer: new OPContractsManagerDeployer(container), - _opcmUpgrader: new OPContractsManagerUpgrader(container), - _opcmInteropMigrator: new OPContractsManagerInteropMigrator(container), - _opcmStandardValidator: new OPContractsManagerStandardValidator( - opcmImplementations, superchainConfigProxy, address(superchainProxyAdmin), challenger, 100, bytes32(0) - ), - _superchainConfig: superchainConfigProxy, - _protocolVersions: protocolVersionsProxy - }); - } - - function test_calculatesBatchInboxAddress_succeeds() public view { - // These test vectors were calculated manually: - // 1. Compute the bytes32 encoding of the chainId: bytes32(uint256(chainId)); - // 2. Hash it and manually take the first 19 bytes, and prefixed it with 0x00. - uint256 chainId = 1234; - address expected = 0x0017FA14b0d73Aa6A26D6b8720c1c84b50984f5C; - address actual = opcmHarness.chainIdToBatchInboxAddress_exposed(chainId); - vm.assertEq(expected, actual); - - chainId = type(uint256).max; - expected = 0x00a9C584056064687E149968cBaB758a3376D22A; - actual = opcmHarness.chainIdToBatchInboxAddress_exposed(chainId); - vm.assertEq(expected, actual); - } -} - -/// @title OPContractsManager_AddGameType_Test -/// @notice Tests the `addGameType` function of the `OPContractsManager` contract. -contract OPContractsManager_AddGameType_Test is OPContractsManager_TestInit { - /// @notice Tests that we can add a PermissionedDisputeGame implementation with addGameType. - function test_addGameType_permissioned_succeeds() public { - // Create the input for the Permissioned game type. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.PERMISSIONED_CANNON); - - // Run the addGameType call. - IOPContractsManager.AddGameOutput memory output = addGameType(input); - IFaultDisputeGame newFDG = assertValidGameType(input, output); - - // Check the values on the new game type. - IPermissionedDisputeGame newPDG = IPermissionedDisputeGame(address(newFDG)); - - // Check the proposer and challenger values. - assertEq(newPDG.proposer(), proposer, "proposer mismatch"); - assertEq(newPDG.challenger(), challenger, "challenger mismatch"); - - // L2 chain ID call should not revert because this is not a Super game. - assertEq(newPDG.l2ChainId(), chain1L2ChainId, "l2ChainId should be set correctly"); - - // Get the v2 implementation address from OPCM - IOPContractsManager.Implementations memory impls = opcm.implementations(); - - // Verify v2 implementation is registered in DisputeGameFactory - address registeredImpl = - address(chainDeployOutput1.disputeGameFactoryProxy.gameImpls(GameTypes.PERMISSIONED_CANNON)); - - // Verify implementation address matches permissionedDisputeGameImpl - assertEq( - registeredImpl, - address(impls.permissionedDisputeGameImpl), - "DisputeGameFactory should have v2 PermissionedDisputeGame implementation registered" - ); - - // Verify that the returned fault dispute game is the v2 implementation - assertEq( - address(output.faultDisputeGame), - address(impls.permissionedDisputeGameImpl), - "addGameType should return v2 PermissionedDisputeGame implementation" - ); - } - - /// @notice Tests that we can add a FaultDisputeGame implementation with addGameType. - function test_addGameType_cannon_succeeds() public { - // Create the input for the Permissionless game type. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.CANNON); - - // Run the addGameType call. - IOPContractsManager.AddGameOutput memory output = addGameType(input); - IFaultDisputeGame newGame = assertValidGameType(input, output); - - // Check the values on the new game type. - IPermissionedDisputeGame notPDG = IPermissionedDisputeGame(address(newGame)); - - // Proposer call should revert because this is a permissionless game. - vm.expectRevert(); // nosemgrep: sol-safety-expectrevert-no-args - notPDG.proposer(); - - // L2 chain ID call should not revert because this is not a Super game. - assertEq(notPDG.l2ChainId(), chain1L2ChainId, "l2ChainId should be set correctly"); - - // Verify v2 implementation is registered in DisputeGameFactory - address registeredImpl = address(chainDeployOutput1.disputeGameFactoryProxy.gameImpls(input.disputeGameType)); - assertNotEq(registeredImpl, address(0), "Implementation should have been set"); - - // Get the v2 implementation address from OPCM - IOPContractsManager.Implementations memory impls = opcm.implementations(); - - // Verify implementation address matches permissionedDisputeGameImpl - assertEq( - registeredImpl, - address(impls.faultDisputeGameImpl), - "DisputeGameFactory should have v2 FaultDisputeGame implementation registered" - ); - - // Verify that the returned fault dispute game is the v2 implementation - assertEq( - address(output.faultDisputeGame), - address(impls.faultDisputeGameImpl), - "addGameType should return v2 FaultDisputeGame implementation" - ); - } - - /// @notice Tests that we can add a SuperPermissionedDisputeGame implementation with addGameType. - function test_addGameType_permissionedSuper_succeeds() public { - // The super game implementations are required for addGameType - skipIfDevFeatureDisabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); - - // Create the input for the Super game type. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.SUPER_PERMISSIONED_CANNON); - - // Since OPCM will start with the standard Permissioned (non-Super) game type we won't have - // a Super dispute game to grab the proposer and challenger from. In production we'd either - // already have a Super dispute game or we'd trigger the migration to make sure one exists. - // Here for simplicity we'll just mock it out so the values exist. - - // Mock the DisputeGameFactory to return the non-Super implementation, good enough, it'll - // have the right variables on it for the test to pass. We're basically just pretending - // that the non-Super game is a Super game for the sake of this test. - vm.mockCall( - address(chainDeployOutput1.disputeGameFactoryProxy), - abi.encodeCall(IDisputeGameFactory.gameImpls, (GameTypes.SUPER_PERMISSIONED_CANNON)), - abi.encode(chainDeployOutput1.permissionedDisputeGame) - ); - vm.mockCall( - address(chainDeployOutput1.permissionedDisputeGame), - abi.encodeCall(IDisputeGame.gameType, ()), - abi.encode(GameTypes.SUPER_PERMISSIONED_CANNON) - ); - // Mock the proposer and challenger calls to behave like SuperPermissionedDisputeGame - // When V2 contracts are used the permissioned game may be the V2 contract and not have proposer and challenger - // in the implementation contract. - vm.mockCall( - address(chainDeployOutput1.permissionedDisputeGame), - abi.encodeCall(IPermissionedDisputeGame.proposer, ()), - abi.encode(proposer) - ); - vm.mockCall( - address(chainDeployOutput1.permissionedDisputeGame), - abi.encodeCall(IPermissionedDisputeGame.challenger, ()), - abi.encode(challenger) - ); - - // Run the addGameType call. - IOPContractsManager.AddGameOutput memory output = addGameType(input); - vm.clearMockedCalls(); - IFaultDisputeGame newGame = assertValidGameType(input, output); - // Check the values on the new game type. - IPermissionedDisputeGame newPDG = IPermissionedDisputeGame(address(newGame)); - assertEq(newPDG.proposer(), proposer, "proposer mismatch"); - assertEq(newPDG.challenger(), challenger, "challenger mismatch"); - - // Super games don't have the l2ChainId function. - vm.expectRevert(); // nosemgrep: sol-safety-expectrevert-no-args - newPDG.l2ChainId(); - } - - /// @notice Tests that we can add a SuperFaultDisputeGame implementation with addGameType. - function test_addGameType_superCannon_succeeds() public { - // The super game implementations are required for addGameType - skipIfDevFeatureDisabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); - - // Create the input for the Super game type. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.SUPER_CANNON); - - // Run the addGameType call. - IOPContractsManager.AddGameOutput memory output = addGameType(input); - assertValidGameType(input, output); - - // Grab the new game type. - IPermissionedDisputeGame notPDG = IPermissionedDisputeGame(address(output.faultDisputeGame)); - - // Proposer should fail, this is a permissionless game. - vm.expectRevert(); // nosemgrep: sol-safety-expectrevert-no-args - notPDG.proposer(); - - // Super games don't have the l2ChainId function. - vm.expectRevert(); // nosemgrep: sol-safety-expectrevert-no-args - notPDG.l2ChainId(); - } - - /// @notice Tests that addGameType will revert if the game type is not supported. - function test_addGameType_unsupportedGameType_reverts() public { - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameType.wrap(2000)); - - // Run the addGameType call, should revert. - IOPContractsManager.AddGameInput[] memory inputs = new IOPContractsManager.AddGameInput[](1); - inputs[0] = input; - (bool success,) = address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.addGameType, (inputs))); - assertFalse(success, "addGameType should have failed"); - } - - function test_addGameType_reusedDelayedWETH_succeeds() public { - IDelayedWETH delayedWETH = IDelayedWETH( - DeployUtils.create1({ - _name: "Proxy", - _args: DeployUtils.encodeConstructor(abi.encodeCall(IProxy.__constructor__, (address(this)))) - }) - ); - IProxy(payable(address(delayedWETH))).upgradeToAndCall( - address(opcm.implementations().delayedWETHImpl), - abi.encodeCall(IDelayedWETH.initialize, (chainDeployOutput1.systemConfigProxy)) - ); - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.CANNON); - input.delayedWETH = delayedWETH; - IOPContractsManager.AddGameOutput memory output = addGameType(input); - assertValidGameType(input, output); - assertEq(address(output.delayedWETH), address(delayedWETH), "delayedWETH address mismatch"); - } - - function test_addGameType_outOfOrderInputs_reverts() public { - IOPContractsManager.AddGameInput memory input1 = newGameInputFactory(GameType.wrap(2)); - IOPContractsManager.AddGameInput memory input2 = newGameInputFactory(GameType.wrap(1)); - IOPContractsManager.AddGameInput[] memory inputs = new IOPContractsManager.AddGameInput[](2); - inputs[0] = input1; - inputs[1] = input2; - - // For the sake of completeness, we run the call again to validate the success behavior. - (bool success,) = address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.addGameType, (inputs))); - assertFalse(success, "addGameType should have failed"); - } - - function test_addGameType_duplicateGameType_reverts() public { - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.CANNON); - IOPContractsManager.AddGameInput[] memory inputs = new IOPContractsManager.AddGameInput[](2); - inputs[0] = input; - inputs[1] = input; - - // See test above for why we run the call twice. - (bool success, bytes memory revertData) = - address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.addGameType, (inputs))); - assertFalse(success, "addGameType should have failed"); - assertEq(bytes4(revertData), IOPContractsManager.InvalidGameConfigs.selector, "revertData mismatch"); - } - - function test_addGameType_zeroLengthInput_reverts() public { - IOPContractsManager.AddGameInput[] memory inputs = new IOPContractsManager.AddGameInput[](0); - - (bool success, bytes memory revertData) = - address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.addGameType, (inputs))); - assertFalse(success, "addGameType should have failed"); - assertEq(bytes4(revertData), IOPContractsManager.InvalidGameConfigs.selector, "revertData mismatch"); - } - - function test_addGameType_notDelegateCall_reverts() public { - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.PERMISSIONED_CANNON); - IOPContractsManager.AddGameInput[] memory inputs = new IOPContractsManager.AddGameInput[](1); - inputs[0] = input; - - vm.expectRevert(IOPContractsManager.OnlyDelegatecall.selector); - opcm.addGameType(inputs); - } - - function assertValidGameType( - IOPContractsManager.AddGameInput memory agi, - IOPContractsManager.AddGameOutput memory ago - ) - internal - returns (IFaultDisputeGame) - { - // Create a game so we can assert on game args which aren't baked into the implementation contract - Claim claim; - bytes memory extraData; - if (DisputeGames.isSuperGame(agi.disputeGameType)) { - LibTypes.OutputRootWithChainId[] memory outputRoots = new LibTypes.OutputRootWithChainId[](1); - outputRoots[0] = LibTypes.OutputRootWithChainId({ chainId: 100, root: keccak256(abi.encode(gasleft())) }); - LibTypes.SuperRootProof memory superRootProof; - superRootProof.version = bytes1(uint8(1)); - superRootProof.timestamp = uint64(123); - superRootProof.outputRoots = outputRoots; - extraData = Encoding.encodeSuperRootProof(superRootProof); - claim = Claim.wrap(Hashing.hashSuperRootProof(superRootProof)); - } else { - claim = Claim.wrap(bytes32(uint256(9876))); - extraData = abi.encode(uint256(123)); // l2BlockNumber - } - IFaultDisputeGame game = IFaultDisputeGame( - payable( - DisputeGames.createGame( - chainDeployOutput1.disputeGameFactoryProxy, agi.disputeGameType, proposer, claim, extraData - ) - ) - ); - - // Verify immutable fields on the game proxy - assertEq(game.gameType().raw(), agi.disputeGameType.raw(), "Game type should match"); - assertEq(game.clockExtension().raw(), agi.disputeClockExtension.raw(), "Clock extension should match"); - assertEq(game.maxClockDuration().raw(), agi.disputeMaxClockDuration.raw(), "Max clock duration should match"); - assertEq(game.splitDepth(), agi.disputeSplitDepth, "Split depth should match"); - assertEq(game.maxGameDepth(), agi.disputeMaxGameDepth, "Max game depth should match"); - assertEq(game.gameCreator(), proposer, "Game creator should match"); - assertEq(game.rootClaim().raw(), claim.raw(), "Claim should match"); - assertEq(game.l1Head().raw(), blockhash(block.number - 1), "L1 head should match"); - assertEq(game.l2SequenceNumber(), 123, "L2 sequence number should match"); - assertEq( - game.absolutePrestate().raw(), agi.disputeAbsolutePrestate.raw(), "Absolute prestate should match input" - ); - assertEq(address(game.vm()), address(agi.vm), "VM should match MIPS implementation"); - assertEq( - address(game.anchorStateRegistry()), - address(chainDeployOutput1.anchorStateRegistryProxy), - "ASR should match" - ); - assertEq(address(game.weth()), address(ago.delayedWETH), "WETH should match"); - - // Check the DGF - assertEq( - address(chainDeployOutput1.disputeGameFactoryProxy.gameImpls(agi.disputeGameType)), - address(ago.faultDisputeGame), - "gameImpl address mismatch" - ); - assertEq( - chainDeployOutput1.disputeGameFactoryProxy.initBonds(agi.disputeGameType), agi.initialBond, "bond mismatch" - ); - return game; - } - - /// @notice Tests that addGameType will revert if the game type is cannon-kona and the dev feature is not enabled - function test_addGameType_cannonKonaGameType_succeeds() public { - // Create the input for the cannon-kona game type. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.CANNON_KONA); - - // Run the addGameType call. - IOPContractsManager.AddGameOutput memory output = addGameType(input); - IFaultDisputeGame game = assertValidGameType(input, output); - - // Check the values on the new game type. - IPermissionedDisputeGame notPDG = IPermissionedDisputeGame(address(game)); - - // Proposer call should revert because this is a permissionless game. - vm.expectRevert(); // nosemgrep: sol-safety-expectrevert-no-args - notPDG.proposer(); - - // L2 chain ID call should not revert because this is not a Super game. - assertNotEq(notPDG.l2ChainId(), 0, "l2ChainId should not be zero"); - } - - /// @notice Tests that addGameType will revert if the game type is cannon-kona and the dev feature is not enabled - function test_addGameType_superCannonKonaGameType_succeeds() public { - skipIfDevFeatureDisabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); - // Create the input for the cannon-kona game type. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.SUPER_CANNON_KONA); - - // Run the addGameType call. - IOPContractsManager.AddGameOutput memory output = addGameType(input); - assertValidGameType(input, output); - - // Grab the new game type. - IPermissionedDisputeGame notPDG = IPermissionedDisputeGame(address(output.faultDisputeGame)); - - // Proposer should fail, this is a permissionless game. - vm.expectRevert(); // nosemgrep: sol-safety-expectrevert-no-args - notPDG.proposer(); - - // Super games don't have the l2ChainId function. - vm.expectRevert(); // nosemgrep: sol-safety-expectrevert-no-args - notPDG.l2ChainId(); - } -} - -/// @title OPContractsManager_UpdatePrestate_Test -/// @notice Tests the `updatePrestate` function of the `OPContractsManager` contract. -contract OPContractsManager_UpdatePrestate_Test is OPContractsManager_TestInit { - IOPContractsManager internal prestateUpdater; - OPContractsManager.AddGameInput[] internal gameInput; - - function setUp() public virtual override { - super.setUp(); - prestateUpdater = opcm; - } - - /// @notice Runs the OPCM updatePrestate function and checks the results. - /// @param _input The input to the OPCM updatePrestate function. - function _runUpdatePrestateAndChecks(IOPContractsManager.UpdatePrestateInput memory _input) internal { - _runUpdatePrestateAndChecks(_input, bytes("")); - } - - /// @notice Returns the game args of a v1 or v2 game. - function _getParsedGameArgs( - IDisputeGameFactory _dgf, - GameType _gameType - ) - internal - view - returns (LibGameArgs.GameArgs memory gameArgs_) - { - bytes memory args = _dgf.gameArgs(_gameType); - if (args.length == 0) { - IPermissionedDisputeGame game = IPermissionedDisputeGame(address(_dgf.gameImpls(_gameType))); - gameArgs_.absolutePrestate = game.absolutePrestate().raw(); - gameArgs_.vm = address(game.vm()); - gameArgs_.anchorStateRegistry = address(game.anchorStateRegistry()); - gameArgs_.weth = address(game.weth()); - gameArgs_.l2ChainId = game.l2ChainId(); - if ( - game.gameType().raw() == GameTypes.PERMISSIONED_CANNON.raw() - || game.gameType().raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw() - ) { - gameArgs_.proposer = game.proposer(); - gameArgs_.challenger = game.challenger(); - } - return gameArgs_; - } else { - return LibGameArgs.decode(args); - } - } - - function _assertGameArgsEqual( - LibGameArgs.GameArgs memory a, - LibGameArgs.GameArgs memory b, - bool _skipPrestateCheck - ) - internal - pure - { - if (!_skipPrestateCheck) { - assertEq(a.absolutePrestate, b.absolutePrestate, "absolutePrestate mismatch"); - } - assertEq(a.vm, b.vm, "vm mismatch"); - assertEq(a.anchorStateRegistry, b.anchorStateRegistry, "anchorStateRegistry mismatch"); - assertEq(a.weth, b.weth, "weth mismatch"); - assertEq(a.l2ChainId, b.l2ChainId, "l2ChainId mismatch"); - assertEq(a.proposer, b.proposer, "proposer mismatch"); - assertEq(a.challenger, b.challenger, "challenger mismatch"); - } - - /// @notice Runs the OPCM updatePrestate function and checks the results. - /// @param _input The input to the OPCM updatePrestate function. - /// @param _revertBytes The bytes of the revert to expect, if any. - function _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput memory _input, - bytes memory _revertBytes - ) - internal - { - bool expectCannonUpdated = address( - IDisputeGameFactory(chainDeployOutput1.systemConfigProxy.disputeGameFactory()).gameImpls(GameTypes.CANNON) - ) != address(0); - bool expectCannonKonaUpdated = address( - IDisputeGameFactory(chainDeployOutput1.systemConfigProxy.disputeGameFactory()).gameImpls( - GameTypes.CANNON_KONA - ) - ) != address(0); - - // Retrieve current game args before updatePrestate - IDisputeGameFactory dgf = IDisputeGameFactory(chainDeployOutput1.systemConfigProxy.disputeGameFactory()); - LibGameArgs.GameArgs memory pdgArgsBefore = _getParsedGameArgs(dgf, GameTypes.PERMISSIONED_CANNON); - LibGameArgs.GameArgs memory cannonArgsBefore; - LibGameArgs.GameArgs memory cannonKonaArgsBefore; - if (expectCannonUpdated) { - cannonArgsBefore = _getParsedGameArgs(dgf, GameTypes.CANNON); - } - if (expectCannonKonaUpdated) { - cannonKonaArgsBefore = _getParsedGameArgs(dgf, GameTypes.CANNON_KONA); - } - - IOPContractsManager.UpdatePrestateInput[] memory inputs = new IOPContractsManager.UpdatePrestateInput[](1); - inputs[0] = _input; - - // make the call to cache the proxy admin owner before setting expectRevert - address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner(); - if (_revertBytes.length > 0) { - vm.expectRevert(_revertBytes); - } - - // Trigger the updatePrestate function. - prankDelegateCall(proxyAdminOwner); - (bool success,) = - address(prestateUpdater).delegatecall(abi.encodeCall(IOPContractsManager.updatePrestate, (inputs))); - assertTrue(success, "updatePrestate failed"); - - // Return early if a revert was expected. Otherwise we'll get errors below. - if (_revertBytes.length > 0) { - return; - } - - LibGameArgs.GameArgs memory pdgArgsAfter = _getParsedGameArgs(dgf, GameTypes.PERMISSIONED_CANNON); - _assertGameArgsEqual(pdgArgsBefore, pdgArgsAfter, true); - assertEq(pdgArgsAfter.absolutePrestate, _input.cannonPrestate.raw(), "permissioned game prestate mismatch"); - // Ensure that the WETH contracts are not reverting - IDelayedWETH(payable(pdgArgsAfter.weth)).balanceOf(address(0)); - - if (expectCannonUpdated) { - LibGameArgs.GameArgs memory cannonArgsAfter = _getParsedGameArgs(dgf, GameTypes.CANNON); - _assertGameArgsEqual(cannonArgsBefore, cannonArgsAfter, true); - assertEq(cannonArgsAfter.absolutePrestate, _input.cannonPrestate.raw(), "cannon game prestate mismatch"); - // Ensure that the WETH contracts are not reverting - IDelayedWETH(payable(cannonArgsAfter.weth)).balanceOf(address(0)); - } else { - assertEq(address(dgf.gameImpls(GameTypes.CANNON)), (address(0)), "cannon game should not exist"); - } - - if (expectCannonKonaUpdated) { - LibGameArgs.GameArgs memory cannonKonaArgsAfter = _getParsedGameArgs(dgf, GameTypes.CANNON_KONA); - _assertGameArgsEqual(cannonKonaArgsBefore, cannonKonaArgsAfter, true); - assertEq( - cannonKonaArgsAfter.absolutePrestate, - _input.cannonKonaPrestate.raw(), - "cannon-kona game prestate mismatch" - ); - // Ensure that the WETH contracts are not reverting - IDelayedWETH(payable(cannonKonaArgsAfter.weth)).balanceOf(address(0)); - } else { - assertEq(address(dgf.gameImpls(GameTypes.CANNON_KONA)), (address(0)), "cannon_kona game should not exist"); - } - } - - /// @notice Mocks the existence of a previous SuperPermissionedDisputeGame so we can add a real - /// SuperPermissionedDisputeGame implementation by calling opcm.updatePrestate. - function _mockSuperPermissionedGame() internal { - vm.mockCall( - address(chainDeployOutput1.disputeGameFactoryProxy), - abi.encodeCall(IDisputeGameFactory.gameImpls, (GameTypes.SUPER_PERMISSIONED_CANNON)), - abi.encode(chainDeployOutput1.permissionedDisputeGame) - ); - vm.mockCall( - address(chainDeployOutput1.permissionedDisputeGame), - abi.encodeCall(IDisputeGame.gameType, ()), - abi.encode(GameTypes.SUPER_PERMISSIONED_CANNON) - ); - vm.mockCall( - address(chainDeployOutput1.permissionedDisputeGame), - abi.encodeCall(IPermissionedDisputeGame.proposer, ()), - abi.encode(proposer) - ); - vm.mockCall( - address(chainDeployOutput1.permissionedDisputeGame), - abi.encodeCall(IPermissionedDisputeGame.challenger, ()), - abi.encode(challenger) - ); - } - - /// @notice Tests that we can update the prestate when only the PermissionedDisputeGame exists. - function test_updatePrestate_pdgOnlyWithValidInput_succeeds() public { - Claim prestate = Claim.wrap(bytes32(hex"ABBA")); - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput( - chainDeployOutput1.systemConfigProxy, prestate, Claim.wrap(bytes32(0)) - ) - ); - } - - /// @notice Tests that we can update the prestate when both the PermissionedDisputeGame and - /// FaultDisputeGame exist. - function test_updatePrestate_bothGamesWithValidInput_succeeds() public { - // Add a FaultDisputeGame implementation via addGameType. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.CANNON); - addGameType(input); - - Claim prestate = Claim.wrap(bytes32(hex"ABBA")); - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput( - chainDeployOutput1.systemConfigProxy, prestate, Claim.wrap(bytes32(0)) - ) - ); - } - - /// @notice Tests that we can update the prestate when a SuperFaultDisputeGame exists. Note - /// that this test isn't ideal because the system starts with a PermissionedDisputeGame - /// and then adds a SuperPermissionedDisputeGame and SuperFaultDisputeGame. In the real - /// system we wouldn't have that PermissionedDisputeGame to start with, but it - /// shouldn't matter because the function is independent of other game types that - /// exist. - function test_updatePrestate_withSuperGame_succeeds() public { - skipIfDevFeatureDisabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); - - _mockSuperPermissionedGame(); - - // Add a SuperPermissionedDisputeGame implementation via addGameType. - IOPContractsManager.AddGameInput memory input1 = newGameInputFactory(GameTypes.SUPER_PERMISSIONED_CANNON); - addGameType(input1); - vm.clearMockedCalls(); - - // Add a SuperFaultDisputeGame implementation via addGameType. - IOPContractsManager.AddGameInput memory input2 = newGameInputFactory(GameTypes.SUPER_CANNON); - addGameType(input2); - - // Clear out the PermissionedDisputeGame implementation. - address owner = chainDeployOutput1.disputeGameFactoryProxy.owner(); - vm.prank(owner); - chainDeployOutput1.disputeGameFactoryProxy.setImplementation( - GameTypes.PERMISSIONED_CANNON, IDisputeGame(payable(address(0))) - ); - - // Create the input for the function call. - Claim prestate = Claim.wrap(bytes32(hex"ABBA")); - IOPContractsManager.UpdatePrestateInput[] memory inputs = new IOPContractsManager.UpdatePrestateInput[](1); - inputs[0] = IOPContractsManager.UpdatePrestateInput( - chainDeployOutput1.systemConfigProxy, prestate, Claim.wrap(bytes32(0)) - ); - - // Trigger the updatePrestate function. - address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner(); - prankDelegateCall(proxyAdminOwner); - (bool success,) = - address(prestateUpdater).delegatecall(abi.encodeCall(IOPContractsManager.updatePrestate, (inputs))); - assertTrue(success, "updatePrestate failed"); - - LibGameArgs.GameArgs memory permissionedGameArgs = LibGameArgs.decode( - IDisputeGameFactory(chainDeployOutput1.systemConfigProxy.disputeGameFactory()).gameArgs( - GameTypes.SUPER_PERMISSIONED_CANNON - ) - ); - LibGameArgs.GameArgs memory cannonGameArgs = LibGameArgs.decode( - IDisputeGameFactory(chainDeployOutput1.systemConfigProxy.disputeGameFactory()).gameArgs( - GameTypes.SUPER_CANNON - ) - ); - - // Check the prestate values. - assertEq(permissionedGameArgs.absolutePrestate, prestate.raw(), "pdg prestate mismatch"); - assertEq(cannonGameArgs.absolutePrestate, prestate.raw(), "fdg prestate mismatch"); - - // Ensure that the WETH contracts are not reverting - IDelayedWETH(payable(permissionedGameArgs.weth)).balanceOf(address(0)); - IDelayedWETH(payable(cannonGameArgs.weth)).balanceOf(address(0)); - } - - /// @notice Tests that the updatePrestate function will revert if the provided prestate is for - /// mixed game types (i.e. CANNON and SUPER_CANNON). - function test_updatePrestate_mixedGameTypes_reverts() public { - skipIfDevFeatureDisabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); - - // Add a SuperFaultDisputeGame implementation via addGameType. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.SUPER_CANNON); - addGameType(input); - - // nosemgrep: sol-style-use-abi-encodecall - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput({ - systemConfigProxy: chainDeployOutput1.systemConfigProxy, - cannonPrestate: Claim.wrap(bytes32(hex"ABBA")), - cannonKonaPrestate: Claim.wrap(bytes32(0)) - }), - abi.encodeWithSelector( - IOPContractsManagerGameTypeAdder.OPContractsManagerGameTypeAdder_MixedGameTypes.selector - ) - ); - } - - /// @notice Tests that the updatePrestate function will revert if the provided prestate is the - /// zero hash. - function test_updatePrestate_whenPDGPrestateIsZero_reverts() public { - // nosemgrep: sol-style-use-abi-encodecall - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput({ - systemConfigProxy: chainDeployOutput1.systemConfigProxy, - cannonPrestate: Claim.wrap(bytes32(0)), - cannonKonaPrestate: Claim.wrap(bytes32(0)) - }), - abi.encodeWithSelector(IOPContractsManager.PrestateRequired.selector) - ); - } - - function test_updatePrestate_whenOnlyCannonPrestateIsZeroAndCannonGameTypeDisabled_reverts() public { - // nosemgrep: sol-style-use-abi-encodecall - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput({ - systemConfigProxy: chainDeployOutput1.systemConfigProxy, - cannonPrestate: Claim.wrap(bytes32(0)), - cannonKonaPrestate: Claim.wrap(bytes32(hex"ABBA")) - }), - abi.encodeWithSelector(IOPContractsManager.PrestateRequired.selector) - ); - } - - /// @notice Tests that we can update the prestate for both CANNON and CANNON_KONA game types. - function test_updatePrestate_bothGamesAndCannonKonaWithValidInput_succeeds() public { - // Add a FaultDisputeGame implementation via addGameType. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.CANNON); - addGameType(input); - input = newGameInputFactory(GameTypes.CANNON_KONA); - addGameType(input); - - Claim cannonPrestate = Claim.wrap(bytes32(hex"ABBA")); - Claim cannonKonaPrestate = Claim.wrap(bytes32(hex"ADDA")); - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput({ - systemConfigProxy: chainDeployOutput1.systemConfigProxy, - cannonPrestate: cannonPrestate, - cannonKonaPrestate: cannonKonaPrestate - }) - ); - } - - function test_updatePrestate_cannonKonaWithSuperGame_succeeds() public { - skipIfDevFeatureDisabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); - - _mockSuperPermissionedGame(); - // Add a SuperPermissionedDisputeGame implementation via addGameType. - IOPContractsManager.AddGameInput memory input1 = newGameInputFactory(GameTypes.SUPER_PERMISSIONED_CANNON); - addGameType(input1); - vm.clearMockedCalls(); - - // Add a SuperFaultDisputeGame implementation via addGameType. - IOPContractsManager.AddGameInput memory input2 = newGameInputFactory(GameTypes.SUPER_CANNON); - addGameType(input2); - IOPContractsManager.AddGameInput memory input3 = newGameInputFactory(GameTypes.SUPER_CANNON_KONA); - addGameType(input3); - - // Clear out the PermissionedDisputeGame implementation. - address owner = chainDeployOutput1.disputeGameFactoryProxy.owner(); - vm.prank(owner); - chainDeployOutput1.disputeGameFactoryProxy.setImplementation( - GameTypes.PERMISSIONED_CANNON, IDisputeGame(payable(address(0))) - ); - - // Create the input for the function call. - Claim cannonPrestate = Claim.wrap(bytes32(hex"ABBA")); - Claim cannonKonaPrestate = Claim.wrap(bytes32(hex"ABBA")); - IOPContractsManager.UpdatePrestateInput[] memory inputs = new IOPContractsManager.UpdatePrestateInput[](1); - inputs[0] = IOPContractsManager.UpdatePrestateInput({ - systemConfigProxy: chainDeployOutput1.systemConfigProxy, - cannonPrestate: cannonPrestate, - cannonKonaPrestate: cannonKonaPrestate - }); - - // Trigger the updatePrestate function. - address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner(); - prankDelegateCall(proxyAdminOwner); - (bool success,) = - address(prestateUpdater).delegatecall(abi.encodeCall(IOPContractsManager.updatePrestate, (inputs))); - assertTrue(success, "updatePrestate failed"); - - LibGameArgs.GameArgs memory permissionedGameArgs = - LibGameArgs.decode(chainDeployOutput1.disputeGameFactoryProxy.gameArgs(GameTypes.SUPER_PERMISSIONED_CANNON)); - LibGameArgs.GameArgs memory cannonGameArgs = - LibGameArgs.decode(chainDeployOutput1.disputeGameFactoryProxy.gameArgs(GameTypes.SUPER_CANNON)); - LibGameArgs.GameArgs memory cannonKonaGameArgs = - LibGameArgs.decode(chainDeployOutput1.disputeGameFactoryProxy.gameArgs(GameTypes.SUPER_CANNON_KONA)); - - // Check the prestate values. - assertEq(permissionedGameArgs.absolutePrestate, cannonPrestate.raw(), "pdg prestate mismatch"); - assertEq(cannonGameArgs.absolutePrestate, cannonPrestate.raw(), "fdg prestate mismatch"); - assertEq(cannonKonaGameArgs.absolutePrestate, cannonKonaPrestate.raw(), "fdgKona prestate mismatch"); - - // Ensure that the WETH contracts are not reverting - IDelayedWETH(payable(permissionedGameArgs.weth)).balanceOf(address(0)); - IDelayedWETH(payable(cannonGameArgs.weth)).balanceOf(address(0)); - IDelayedWETH(payable(cannonKonaGameArgs.weth)).balanceOf(address(0)); - } - - /// @notice Tests that we can update the prestate when both the PermissionedDisputeGame and - /// FaultDisputeGame exist, and the FaultDisputeGame is of type CANNON_KONA. - function test_updatePrestate_pdgAndCannonKonaOnly_succeeds() public { - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.CANNON_KONA); - addGameType(input); - - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput({ - systemConfigProxy: chainDeployOutput1.systemConfigProxy, - cannonPrestate: Claim.wrap(bytes32(hex"ABBA")), - cannonKonaPrestate: Claim.wrap(bytes32(hex"ADDA")) - }) - ); - } - - /// @notice Tests that the updatePrestate function will revert if the provided prestate is for - /// mixed game types (i.e. CANNON and SUPER_CANNON_KONA). - function test_updatePrestate_cannonKonaMixedGameTypes_reverts() public { - skipIfDevFeatureDisabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); - - // Add a SuperFaultDisputeGame implementation via addGameType. - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.SUPER_CANNON_KONA); - addGameType(input); - - // nosemgrep: sol-style-use-abi-encodecall - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput({ - systemConfigProxy: chainDeployOutput1.systemConfigProxy, - cannonPrestate: Claim.wrap(bytes32(hex"ABBA")), - cannonKonaPrestate: Claim.wrap(hex"ADDA") - }), - abi.encodeWithSelector( - IOPContractsManagerGameTypeAdder.OPContractsManagerGameTypeAdder_MixedGameTypes.selector - ) - ); - } - - /// @notice Tests that the updatePrestate function will revert if the provided prestate is the - /// zero hash. - function test_updatePrestate_presetCannonKonaWhenOnlyCannonPrestateIsZeroAndCannonGameTypeDisabled_reverts() - public - { - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.CANNON_KONA); - addGameType(input); - - // nosemgrep: sol-style-use-abi-encodecall - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput({ - systemConfigProxy: chainDeployOutput1.systemConfigProxy, - cannonPrestate: Claim.wrap(bytes32(0)), - cannonKonaPrestate: Claim.wrap(bytes32(hex"ABBA")) - }), - abi.encodeWithSelector(IOPContractsManager.PrestateRequired.selector) - ); - } - - /// @notice Tests that the updatePrestate function will revert if the provided prestate is the - /// zero hash. - function test_updatePrestate_whenCannonKonaPrestateIsZero_reverts() public { - IOPContractsManager.AddGameInput memory input = newGameInputFactory(GameTypes.CANNON_KONA); - addGameType(input); - - // nosemgrep: sol-style-use-abi-encodecall - _runUpdatePrestateAndChecks( - IOPContractsManager.UpdatePrestateInput({ - systemConfigProxy: chainDeployOutput1.systemConfigProxy, - cannonPrestate: Claim.wrap(bytes32(hex"ABBA")), - cannonKonaPrestate: Claim.wrap(bytes32(0)) - }), - abi.encodeWithSelector(IOPContractsManager.PrestateRequired.selector) - ); - } -} - -/// @title OPContractsManager_Upgrade_Test -/// @notice Tests the `upgrade` function of the `OPContractsManager` contract. -contract OPContractsManager_Upgrade_Test is OPContractsManager_Upgrade_Harness { - function setUp() public override { - super.setUp(); - - // Run all past upgrades. - runPastUpgrades(upgrader); - - // Grab the pre-upgrade state. Use getGameImplPrestate to handle both v1 and v2 - // dispute games (v1 stores prestate on game impl, v2 stores it in gameArgs). - preUpgradeState = PreUpgradeState({ - cannonAbsolutePrestate: DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON), - permissionedAbsolutePrestate: DisputeGames.getGameImplPrestate( - disputeGameFactory, GameTypes.PERMISSIONED_CANNON - ), - cannonKonaAbsolutePrestate: DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON_KONA), - permissionlessWethProxy: DisputeGames.getGameImplDelayedWeth(disputeGameFactory, GameTypes.CANNON), - permissionedCannonWethProxy: DisputeGames.getGameImplDelayedWeth( - disputeGameFactory, GameTypes.PERMISSIONED_CANNON - ) - }); - } - - function getDisputeGameV2AbsolutePrestate(GameType _gameType) internal view returns (Claim) { - bytes memory gameArgsBytes = disputeGameFactory.gameArgs(_gameType); - LibGameArgs.GameArgs memory gameArgs = LibGameArgs.decode(gameArgsBytes); - return Claim.wrap(gameArgs.absolutePrestate); - } - - function test_upgradeOPChainOnly_succeeds() public { - // Run the upgrade test and checks - runCurrentUpgrade(upgrader); - } - - function test_verifyOpcmCorrectness_succeeds() public { - skipIfUnoptimized(); - - // Set up environment variables with the actual OPCM addresses for tests that need them. - // These values come from the StandardValidator that was deployed with the OPCM. - vm.setEnv("EXPECTED_SUPERCHAIN_CONFIG", vm.toString(address(opcm.superchainConfig()))); - vm.setEnv("EXPECTED_PROTOCOL_VERSIONS", vm.toString(address(opcm.protocolVersions()))); - IOPContractsManagerStandardValidator validator = opcm.opcmStandardValidator(); - vm.setEnv("EXPECTED_L1_PAO_MULTISIG", vm.toString(validator.l1PAOMultisig())); - vm.setEnv("EXPECTED_CHALLENGER", vm.toString(validator.challenger())); - vm.setEnv("EXPECTED_WITHDRAWAL_DELAY_SECONDS", vm.toString(validator.withdrawalDelaySeconds())); - - // Run the upgrade test and checks - runCurrentUpgrade(upgrader); - - // Run the verification script without etherscan verification. Hard to run with etherscan - // verification in these tests, can do it but means we add even more dependencies to the - // test environment. - VerifyOPCM verify = new VerifyOPCM(); - verify.run(address(opcm), true); - } - - function test_upgrade_duplicateL2ChainId_succeeds() public { - // Deploy a new OPChain with the same L2 chain ID as the current OPChain - Deploy deploy = Deploy(address(uint160(uint256(keccak256(abi.encode("optimism.deploy")))))); - IOPContractsManager.DeployInput memory deployInput = deploy.getDeployInput(); - deployInput.l2ChainId = l2ChainId; - deployInput.saltMixer = "v2.0.0"; - opcm.deploy(deployInput); - - // Try to upgrade the current OPChain - runCurrentUpgrade(upgrader); - } - - /// @notice Tests that the absolute prestate can be overridden using the upgrade config. - function test_upgrade_absolutePrestateOverride_succeeds() public { - // Get the pdg and fdg before the upgrade. Use getGameImplPrestate to handle both v1 and v2 - // dispute games (v1 stores prestate on game impl, v2 stores it in gameArgs). - Claim pdgPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.PERMISSIONED_CANNON); - Claim fdgPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON); - - // Assert that the prestate is not zero. - assertNotEq(pdgPrestateBefore.raw(), bytes32(0)); - assertNotEq(fdgPrestateBefore.raw(), bytes32(0)); - - // Set the absolute prestate input to something non-zero. - opChainConfigs[0].cannonPrestate = Claim.wrap(bytes32(uint256(1))); - opChainConfigs[0].cannonKonaPrestate = Claim.wrap(bytes32(uint256(2))); - - // Run the upgrade. - runCurrentUpgrade(upgrader); - - // Get the absolute prestate after the upgrade - Claim pdgPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.PERMISSIONED_CANNON); - Claim fdgPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.CANNON); - - // Assert that the absolute prestate is the non-zero value we set. - assertEq(pdgPrestateAfter.raw(), bytes32(uint256(1))); - assertEq(fdgPrestateAfter.raw(), bytes32(uint256(1))); - - LibGameArgs.GameArgs memory cannonArgs = LibGameArgs.decode(disputeGameFactory.gameArgs(GameTypes.CANNON)); - LibGameArgs.GameArgs memory cannonKonaArgs = - LibGameArgs.decode(disputeGameFactory.gameArgs(GameTypes.CANNON_KONA)); - assertEq(cannonKonaArgs.weth, cannonArgs.weth); - assertEq(cannonKonaArgs.anchorStateRegistry, cannonArgs.anchorStateRegistry); - assertEq(cannonKonaArgs.absolutePrestate, bytes32(uint256(2))); - } - - /// @notice Tests that the old absolute prestate is used if the upgrade config does not set an - /// absolute prestate. - function test_upgrade_absolutePrestateNotSet_succeeds() public { - // Get the pdg and fdg before the upgrade. Use getGameImplPrestate to handle both v1 and v2 - // dispute games (v1 stores prestate on game impl, v2 stores it in gameArgs). - Claim pdgPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.PERMISSIONED_CANNON); - Claim fdgPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON); - Claim cannonKonaPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON_KONA); - - // Assert that the prestate is not zero. - assertNotEq(pdgPrestateBefore.raw(), bytes32(0)); - assertNotEq(fdgPrestateBefore.raw(), bytes32(0)); - assertNotEq(cannonKonaPrestateBefore.raw(), bytes32(0)); - - // Set the absolute prestate input to zero. - opChainConfigs[0].cannonPrestate = Claim.wrap(bytes32(0)); - opChainConfigs[0].cannonKonaPrestate = Claim.wrap(bytes32(0)); - - // Run the upgrade. - runCurrentUpgrade(upgrader); - - // Get the absolute prestate after the upgrade - Claim pdgPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.PERMISSIONED_CANNON); - Claim fdgPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.CANNON); - Claim cannonKonaPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.CANNON_KONA); - - // Assert that the absolute prestate is the same as before the upgrade. - assertEq(pdgPrestateAfter.raw(), pdgPrestateBefore.raw()); - assertEq(fdgPrestateAfter.raw(), fdgPrestateBefore.raw()); - assertEq(cannonKonaPrestateAfter.raw(), cannonKonaPrestateBefore.raw()); - } - - /// @notice Tests that the old absolute prestate is used and cannon kona is updated if the upgrade config does not - /// set a cannon prestate. - function test_upgrade_cannonPrestateNotSet_succeeds() public { - // Get the pdg and fdg before the upgrade. Use getGameImplPrestate to handle both v1 and v2 - // dispute games (v1 stores prestate on game impl, v2 stores it in gameArgs). - Claim pdgPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.PERMISSIONED_CANNON); - Claim fdgPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON); - Claim cannonKonaPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON_KONA); - - // Assert that the prestate is not zero. - assertNotEq(pdgPrestateBefore.raw(), bytes32(0)); - assertNotEq(fdgPrestateBefore.raw(), bytes32(0)); - assertNotEq(cannonKonaPrestateBefore.raw(), bytes32(0)); - - // Set the cannon prestate input to zero. - opChainConfigs[0].cannonPrestate = Claim.wrap(bytes32(0)); - - // Set the cannon kona prestate input to something non-zero. - opChainConfigs[0].cannonKonaPrestate = Claim.wrap(bytes32(uint256(1))); - - // Run the upgrade. - runCurrentUpgrade(upgrader); - - // Get the absolute prestate after the upgrade - Claim pdgPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.PERMISSIONED_CANNON); - Claim fdgPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.CANNON); - Claim cannonKonaPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.CANNON_KONA); - - // Assert that the absolute prestate is the same as before the upgrade. - assertEq(pdgPrestateAfter.raw(), pdgPrestateBefore.raw()); - assertEq(fdgPrestateAfter.raw(), fdgPrestateBefore.raw()); - - // Assert that the cannon kona prestate is the non-zero value we set. - assertEq(cannonKonaPrestateAfter.raw(), bytes32(uint256(1))); - } - - /// @notice Tests that the cannon absolute prestate is updated even if the cannon kona prestate is not specified - function test_upgrade_cannonKonaPrestateNotSet_succeeds() public { - // Get the pdg and fdg before the upgrade. Use getGameImplPrestate to handle both v1 and v2 - // dispute games (v1 stores prestate on game impl, v2 stores it in gameArgs). - Claim pdgPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.PERMISSIONED_CANNON); - Claim fdgPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON); - Claim cannonKonaPrestateBefore = DisputeGames.getGameImplPrestate(disputeGameFactory, GameTypes.CANNON_KONA); - - // Assert that the prestate is not zero. - assertNotEq(pdgPrestateBefore.raw(), bytes32(0)); - assertNotEq(fdgPrestateBefore.raw(), bytes32(0)); - assertNotEq(cannonKonaPrestateBefore.raw(), bytes32(0)); - - // Set the absolute prestate input to something non-zero. - opChainConfigs[0].cannonPrestate = Claim.wrap(bytes32(uint256(1))); - - // Set the cannon kona prestate input to zero. - opChainConfigs[0].cannonKonaPrestate = Claim.wrap(bytes32(0)); - - // Run the upgrade. - runCurrentUpgrade(upgrader); - - // Get the absolute prestate after the upgrade - Claim pdgPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.PERMISSIONED_CANNON); - Claim fdgPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.CANNON); - Claim cannonKonaPrestateAfter = getDisputeGameV2AbsolutePrestate(GameTypes.CANNON_KONA); - - // Assert that the absolute prestate is the non-zero value we set. - assertEq(pdgPrestateAfter.raw(), bytes32(uint256(1))); - assertEq(fdgPrestateAfter.raw(), bytes32(uint256(1))); - - // Assert that the cannon kona prestate is the same as before the upgrade. - assertEq(cannonKonaPrestateAfter.raw(), cannonKonaPrestateBefore.raw()); - } - - function test_upgrade_notDelegateCalled_reverts() public { - vm.prank(upgrader); - vm.expectRevert(IOPContractsManager.OnlyDelegatecall.selector); - opcm.upgrade(opChainConfigs); - } - - function test_upgrade_notProxyAdminOwner_reverts() public { - address delegateCaller = makeAddr("delegateCaller"); - - assertNotEq(superchainProxyAdmin.owner(), delegateCaller); - assertNotEq(proxyAdmin.owner(), delegateCaller); - - runCurrentUpgrade(delegateCaller, bytes("Ownable: caller is not the owner")); - } - - /// @notice Tests that upgrade reverts when absolutePrestate is zero and the existing game also - /// has an absolute prestate of zero. - function test_upgrade_absolutePrestateNotSet_reverts() public { - // Set the config to try to update the absolutePrestate to zero. - opChainConfigs[0].cannonPrestate = Claim.wrap(bytes32(0)); - - // Mock the PDG prestate to zero. This uses mockGameImplPrestate which handles both v1 and v2 - // dispute games correctly (v1 stores prestate on the game impl, v2 stores it in gameArgs). - DisputeGames.mockGameImplPrestate(disputeGameFactory, GameTypes.PERMISSIONED_CANNON, bytes32(0)); - - // Expect the upgrade to revert with PrestateNotSet. - // nosemgrep: sol-style-use-abi-encodecall - runCurrentUpgrade(upgrader, abi.encodeWithSelector(IOPContractsManager.PrestateNotSet.selector)); - } - - /// @notice Tests that the upgrade function reverts when the superchainConfig is not at the expected target version. - function test_upgrade_superchainConfigNeedsUpgrade_reverts() public { - // Force the SuperchainConfig to return an obviously outdated version. - vm.mockCall(address(superchainConfig), abi.encodeCall(ISuperchainConfig.version, ()), abi.encode("0.0.0")); - - // Try upgrading an OPChain without upgrading its superchainConfig. - // nosemgrep: sol-style-use-abi-encodecall - runCurrentUpgrade( - upgrader, - abi.encodeWithSelector( - IOPContractsManagerUpgrader.OPContractsManagerUpgrader_SuperchainConfigNeedsUpgrade.selector, (0) - ) - ); - } -} - -contract OPContractsManager_UpgradeSuperchainConfig_Test is OPContractsManager_Upgrade_Harness { - function setUp() public override { - super.setUp(); - - // The superchainConfig is already at the expected version so we mock this call here to bypass that check and - // get our expected error. - vm.mockCall(address(superchainConfig), abi.encodeCall(ISuperchainConfig.version, ()), abi.encode("2.2.0")); - } - - /// @notice Tests that the upgradeSuperchainConfig function succeeds when the superchainConfig is at the expected - /// version and the delegate caller is the superchainProxyAdmin owner. - function test_upgradeSuperchainConfig_succeeds() public { - IOPContractsManager.Implementations memory impls = opcm.implementations(); - - ISuperchainConfig superchainConfig = ISuperchainConfig(artifacts.mustGetAddress("SuperchainConfigProxy")); - - address superchainPAO = IProxyAdmin(EIP1967Helper.getAdmin(address(superchainConfig))).owner(); - - vm.expectEmit(address(superchainConfig)); - emit Upgraded(impls.superchainConfigImpl); - prankDelegateCall(superchainPAO); - (bool success,) = - address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig))); - assertTrue(success, "upgradeSuperchainConfig failed"); - } - - /// @notice Tests that the upgradeSuperchainConfig function reverts when it is not called via delegatecall. - function test_upgradeSuperchainConfig_notDelegateCalled_reverts() public { - ISuperchainConfig superchainConfig = ISuperchainConfig(artifacts.mustGetAddress("SuperchainConfigProxy")); - - vm.expectRevert(IOPContractsManager.OnlyDelegatecall.selector); - opcm.upgradeSuperchainConfig(superchainConfig); - } - - /// @notice Tests that the upgradeSuperchainConfig function reverts when the delegate caller is not the - /// superchainProxyAdmin owner. - function test_upgradeSuperchainConfig_notProxyAdminOwner_reverts() public { - ISuperchainConfig superchainConfig = ISuperchainConfig(artifacts.mustGetAddress("SuperchainConfigProxy")); - - address delegateCaller = makeAddr("delegateCaller"); - - assertNotEq(superchainProxyAdmin.owner(), delegateCaller); - assertNotEq(proxyAdmin.owner(), delegateCaller); - - vm.expectRevert("Ownable: caller is not the owner"); - prankDelegateCall(delegateCaller); - (bool success,) = - address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig))); - assertTrue(success, "upgradeSuperchainConfig failed"); - } - - /// @notice Tests that the upgradeSuperchainConfig function reverts when the superchainConfig version is the same or - /// newer than the target version. - function test_upgradeSuperchainConfig_superchainConfigAlreadyUpToDate_reverts() public { - ISuperchainConfig superchainConfig = ISuperchainConfig(artifacts.mustGetAddress("SuperchainConfigProxy")); - - // Set the version of the superchain config to a version that is the target version. - vm.clearMockedCalls(); - - // Mock the SuperchainConfig to return a very large version. - vm.mockCall(address(superchainConfig), abi.encodeCall(ISuperchainConfig.version, ()), abi.encode("99.99.99")); - - // Try to upgrade the SuperchainConfig contract again, should fail. - vm.expectRevert(IOPContractsManagerUpgrader.OPContractsManagerUpgrader_SuperchainConfigAlreadyUpToDate.selector); - prankDelegateCall(upgrader); - (bool success,) = - address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig))); - assertTrue(success, "upgradeSuperchainConfig failed"); - } -} - -/// @title OPContractsManager_Migrate_Test -/// @notice Tests the `migrate` function of the `OPContractsManager` contract. -contract OPContractsManager_Migrate_Test is OPContractsManager_TestInit { - Claim cannonPrestate1 = Claim.wrap(bytes32(hex"ABBA")); - Claim cannonPrestate2 = Claim.wrap(bytes32(hex"DEAD")); - Claim cannonKonaPrestate1 = Claim.wrap(bytes32(hex"ABBACADABA")); - Claim cannonKonaPrestate2 = Claim.wrap(bytes32(hex"DEADBEEF")); - Claim emptyPrestate = Claim.wrap(bytes32(0)); - - /// @notice Function requires interop portal. - function setUp() public override { - super.setUp(); - skipIfDevFeatureDisabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); - } - - /// @notice Helper function to create the default migration input. - function _getDefaultInput() internal view returns (IOPContractsManagerInteropMigrator.MigrateInput memory) { - IOPContractsManagerInteropMigrator.GameParameters memory gameParameters = IOPContractsManagerInteropMigrator - .GameParameters({ - proposer: address(1234), - challenger: address(5678), - maxGameDepth: 73, - splitDepth: 30, - initBond: 1 ether, - clockExtension: Duration.wrap(10800), - maxClockDuration: Duration.wrap(302400) - }); - - IOPContractsManager.OpChainConfig[] memory opChainConfigs = new IOPContractsManager.OpChainConfig[](2); - opChainConfigs[0] = IOPContractsManager.OpChainConfig( - chainDeployOutput1.systemConfigProxy, cannonPrestate1, cannonKonaPrestate1 - ); - opChainConfigs[1] = IOPContractsManager.OpChainConfig( - chainDeployOutput2.systemConfigProxy, cannonPrestate1, cannonKonaPrestate1 - ); - - return IOPContractsManagerInteropMigrator.MigrateInput({ - usePermissionlessGame: true, - startingAnchorRoot: Proposal({ root: Hash.wrap(bytes32(hex"ABBA")), l2SequenceNumber: 1234 }), - gameParameters: gameParameters, - opChainConfigs: opChainConfigs - }); - } - - /// @notice Helper function to execute a migration. - /// @param _input The input to the migration function. - function _doMigration(IOPContractsManagerInteropMigrator.MigrateInput memory _input) internal { - _doMigration(_input, bytes4(0)); - } - - /// @notice Helper function to execute a migration with a revert selector. - /// @param _input The input to the migration function. - /// @param _revertSelector The selector of the revert to expect. - function _doMigration( - IOPContractsManagerInteropMigrator.MigrateInput memory _input, - bytes4 _revertSelector - ) - internal - { - // Set the proxy admin owner to be a delegate caller. - address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner(); - - // Execute a delegatecall to the OPCM migration function. - // Check gas usage of the migration function. - uint256 gasBefore = gasleft(); - if (_revertSelector != bytes4(0)) { - vm.expectRevert(_revertSelector); - } - prankDelegateCall(proxyAdminOwner); - (bool success,) = address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.migrate, (_input))); - assertTrue(success, "migrate failed"); - uint256 gasAfter = gasleft(); - - // Make sure the gas usage is less than 20 million so we can definitely fit in a block. - assertLt(gasBefore - gasAfter, 20_000_000, "Gas usage too high"); - } - - /// @notice Helper function to assert that the old game implementations are now zeroed out. - /// We need a separate helper to avoid stack too deep errors. - /// @param _disputeGameFactory The dispute game factory to check. - function _assertOldGamesZeroed(IDisputeGameFactory _disputeGameFactory) internal view { - // Assert that the old game implementations are now zeroed out. - _assertGameIsEmpty(_disputeGameFactory, GameTypes.CANNON, "CANNON"); - _assertGameIsEmpty(_disputeGameFactory, GameTypes.SUPER_CANNON, "SUPER_CANNON"); - _assertGameIsEmpty(_disputeGameFactory, GameTypes.PERMISSIONED_CANNON, "PERMISSIONED_CANNON"); - _assertGameIsEmpty(_disputeGameFactory, GameTypes.SUPER_PERMISSIONED_CANNON, "SUPER_PERMISSIONED_CANNON"); - // Only explicitly zeroed out if feature is enabled. Otherwise left unchanged (which may still be 0). - _assertGameIsEmpty(_disputeGameFactory, GameTypes.CANNON_KONA, "CANNON_KONA"); - _assertGameIsEmpty(_disputeGameFactory, GameTypes.SUPER_CANNON_KONA, "SUPER_CANNON_KONA"); - } - - function _assertGameIsEmpty(IDisputeGameFactory _dgf, GameType _gameType, string memory _label) internal view { - assertEq( - address(_dgf.gameImpls(_gameType)), - address(0), - string.concat("Game type set when it should not be: ", _label) - ); - assertEq(_dgf.gameArgs(_gameType), hex"", string.concat("Game args should be empty: ", _label)); - } - - /// @notice Creates a dummy super root proof consisting of all chains being migrated - function _createSuperRootProof( - IOPContractsManagerInteropMigrator.MigrateInput memory _input, - uint64 _l2SequenceNumber - ) - internal - view - returns (LibTypes.SuperRootProof memory super_) - { - LibTypes.OutputRootWithChainId[] memory outputRoots = - new LibTypes.OutputRootWithChainId[](_input.opChainConfigs.length); - for (uint256 j; j < _input.opChainConfigs.length; j++) { - outputRoots[j] = LibTypes.OutputRootWithChainId({ - chainId: uint32(_input.opChainConfigs[j].systemConfigProxy.l2ChainId()), - root: keccak256(abi.encode(gasleft())) - }); - } - super_.version = bytes1(uint8(1)); - super_.timestamp = uint64(_l2SequenceNumber); - super_.outputRoots = outputRoots; - } - - /// @notice Runs some tests after opcm.migrate - function _runPostMigrateSmokeTests(IOPContractsManagerInteropMigrator.MigrateInput memory _input) internal { - IDisputeGameFactory dgf = IDisputeGameFactory(chainDeployOutput1.systemConfigProxy.disputeGameFactory()); - IAnchorStateRegistry anchorStateRegistry = - IOptimismPortal2(payable(chainDeployOutput1.systemConfigProxy.optimismPortal())).anchorStateRegistry(); - address proposer = _input.gameParameters.proposer; - - (, uint256 l2SequenceNumberAnchor) = anchorStateRegistry.getAnchorRoot(); - uint256 l2SequenceNumber = l2SequenceNumberAnchor + 1; - GameType[] memory gameTypes = _getPostMigrateExpectedGameTypes(_input); - - address permissionlessWeth; - for (uint256 i = 0; i < gameTypes.length; i++) { - LibGameArgs.GameArgs memory gameArgs = LibGameArgs.decode(dgf.gameArgs(gameTypes[i])); - if (permissionlessWeth == address(0) && !DisputeGames.isGamePermissioned(gameTypes[i])) { - // Remember the first permissionless weth we encounter - permissionlessWeth = gameArgs.weth; - } - - assertEq(gameArgs.vm, opcm.implementations().mipsImpl, "gameArgs vm mismatch"); - assertEq(gameArgs.anchorStateRegistry, address(anchorStateRegistry), "gameArgs asr mismatch"); - assertEq(gameArgs.l2ChainId, 0, "gameArgs non-zero l2ChainId"); - if (gameTypes[i].raw() == GameTypes.SUPER_CANNON_KONA.raw()) { - assertEq(gameArgs.absolutePrestate, cannonKonaPrestate1.raw(), "gameArgs prestate mismatch"); - } else { - assertEq(gameArgs.absolutePrestate, cannonPrestate1.raw(), "gameArgs prestate mismatch"); - } - if (!DisputeGames.isGamePermissioned(gameTypes[i])) { - // All permissionless FDG games should share the same weth contract - assertEq(gameArgs.weth, permissionlessWeth, "gameArgs weth mismatch"); - } - - LibTypes.SuperRootProof memory superRootProof = _createSuperRootProof(_input, uint64(l2SequenceNumber)); - uint256 bondAmount = dgf.initBonds(gameTypes[i]); - vm.deal(address(proposer), bondAmount); - vm.prank(proposer, proposer); - - ISuperPermissionedDisputeGame game = ISuperPermissionedDisputeGame( - address( - dgf.create{ value: bondAmount }( - gameTypes[i], - Claim.wrap(Hashing.hashSuperRootProof(superRootProof)), - Encoding.encodeSuperRootProof(superRootProof) - ) - ) - ); - - assertEq(game.gameType().raw(), gameTypes[i].raw(), "Super Cannon game type not set properly"); - assertEq( - game.maxClockDuration().raw(), - _input.gameParameters.maxClockDuration.raw(), - "max clock duration mismatch" - ); - assertEq( - game.clockExtension().raw(), _input.gameParameters.clockExtension.raw(), "max clock duration mismatch" - ); - assertEq(game.maxGameDepth(), _input.gameParameters.maxGameDepth, "max game depth mismatch"); - assertEq(game.splitDepth(), _input.gameParameters.splitDepth, "split depth mismatch"); - assertEq(game.l2SequenceNumber(), l2SequenceNumber, "sequence number mismatch"); - assertEq(game.gameCreator(), proposer, "game creator mismatch"); - assertEq(game.l1Head().raw(), blockhash(block.number - 1), "l1 head mismatch"); - - // check game args - assertEq(game.absolutePrestate().raw(), gameArgs.absolutePrestate, "prestate mismatch"); - assertEq(address(game.vm()), gameArgs.vm, "vm mismatch"); - assertEq(address(game.anchorStateRegistry()), gameArgs.anchorStateRegistry, "prestate mismatch"); - assertEq(address(game.weth()), gameArgs.weth, "weth mismatch"); - if (gameTypes[i].raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw()) { - assertEq(game.proposer(), gameArgs.proposer, "proposer mismatch"); - assertEq(game.challenger(), gameArgs.challenger, "challenger mismatch"); - } - } - } - - function _getPostMigrateExpectedGameTypes(IOPContractsManagerInteropMigrator.MigrateInput memory _input) - internal - pure - returns (GameType[] memory gameTypes_) - { - uint256 gameCount = 1; - bytes32 cannonKonaPrestate = _input.opChainConfigs[0].cannonKonaPrestate.raw(); - if (_input.usePermissionlessGame) { - gameCount += 1; - if (cannonKonaPrestate != bytes32(0)) { - gameCount += 1; - } - } - - gameTypes_ = new GameType[](gameCount); - gameTypes_[0] = GameTypes.SUPER_PERMISSIONED_CANNON; - if (_input.usePermissionlessGame) { - gameTypes_[1] = GameTypes.SUPER_CANNON; - if (cannonKonaPrestate != bytes32(0)) { - gameTypes_[2] = GameTypes.SUPER_CANNON_KONA; - } - } - } - - /// @notice Tests that the migration function succeeds when requesting to use the - /// permissionless game. - function test_migrate_withPermissionlessGame_succeeds() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - (IAnchorStateRegistry asr, IDisputeGameFactory dgf) = _runMigrationAndStandardChecks(input); - - // Check the respected game type - assertEq(asr.respectedGameType().raw(), GameTypes.SUPER_CANNON.raw(), "Super Cannon game type mismatch"); - - // Check initial bonds - assertEq( - dgf.initBonds(GameTypes.SUPER_CANNON), input.gameParameters.initBond, "Super Cannon init bond mismatch" - ); - assertEq( - dgf.initBonds(GameTypes.SUPER_PERMISSIONED_CANNON), - input.gameParameters.initBond, - "Super Permissioned Cannon init bond mismatch" - ); - assertEq( - dgf.initBonds(GameTypes.SUPER_CANNON_KONA), - input.gameParameters.initBond, - "Super CannonKona init bond mismatch" - ); - - // Check game configuration - _validateSuperGameImplParams(input, dgf, GameTypes.SUPER_PERMISSIONED_CANNON, "SUPER_PERMISSIONED_CANNON"); - _validateSuperGameImplParams(input, dgf, GameTypes.SUPER_CANNON, "SUPER_CANNON"); - _validateSuperGameImplParams(input, dgf, GameTypes.SUPER_CANNON_KONA, "SUPER_CANNON_KONA"); - - _runPostMigrateSmokeTests(input); - } - - /// @notice Tests that permissionless migration reverts when cannon prestates are empty. - function test_migrate_permissionlessWithEmptyCannonPrestate_reverts() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - input.opChainConfigs[0].cannonPrestate = emptyPrestate; - input.opChainConfigs[1].cannonPrestate = emptyPrestate; - - // Execute the migration. - _doMigration(input, IOPContractsManager.PrestateNotSet.selector); - } - - /// @notice Tests that the permissionless migration succeeds when cannonKona prestates are empty. - function test_migrate_permissionlessWithEmptyCannonKonaPrestate_succeeds() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - input.opChainConfigs[0].cannonKonaPrestate = emptyPrestate; - input.opChainConfigs[1].cannonKonaPrestate = emptyPrestate; - (IAnchorStateRegistry asr, IDisputeGameFactory dgf) = _runMigrationAndStandardChecks(input); - - // Check the respected game type - assertEq(asr.respectedGameType().raw(), GameTypes.SUPER_CANNON.raw(), "Super Cannon game type mismatch"); - - // Check initial bonds - assertEq( - dgf.initBonds(GameTypes.SUPER_CANNON), input.gameParameters.initBond, "Super Cannon init bond mismatch" - ); - assertEq( - dgf.initBonds(GameTypes.SUPER_PERMISSIONED_CANNON), - input.gameParameters.initBond, - "Super Permissioned Cannon init bond mismatch" - ); - assertEq(dgf.initBonds(GameTypes.SUPER_CANNON_KONA), uint256(0), "Super CannonKona init bond should be zero"); - - // Check game configuration - _validateSuperGameImplParams(input, dgf, GameTypes.SUPER_PERMISSIONED_CANNON, "SUPER_PERMISSIONED_CANNON"); - _validateSuperGameImplParams(input, dgf, GameTypes.SUPER_CANNON, "SUPER_CANNON"); - _assertGameIsEmpty(dgf, GameTypes.SUPER_CANNON_KONA, "SUPER_CANNON_KONA"); - - _runPostMigrateSmokeTests(input); - } - - /// @notice Tests that the migration function succeeds when requesting to not use the - /// permissioned game (no permissioned game is deployed). - function test_migrate_withoutPermissionlessGame_succeeds() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - input.usePermissionlessGame = false; - (IAnchorStateRegistry asr, IDisputeGameFactory dgf) = _runMigrationAndStandardChecks(input); - - // Check the respected game type - assertEq( - asr.respectedGameType().raw(), - GameTypes.SUPER_PERMISSIONED_CANNON.raw(), - "Super Permissioned Cannon game type mismatch" - ); - - // Check intial bonds - assertEq( - dgf.initBonds(GameTypes.SUPER_PERMISSIONED_CANNON), - input.gameParameters.initBond, - "Super Permissioned Cannon init bond mismatch" - ); - assertEq(dgf.initBonds(GameTypes.SUPER_CANNON), 0, "Super Cannon init bond mismatch"); - assertEq(dgf.initBonds(GameTypes.SUPER_CANNON_KONA), 0, "Super CannonKona init bond mismatch"); - - // Check game configuration - _validateSuperGameImplParams(input, dgf, GameTypes.SUPER_PERMISSIONED_CANNON, "SUPER_PERMISSIONED_CANNON"); - _assertGameIsEmpty(dgf, GameTypes.SUPER_CANNON, "SUPER_CANNON"); - _assertGameIsEmpty(dgf, GameTypes.SUPER_CANNON_KONA, "SUPER_CANNON_KONA"); - - _runPostMigrateSmokeTests(input); - } - - /// @notice Tests that permissioned migration reverts when cannon prestates are empty. - function test_migrate_permissionedWithEmptyCannonPrestate_reverts() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - input.usePermissionlessGame = false; - input.opChainConfigs[0].cannonPrestate = emptyPrestate; - input.opChainConfigs[1].cannonPrestate = emptyPrestate; - - // Execute the migration. - _doMigration(input, IOPContractsManager.PrestateNotSet.selector); - } - - function _runMigrationAndStandardChecks(IOPContractsManagerInteropMigrator.MigrateInput memory input) - internal - returns (IAnchorStateRegistry asr_, IDisputeGameFactory dgf_) - { - // Separate context to avoid stack too deep errors. - { - // Grab the existing DisputeGameFactory for each chain. - IDisputeGameFactory oldDisputeGameFactory1 = - IDisputeGameFactory(payable(chainDeployOutput1.systemConfigProxy.disputeGameFactory())); - IDisputeGameFactory oldDisputeGameFactory2 = - IDisputeGameFactory(payable(chainDeployOutput2.systemConfigProxy.disputeGameFactory())); - - // Execute the migration. - _doMigration(input); - - // Assert that the old game implementations are now zeroed out. - _assertOldGamesZeroed(oldDisputeGameFactory1); - _assertOldGamesZeroed(oldDisputeGameFactory2); - } - - // Grab the two OptimismPortal addresses. - IOptimismPortal2 optimismPortal1 = - IOptimismPortal2(payable(chainDeployOutput1.systemConfigProxy.optimismPortal())); - IOptimismPortal2 optimismPortal2 = - IOptimismPortal2(payable(chainDeployOutput2.systemConfigProxy.optimismPortal())); - - // Grab the AnchorStateRegistry from the OptimismPortal for both chains, confirm same. - assertEq( - address(optimismPortal1.anchorStateRegistry()), - address(optimismPortal2.anchorStateRegistry()), - "AnchorStateRegistry mismatch" - ); - - // Extract the AnchorStateRegistry now that we know it's the same on both chains. - asr_ = optimismPortal1.anchorStateRegistry(); - - // Check that the starting anchor root is the same as the input. - (Hash root, uint256 l2SequenceNumber) = asr_.getAnchorRoot(); - assertEq(root.raw(), input.startingAnchorRoot.root.raw(), "Starting anchor root mismatch"); - assertEq( - l2SequenceNumber, - input.startingAnchorRoot.l2SequenceNumber, - "Starting anchor root L2 sequence number mismatch" - ); - - // Grab the DisputeGameFactory from the SystemConfig for both chains, confirm same. - assertEq( - chainDeployOutput1.systemConfigProxy.disputeGameFactory(), - chainDeployOutput2.systemConfigProxy.disputeGameFactory(), - "DisputeGameFactory mismatch" - ); - - // Extract the DisputeGameFactory now that we know it's the same on both chains. - dgf_ = IDisputeGameFactory(chainDeployOutput1.systemConfigProxy.disputeGameFactory()); - - // Grab the ETHLockbox from the OptimismPortal for both chains, confirm same. - assertEq(address(optimismPortal1.ethLockbox()), address(optimismPortal2.ethLockbox()), "ETHLockbox mismatch"); - - // Extract the ETHLockbox now that we know it's the same on both chains. - IETHLockbox ethLockbox = optimismPortal1.ethLockbox(); - - // Check that the ETHLockbox was migrated correctly. - assertGt(address(ethLockbox).balance, 0, "ETHLockbox balance is zero"); - assertTrue(ethLockbox.authorizedPortals(optimismPortal1), "ETHLockbox does not have portal 1 authorized"); - assertTrue(ethLockbox.authorizedPortals(optimismPortal2), "ETHLockbox does not have portal 2 authorized"); - } - - function _validateSuperGameImplParams( - IOPContractsManagerInteropMigrator.MigrateInput memory _input, - IDisputeGameFactory _dgf, - GameType _gameType, - string memory _label - ) - internal - view - { - IDisputeGame dgImpl = _dgf.gameImpls(_gameType); - ISuperFaultDisputeGame superImpl = ISuperFaultDisputeGame(address(dgImpl)); - assertEq( - superImpl.maxGameDepth(), - _input.gameParameters.maxGameDepth, - string.concat("MaxGameDepth mismatch: ", _label) - ); - assertEq( - superImpl.splitDepth(), _input.gameParameters.splitDepth, string.concat("SplitDepth mismatch: ", _label) - ); - assertEq( - superImpl.clockExtension().raw(), - _input.gameParameters.clockExtension.raw(), - string.concat("ClockExtension mismatch: ", _label) - ); - assertEq( - superImpl.maxClockDuration().raw(), - _input.gameParameters.maxClockDuration.raw(), - string.concat("MaxClockDuration mismatch: ", _label) - ); - } - - /// @notice Tests that the migration function reverts when the ProxyAdmin owners are - /// mismatched. - function test_migrate_mismatchedProxyAdminOwners_reverts() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - - // Mock out the owners of the ProxyAdmins to be different. - vm.mockCall( - address(input.opChainConfigs[0].systemConfigProxy.proxyAdmin()), - abi.encodeCall(IProxyAdmin.owner, ()), - abi.encode(address(1234)) - ); - vm.mockCall( - address(input.opChainConfigs[1].systemConfigProxy.proxyAdmin()), - abi.encodeCall(IProxyAdmin.owner, ()), - abi.encode(address(5678)) - ); - - // Execute the migration. - _doMigration( - input, OPContractsManagerInteropMigrator.OPContractsManagerInteropMigrator_ProxyAdminOwnerMismatch.selector - ); - } - - /// @notice Tests that the migration function reverts when the absolute prestates are - /// mismatched. - function test_migrate_mismatchedCannonPrestates_reverts() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - - // Set the prestates to be different. - input.opChainConfigs[0].cannonPrestate = cannonPrestate1; - input.opChainConfigs[1].cannonPrestate = cannonPrestate2; - - // Execute the migration. - _doMigration( - input, OPContractsManagerInteropMigrator.OPContractsManagerInteropMigrator_AbsolutePrestateMismatch.selector - ); - } - - /// @notice Tests that the migration function reverts when the absolute prestates are - /// mismatched. - function test_migrate_mismatchedKonaPrestates_reverts() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - - // Set the prestates to be different. - input.opChainConfigs[0].cannonKonaPrestate = cannonKonaPrestate1; - input.opChainConfigs[1].cannonKonaPrestate = cannonKonaPrestate2; - - // Execute the migration. - // We should revert if there is a mismatch and cannonaKona is enabled - _doMigration( - input, OPContractsManagerInteropMigrator.OPContractsManagerInteropMigrator_AbsolutePrestateMismatch.selector - ); - } - - /// @notice Tests that the migration function reverts when the SuperchainConfig addresses are - /// mismatched. - function test_migrate_mismatchedSuperchainConfig_reverts() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - - // Mock out the SuperchainConfig addresses to be different. - vm.mockCall( - address(chainDeployOutput1.optimismPortalProxy), - abi.encodeCall(IOptimismPortal2.superchainConfig, ()), - abi.encode(address(1234)) - ); - vm.mockCall( - address(chainDeployOutput2.optimismPortalProxy), - abi.encodeCall(IOptimismPortal2.superchainConfig, ()), - abi.encode(address(5678)) - ); - - // Execute the migration. - _doMigration( - input, OPContractsManagerInteropMigrator.OPContractsManagerInteropMigrator_SuperchainConfigMismatch.selector - ); - } - - function test_migrate_zerosOutCannonKonaGameTypes_succeeds() public { - IOPContractsManagerInteropMigrator.MigrateInput memory input = _getDefaultInput(); - - // Grab the existing DisputeGameFactory for each chain. - IDisputeGameFactory oldDisputeGameFactory1 = - IDisputeGameFactory(payable(chainDeployOutput1.systemConfigProxy.disputeGameFactory())); - IDisputeGameFactory oldDisputeGameFactory2 = - IDisputeGameFactory(payable(chainDeployOutput2.systemConfigProxy.disputeGameFactory())); - // Ensure cannon kona games have implementations - oldDisputeGameFactory1.setImplementation(GameTypes.CANNON_KONA, IDisputeGame(address(1))); - oldDisputeGameFactory2.setImplementation(GameTypes.CANNON_KONA, IDisputeGame(address(1))); - oldDisputeGameFactory1.setImplementation(GameTypes.SUPER_CANNON_KONA, IDisputeGame(address(2))); - oldDisputeGameFactory2.setImplementation(GameTypes.SUPER_CANNON_KONA, IDisputeGame(address(2))); - - // Execute the migration. - _doMigration(input); - - // Assert that the old game implementations are now zeroed out. - _assertOldGamesZeroed(oldDisputeGameFactory1); - _assertOldGamesZeroed(oldDisputeGameFactory2); - } -} - -/// @title OPContractsManager_Deploy_Test -/// @notice Tests the `deploy` function of the `OPContractsManager` contract. -/// @dev Unlike other test suites, we intentionally do not inherit from CommonTest or Setup. This -/// is because OPContractsManager acts as a deploy script, so we start from a clean slate here -/// and work OPContractsManager's deployment into the existing test setup, instead of using -/// the existing test setup to deploy OPContractsManager. We do however inherit from -/// DeployOPChain_TestBase so we can use its setup to deploy the implementations similarly -/// to how a real deployment would happen. -contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase { - using DisputeGames for *; - using stdStorage for StdStorage; - - function setUp() public override { - super.setUp(); - skipIfDevFeatureEnabled(DevFeatures.OPCM_V2); - } - - // This helper function is used to convert the input struct type defined in DeployOPChain.s.sol - // to the input struct type defined in OPContractsManager.sol. - function toOPCMDeployInput(Types.DeployOPChainInput memory _doi) - internal - returns (IOPContractsManager.DeployInput memory) - { - bytes memory startingAnchorRoot = new DeployOPChain().startingAnchorRoot(); - return IOPContractsManager.DeployInput({ - roles: IOPContractsManager.Roles({ - opChainProxyAdminOwner: _doi.opChainProxyAdminOwner, - systemConfigOwner: _doi.systemConfigOwner, - batcher: _doi.batcher, - unsafeBlockSigner: _doi.unsafeBlockSigner, - proposer: _doi.proposer, - challenger: _doi.challenger - }), - basefeeScalar: _doi.basefeeScalar, - blobBasefeeScalar: _doi.blobBaseFeeScalar, - l2ChainId: _doi.l2ChainId, - startingAnchorRoot: startingAnchorRoot, - saltMixer: _doi.saltMixer, - gasLimit: _doi.gasLimit, - disputeGameType: _doi.disputeGameType, - disputeAbsolutePrestate: _doi.disputeAbsolutePrestate, - disputeMaxGameDepth: _doi.disputeMaxGameDepth, - disputeSplitDepth: _doi.disputeSplitDepth, - disputeClockExtension: _doi.disputeClockExtension, - disputeMaxClockDuration: _doi.disputeMaxClockDuration, - useCustomGasToken: _doi.useCustomGasToken - }); - } - - function test_deploy_l2ChainIdEqualsZero_reverts() public { - IOPContractsManager.DeployInput memory input = toOPCMDeployInput(deployOPChainInput); - input.l2ChainId = 0; - - vm.expectRevert(IOPContractsManager.InvalidChainId.selector); - IOPContractsManager(opcmAddr).deploy(input); - } - - function test_deploy_l2ChainIdEqualsCurrentChainId_reverts() public { - IOPContractsManager.DeployInput memory input = toOPCMDeployInput(deployOPChainInput); - input.l2ChainId = block.chainid; - - vm.expectRevert(IOPContractsManager.InvalidChainId.selector); - IOPContractsManager(opcmAddr).deploy(input); - } - - function test_deploy_succeeds() public { - vm.expectEmit(true, true, true, false); // TODO precompute the expected `deployOutput`. - emit Deployed(deployOPChainInput.l2ChainId, address(this), bytes("")); - IOPContractsManager(opcmAddr).deploy(toOPCMDeployInput(deployOPChainInput)); - } - - /// @notice Test that deploy sets the permissioned dispute game implementation - function test_deployPermissioned_succeeds() public { - // Sanity-check setup is consistent with devFeatures flag - IOPContractsManager.Implementations memory impls = IOPContractsManager(opcmAddr).implementations(); - address pdgImpl = address(impls.permissionedDisputeGameImpl); - address fdgImpl = address(impls.faultDisputeGameImpl); - assertFalse(pdgImpl == address(0), "PDG implementation address should be non-zero"); - assertFalse(fdgImpl == address(0), "FDG implementation address should be non-zero"); - - // Run OPCM.deploy - IOPContractsManager.DeployInput memory opcmInput = toOPCMDeployInput(deployOPChainInput); - IOPContractsManager.DeployOutput memory opcmOutput = IOPContractsManager(opcmAddr).deploy(opcmInput); - - // Verify that the DisputeGameFactory has registered an implementation for the PERMISSIONED_CANNON game type - address actualPDGAddress = address(opcmOutput.disputeGameFactoryProxy.gameImpls(GameTypes.PERMISSIONED_CANNON)); - assertNotEq(actualPDGAddress, address(0), "DisputeGameFactory should have a registered PERMISSIONED_CANNON"); - assertEq(actualPDGAddress, pdgImpl, "PDG address should match"); - - // Create a game proxy to test immutable fields - Claim claim = Claim.wrap(bytes32(uint256(9876))); - uint256 l2BlockNumber = uint256(123); - IPermissionedDisputeGame pdg = IPermissionedDisputeGame( - payable( - DisputeGames.createGame( - opcmOutput.disputeGameFactoryProxy, - GameTypes.PERMISSIONED_CANNON, - opcmInput.roles.proposer, - claim, - l2BlockNumber - ) - ) - ); - - // Verify immutable fields on the game proxy - // Constructor args - assertEq(pdg.gameType().raw(), GameTypes.PERMISSIONED_CANNON.raw(), "Game type should match"); - assertEq(pdg.clockExtension().raw(), opcmInput.disputeClockExtension.raw(), "Clock extension should match"); - assertEq( - pdg.maxClockDuration().raw(), opcmInput.disputeMaxClockDuration.raw(), "Max clock duration should match" - ); - assertEq(pdg.splitDepth(), opcmInput.disputeSplitDepth, "Split depth should match"); - assertEq(pdg.maxGameDepth(), opcmInput.disputeMaxGameDepth, "Max game depth should match"); - // Clone-with-immutable-args - assertEq(pdg.gameCreator(), opcmInput.roles.proposer, "Game creator should match"); - assertEq(pdg.rootClaim().raw(), claim.raw(), "Claim should match"); - assertEq(pdg.l1Head().raw(), blockhash(block.number - 1), "L1 head should match"); - assertEq(pdg.l2BlockNumber(), l2BlockNumber, "L2 Block number should match"); - assertEq( - pdg.absolutePrestate().raw(), - opcmInput.disputeAbsolutePrestate.raw(), - "Absolute prestate should match input" - ); - assertEq(address(pdg.vm()), address(impls.mipsImpl), "VM should match MIPS implementation"); - assertEq(address(pdg.anchorStateRegistry()), address(opcmOutput.anchorStateRegistryProxy), "ASR should match"); - assertEq(address(pdg.weth()), address(opcmOutput.delayedWETHPermissionedGameProxy), "WETH should match"); - assertEq(pdg.l2ChainId(), opcmInput.l2ChainId, "L2 chain ID should match"); - // For permissioned game, check proposer and challenger - assertEq(pdg.proposer(), opcmInput.roles.proposer, "Proposer should match"); - assertEq(pdg.challenger(), opcmInput.roles.challenger, "Challenger should match"); - } -} - -/// @title OPContractsManager_Version_Test -/// @notice Tests the `version` function of the `OPContractsManager` contract. -contract OPContractsManager_Version_Test is OPContractsManager_TestInit { - function test_semver_works() public view { - assertNotEq(abi.encode(opcm.version()), abi.encode(0)); - } -} diff --git a/packages/contracts-bedrock/test/L1/OPContractsManagerContractsContainer.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManagerContractsContainer.t.sol deleted file mode 100644 index 0028b6db8139d..0000000000000 --- a/packages/contracts-bedrock/test/L1/OPContractsManagerContractsContainer.t.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing -import { OPContractsManager_TestInit } from "test/L1/OPContractsManager.t.sol"; - -// Contracts -import { OPContractsManager, OPContractsManagerContractsContainer } from "src/L1/OPContractsManager.sol"; - -/// @title OPContractsManagerContractsContainer_Constructor_Test -/// @notice Tests the constructor of the `OPContractsManagerContractsContainer` contract. -contract OPContractsManagerContractsContainer_Constructor_Test is OPContractsManager_TestInit { - /// @notice Tests that the constructor succeeds when the devFeatureBitmap is in dev. - /// @param _devFeatureBitmap The devFeatureBitmap to use. - function testFuzz_constructor_devBitmapInDev_succeeds(bytes32 _devFeatureBitmap) public { - // Etch into the magic testing address. - vm.etch(address(0xbeefcafe), hex"01"); - - // Convert to proper OPCM type for construction. - OPContractsManager opcm2 = OPContractsManager(address(opcm)); - - // Should not revert. - OPContractsManagerContractsContainer container = new OPContractsManagerContractsContainer({ - _blueprints: opcm2.blueprints(), - _implementations: opcm2.implementations(), - _devFeatureBitmap: _devFeatureBitmap - }); - - // Should have the correct devFeatureBitmap. - assertEq(container.devFeatureBitmap(), _devFeatureBitmap); - } - - /// @notice Tests that the constructor reverts when the devFeatureBitmap is in prod. - /// @param _devFeatureBitmap The devFeatureBitmap to use. - function testFuzz_constructor_devBitmapInProd_reverts(bytes32 _devFeatureBitmap) public { - // Anything but zero! - _devFeatureBitmap = bytes32(bound(uint256(_devFeatureBitmap), 1, type(uint256).max)); - - // Make sure magic address has no code. - vm.etch(address(0xbeefcafe), bytes("")); - - // Convert to proper OPCM type for construction. - OPContractsManager opcm2 = OPContractsManager(address(opcm)); - - // Set the chain ID to 1. - vm.chainId(1); - - // Fetch ahead of time to avoid expectRevert applying to these functions by accident. - OPContractsManager.Blueprints memory blueprints = opcm2.blueprints(); - OPContractsManager.Implementations memory implementations = opcm2.implementations(); - - // Should revert. - vm.expectRevert( - OPContractsManagerContractsContainer.OPContractsManagerContractsContainer_DevFeatureInProd.selector - ); - OPContractsManagerContractsContainer container = new OPContractsManagerContractsContainer({ - _blueprints: blueprints, - _implementations: implementations, - _devFeatureBitmap: _devFeatureBitmap - }); - - // Constructor shouldn't have worked, foundry makes this return address(1). - assertEq(address(container), address(1)); - } - - /// @notice Tests that the constructor succeeds when the devFeatureBitmap is used on the - /// mainnet chain ID but this is actually a test environment as shown by the magic - /// address having code. - /// @param _devFeatureBitmap The devFeatureBitmap to use. - function test_constructor_devBitmapMainnetButTestEnv_succeeds(bytes32 _devFeatureBitmap) public { - // Make sure magic address has code. - vm.etch(address(0xbeefcafe), hex"01"); - - // Convert to proper OPCM type for construction. - OPContractsManager opcm2 = OPContractsManager(address(opcm)); - - // Set the chain ID to 1. - vm.chainId(1); - - // Should not revert. - OPContractsManagerContractsContainer container = new OPContractsManagerContractsContainer({ - _blueprints: opcm2.blueprints(), - _implementations: opcm2.implementations(), - _devFeatureBitmap: _devFeatureBitmap - }); - - // Should have the correct devFeatureBitmap. - assertEq(container.devFeatureBitmap(), _devFeatureBitmap); - } -} diff --git a/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol index eb266563bce29..739a10d4deb47 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol @@ -5,22 +5,19 @@ pragma solidity 0.8.15; import { CommonTest } from "test/setup/CommonTest.sol"; import { StandardConstants } from "scripts/deploy/StandardConstants.sol"; import { DisputeGames } from "../setup/DisputeGames.sol"; + // Libraries import { GameType, Hash } from "src/dispute/lib/LibUDT.sol"; import { GameTypes, Duration, Claim } from "src/dispute/lib/Types.sol"; import { ForgeArtifacts } from "scripts/libraries/ForgeArtifacts.sol"; import { Features } from "src/libraries/Features.sol"; -import { DevFeatures } from "src/libraries/DevFeatures.sol"; import { Config } from "scripts/libraries/Config.sol"; // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; - import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; -import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { ISemver } from "interfaces/universal/ISemver.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; @@ -40,11 +37,7 @@ import { IOPContractsManagerStandardValidator } from "interfaces/L1/IOPContracts import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol"; import { IMIPS64 } from "interfaces/cannon/IMIPS64.sol"; -import { IBigStepper } from "../../interfaces/dispute/IBigStepper.sol"; -import { IDisputeGameFactory } from "../../interfaces/dispute/IDisputeGameFactory.sol"; -import { DisputeGames } from "../setup/DisputeGames.sol"; import { IStaticERC1967Proxy } from "interfaces/universal/IStaticERC1967Proxy.sol"; -import { IDelayedWETH } from "../../interfaces/dispute/IDelayedWETH.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; @@ -115,9 +108,6 @@ contract BadVersionReturner { /// @title OPContractsManagerStandardValidator_TestInit /// @notice Base contract for `OPContractsManagerStandardValidator` tests, handles common setup. abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest { - /// @notice Deploy input that was used to deploy the contracts being tested. - IOPContractsManager.DeployInput deployInput; - /// @notice The l2ChainId, either from config or from registry if fork test. uint256 l2ChainId; @@ -159,9 +149,6 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest { } super.setUp(); - // Grab the deploy input for later use. - deployInput = deploy.getDeployInput(); - // Load the dgf dgf = IDisputeGameFactory(artifacts.mustGetAddress("DisputeGameFactoryProxy")); @@ -171,11 +158,7 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest { // Load the PreimageOracle once, we'll need it later. preimageOracle = IPreimageOracle(artifacts.mustGetAddress("PreimageOracle")); - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - standardValidator = opcmV2.opcmStandardValidator(); - } else { - standardValidator = opcm.opcmStandardValidator(); - } + standardValidator = opcmV2.opcmStandardValidator(); // Values are slightly different for fork tests vs local tests. Most we can get from // reasonable sources, challenger we need to get from live system because there's no other @@ -225,10 +208,10 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest { bytes32(uint256(uint160(standardValidator.l1PAOMultisig()))) ); } else { - l2ChainId = deployInput.l2ChainId; - cannonPrestate = deployInput.disputeAbsolutePrestate; - proposer = deployInput.roles.proposer; - challenger = deployInput.roles.challenger; + l2ChainId = deploy.cfg().l2ChainID(); + cannonPrestate = Claim.wrap(bytes32(deploy.cfg().faultGameAbsolutePrestate())); + proposer = deploy.cfg().l2OutputOracleProposer(); + challenger = deploy.cfg().l2OutputOracleChallenger(); } // Deploy the BadDisputeGameFactoryReturner once. @@ -240,86 +223,75 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest { // Load the FaultDisputeGame once, we'll need it later. fdgImpl = IFaultDisputeGame(address(disputeGameFactory.gameImpls(GameTypes.CANNON))); } else { - if (!isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - // Deploy a permissionless FaultDisputeGame. - IOPContractsManager.AddGameOutput memory output = addGameType(GameTypes.CANNON, cannonPrestate); - fdgImpl = output.faultDisputeGame; - - // Deploy cannon-kona - addGameType(GameTypes.CANNON_KONA, cannonKonaPrestate); - } else { - // Get the ProxyAdmin owner. - address owner = proxyAdmin.owner(); - - // Prepare the upgrade input. - IOPContractsManagerUtils.DisputeGameConfig[] memory disputeGameConfigs = - new IOPContractsManagerUtils.DisputeGameConfig[](6); - disputeGameConfigs[0] = IOPContractsManagerUtils.DisputeGameConfig({ - enabled: true, - initBond: disputeGameFactory.initBonds(GameTypes.CANNON), - gameType: GameTypes.CANNON, - gameArgs: abi.encode( - IOPContractsManagerUtils.FaultDisputeGameConfig({ absolutePrestate: cannonPrestate }) - ) - }); - disputeGameConfigs[1] = IOPContractsManagerUtils.DisputeGameConfig({ - enabled: true, - initBond: disputeGameFactory.initBonds(GameTypes.PERMISSIONED_CANNON), - gameType: GameTypes.PERMISSIONED_CANNON, - gameArgs: abi.encode( - IOPContractsManagerUtils.PermissionedDisputeGameConfig({ - absolutePrestate: cannonPrestate, - proposer: proposer, - challenger: challenger + // Get the ProxyAdmin owner. + address owner = proxyAdmin.owner(); + + // Prepare the upgrade input. + IOPContractsManagerUtils.DisputeGameConfig[] memory disputeGameConfigs = + new IOPContractsManagerUtils.DisputeGameConfig[](6); + disputeGameConfigs[0] = IOPContractsManagerUtils.DisputeGameConfig({ + enabled: true, + initBond: disputeGameFactory.initBonds(GameTypes.CANNON), + gameType: GameTypes.CANNON, + gameArgs: abi.encode(IOPContractsManagerUtils.FaultDisputeGameConfig({ absolutePrestate: cannonPrestate })) + }); + disputeGameConfigs[1] = IOPContractsManagerUtils.DisputeGameConfig({ + enabled: true, + initBond: disputeGameFactory.initBonds(GameTypes.PERMISSIONED_CANNON), + gameType: GameTypes.PERMISSIONED_CANNON, + gameArgs: abi.encode( + IOPContractsManagerUtils.PermissionedDisputeGameConfig({ + absolutePrestate: cannonPrestate, + proposer: proposer, + challenger: challenger + }) + ) + }); + disputeGameConfigs[2] = IOPContractsManagerUtils.DisputeGameConfig({ + enabled: true, + initBond: disputeGameFactory.initBonds(GameTypes.CANNON_KONA), + gameType: GameTypes.CANNON_KONA, + gameArgs: abi.encode( + IOPContractsManagerUtils.FaultDisputeGameConfig({ absolutePrestate: cannonKonaPrestate }) + ) + }); + disputeGameConfigs[3] = IOPContractsManagerUtils.DisputeGameConfig({ + enabled: false, + initBond: 0, + gameType: GameTypes.SUPER_CANNON, + gameArgs: hex"" + }); + disputeGameConfigs[4] = IOPContractsManagerUtils.DisputeGameConfig({ + enabled: false, + initBond: 0, + gameType: GameTypes.SUPER_PERMISSIONED_CANNON, + gameArgs: hex"" + }); + disputeGameConfigs[5] = IOPContractsManagerUtils.DisputeGameConfig({ + enabled: false, + initBond: 0, + gameType: GameTypes.SUPER_CANNON_KONA, + gameArgs: hex"" + }); + + // Call upgrade to all games to be enabled. + prankDelegateCall(owner); + (bool success,) = address(opcmV2).delegatecall( + abi.encodeCall( + IOPContractsManagerV2.upgrade, + ( + IOPContractsManagerV2.UpgradeInput({ + systemConfig: systemConfig, + disputeGameConfigs: disputeGameConfigs, + extraInstructions: new IOPContractsManagerUtils.ExtraInstruction[](0) }) ) - }); - disputeGameConfigs[2] = IOPContractsManagerUtils.DisputeGameConfig({ - enabled: true, - initBond: disputeGameFactory.initBonds(GameTypes.CANNON_KONA), - gameType: GameTypes.CANNON_KONA, - gameArgs: abi.encode( - IOPContractsManagerUtils.FaultDisputeGameConfig({ absolutePrestate: cannonKonaPrestate }) - ) - }); - disputeGameConfigs[3] = IOPContractsManagerUtils.DisputeGameConfig({ - enabled: false, - initBond: 0, - gameType: GameTypes.SUPER_CANNON, - gameArgs: hex"" - }); - disputeGameConfigs[4] = IOPContractsManagerUtils.DisputeGameConfig({ - enabled: false, - initBond: 0, - gameType: GameTypes.SUPER_PERMISSIONED_CANNON, - gameArgs: hex"" - }); - disputeGameConfigs[5] = IOPContractsManagerUtils.DisputeGameConfig({ - enabled: false, - initBond: 0, - gameType: GameTypes.SUPER_CANNON_KONA, - gameArgs: hex"" - }); - - // Call upgrade to all games to be enabled. - prankDelegateCall(owner); - (bool success,) = address(opcmV2).delegatecall( - abi.encodeCall( - IOPContractsManagerV2.upgrade, - ( - IOPContractsManagerV2.UpgradeInput({ - systemConfig: systemConfig, - disputeGameConfigs: disputeGameConfigs, - extraInstructions: new IOPContractsManagerUtils.ExtraInstruction[](0) - }) - ) - ) - ); - assertTrue(success, "upgrade failed"); + ) + ); + assertTrue(success, "upgrade failed"); - // Grab the FaultDisputeGame implementation. - fdgImpl = IFaultDisputeGame(address(disputeGameFactory.gameImpls(GameTypes.CANNON))); - } + // Grab the FaultDisputeGame implementation. + fdgImpl = IFaultDisputeGame(address(disputeGameFactory.gameImpls(GameTypes.CANNON))); } } @@ -373,61 +345,6 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest { challenger: address(0) }); } - - function addGameType( - GameType _gameType, - Claim _prestate - ) - internal - returns (IOPContractsManager.AddGameOutput memory) - { - IOPContractsManager.AddGameInput memory input = newGameInputFactory(_gameType, _prestate); - return addGameType(input); - } - - function addGameType(IOPContractsManager.AddGameInput memory input) - internal - returns (IOPContractsManager.AddGameOutput memory) - { - IOPContractsManager.AddGameInput[] memory inputs = new IOPContractsManager.AddGameInput[](1); - inputs[0] = input; - - address owner = deployInput.roles.opChainProxyAdminOwner; - vm.startPrank(address(owner), address(owner), true); - (bool success, bytes memory rawGameOut) = - address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.addGameType, (inputs))); - assertTrue(success, "addGameType failed"); - vm.stopPrank(); - - IOPContractsManager.AddGameOutput[] memory addGameOutAll = - abi.decode(rawGameOut, (IOPContractsManager.AddGameOutput[])); - return addGameOutAll[0]; - } - - function newGameInputFactory( - GameType _gameType, - Claim _prestate - ) - internal - view - returns (IOPContractsManager.AddGameInput memory) - { - return IOPContractsManager.AddGameInput({ - saltMixer: "hello", - systemConfig: systemConfig, - delayedWETH: delayedWeth, - disputeGameType: _gameType, - disputeAbsolutePrestate: _prestate, - disputeMaxGameDepth: 73, - disputeSplitDepth: 30, - disputeClockExtension: Duration.wrap(10800), - disputeMaxClockDuration: Duration.wrap(302400), - initialBond: 1 ether, - vm: IBigStepper(address(opcm.implementations().mipsImpl)), - permissioned: _gameType.raw() == GameTypes.PERMISSIONED_CANNON.raw() - || _gameType.raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw() - }); - } } /// @title OPContractsManagerStandardValidator_CoreValidation_Test @@ -1382,19 +1299,7 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana /// DelayedWETH version is invalid. function test_validate_delayedWETHInvalidVersion_succeeds() public { vm.mockCall(address(delayedWeth), abi.encodeCall(ISemver.version, ()), abi.encode("0.0.1")); - - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - assertEq("PDDG-DWETH-10,PLDG-DWETH-10,CKDG-DWETH-10", _validate(true)); - } else { - // One last mess here, during local tests delayedWeth refers to the contract attached to - // the FaultDisputeGame, but during fork tests it refers to the one attached to the - // PermissionedDisputeGame. We'll just branch based on the test type. - if (isL1ForkTest()) { - assertEq("PDDG-DWETH-10", _validate(true)); - } else { - assertEq("PLDG-DWETH-10,CKDG-DWETH-10", _validate(true)); - } - } + assertEq("PDDG-DWETH-10,PLDG-DWETH-10,CKDG-DWETH-10", _validate(true)); } /// @notice Tests that the validate function successfully returns the right error when the @@ -1405,16 +1310,7 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana abi.encodeCall(IProxyAdmin.getProxyImplementation, (address(delayedWeth))), abi.encode(address(0xbad)) ); - - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - assertEq("PDDG-DWETH-20,PLDG-DWETH-20,CKDG-DWETH-20", _validate(true)); - } else { - if (isL1ForkTest()) { - assertEq("PDDG-DWETH-20", _validate(true)); - } else { - assertEq("PLDG-DWETH-20,CKDG-DWETH-20", _validate(true)); - } - } + assertEq("PDDG-DWETH-20,PLDG-DWETH-20,CKDG-DWETH-20", _validate(true)); } /// @notice Tests that the validate function successfully returns the right error when the @@ -1423,48 +1319,21 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana vm.mockCall( address(delayedWeth), abi.encodeCall(IProxyAdminOwnedBase.proxyAdminOwner, ()), abi.encode(address(0xbad)) ); - - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - assertEq("PDDG-DWETH-30,PLDG-DWETH-30,CKDG-DWETH-30", _validate(true)); - } else { - if (isL1ForkTest()) { - assertEq("PDDG-DWETH-30", _validate(true)); - } else { - assertEq("PLDG-DWETH-30,CKDG-DWETH-30", _validate(true)); - } - } + assertEq("PDDG-DWETH-30,PLDG-DWETH-30,CKDG-DWETH-30", _validate(true)); } /// @notice Tests that the validate function successfully returns the right error when the /// DelayedWETH delay is invalid. function test_validate_delayedWETHInvalidDelay_succeeds() public { vm.mockCall(address(delayedWeth), abi.encodeCall(IDelayedWETH.delay, ()), abi.encode(1000)); - - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - assertEq("PDDG-DWETH-40,PLDG-DWETH-40,CKDG-DWETH-40", _validate(true)); - } else { - if (isL1ForkTest()) { - assertEq("PDDG-DWETH-40", _validate(true)); - } else { - assertEq("PLDG-DWETH-40,CKDG-DWETH-40", _validate(true)); - } - } + assertEq("PDDG-DWETH-40,PLDG-DWETH-40,CKDG-DWETH-40", _validate(true)); } /// @notice Tests that the validate function successfully returns the right error when the /// DelayedWETH systemConfig is invalid. function test_validate_delayedWETHInvalidSystemConfig_succeeds() public { vm.mockCall(address(delayedWeth), abi.encodeCall(IDelayedWETH.systemConfig, ()), abi.encode(address(0xbad))); - - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - assertEq("PDDG-DWETH-50,PLDG-DWETH-50,CKDG-DWETH-50", _validate(true)); - } else { - if (isL1ForkTest()) { - assertEq("PDDG-DWETH-50", _validate(true)); - } else { - assertEq("PLDG-DWETH-50,CKDG-DWETH-50", _validate(true)); - } - } + assertEq("PDDG-DWETH-50,PLDG-DWETH-50,CKDG-DWETH-50", _validate(true)); } /// @notice Tests that the validate function successfully returns the right error when the @@ -1473,16 +1342,7 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana vm.mockCall( address(delayedWeth), abi.encodeCall(IProxyAdminOwnedBase.proxyAdmin, ()), abi.encode(address(0xbad)) ); - - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - assertEq("PDDG-DWETH-60,PLDG-DWETH-60,CKDG-DWETH-60", _validate(true)); - } else { - if (isL1ForkTest()) { - assertEq("PDDG-DWETH-60", _validate(true)); - } else { - assertEq("PLDG-DWETH-60,CKDG-DWETH-60", _validate(true)); - } - } + assertEq("PDDG-DWETH-60,PLDG-DWETH-60,CKDG-DWETH-60", _validate(true)); } } @@ -1892,11 +1752,10 @@ abstract contract OPContractsManagerStandardValidator_SuperMode_TestInit is Comm dgf = IDisputeGameFactory(artifacts.mustGetAddress("DisputeGameFactoryProxy")); standardValidator = opcmV2.opcmStandardValidator(); - IOPContractsManager.DeployInput memory deployInput = deploy.getDeployInput(); - l2ChainId = deployInput.l2ChainId; - cannonPrestate = deployInput.disputeAbsolutePrestate; - proposer = deployInput.roles.proposer; - challenger = deployInput.roles.challenger; + l2ChainId = deploy.cfg().l2ChainID(); + cannonPrestate = Claim.wrap(bytes32(deploy.cfg().faultGameAbsolutePrestate())); + proposer = deploy.cfg().l2OutputOracleProposer(); + challenger = deploy.cfg().l2OutputOracleChallenger(); // The deploy created SUPER_PERMISSIONED_CANNON (enabled) + SUPER_CANNON_KONA (disabled). // Run an upgrade to also enable SUPER_CANNON_KONA so that full validation passes. diff --git a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol index 1ee10710236bd..e4635d1b6c9e9 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol @@ -11,7 +11,6 @@ import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.so import { Constants } from "src/libraries/Constants.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Features } from "src/libraries/Features.sol"; -import { DevFeatures } from "src/libraries/DevFeatures.sol"; // Interfaces import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; @@ -989,9 +988,7 @@ contract SystemConfig_IsCustomGasToken_Test is SystemConfig_TestInit { contract SystemConfig_LastUsedOPCM_Test is SystemConfig_TestInit { /// @notice Tests that `lastUsedOPCM` returns the correct OPCM V2 address and that /// `lastUsedOPCMVersion` matches the OPCM V2 version. - function test_lastUsedOPCM_opcmV2_succeeds() external { - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - + function test_lastUsedOPCM_opcmV2_succeeds() external view { // Verify that the lastUsedOPCM address matches the deployed OPCM V2 address assertEq(systemConfig.lastUsedOPCM(), address(opcmV2)); diff --git a/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol b/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol index f0eaf39ec0538..d3eb2c62a91b9 100644 --- a/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol +++ b/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol @@ -13,9 +13,9 @@ import { Config } from "scripts/libraries/Config.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Claim, Hash } from "src/dispute/lib/LibUDT.sol"; import { GameType, GameTypes, Proposal } from "src/dispute/lib/Types.sol"; +import { Constants } from "src/libraries/Constants.sol"; import { DevFeatures } from "src/libraries/DevFeatures.sol"; import { Features } from "src/libraries/Features.sol"; -import { Constants } from "src/libraries/Constants.sol"; // Interfaces import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; @@ -52,7 +52,6 @@ contract OPContractsManagerV2_TestInit is CommonTest { /// @notice Sets up the test suite. function setUp() public virtual override { super.setUp(); - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); } /// @notice Helper function that runs an OPCM V2 deploy, asserts that the deploy was successful, @@ -501,8 +500,6 @@ contract OPContractsManagerV2_Upgrade_Test is OPContractsManagerV2_Upgrade_TestI /// @notice Tests that the upgrade function succeeds when executed normally. function test_upgrade_succeeds() public { - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - // Run the upgrade test and checks runCurrentUpgradeV2(chainPAO); } @@ -510,8 +507,6 @@ contract OPContractsManagerV2_Upgrade_Test is OPContractsManagerV2_Upgrade_TestI /// @notice Tests that calling upgrade twice does not revert, ensuring the upgrade function /// has no one-time-only state transitions that would block a subsequent upgrade call. function test_upgrade_calledTwice_succeeds() public { - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - runCurrentUpgradeV2(chainPAO); runCurrentUpgradeV2(chainPAO); } @@ -754,8 +749,6 @@ contract OPContractsManagerV2_Upgrade_Test is OPContractsManagerV2_Upgrade_TestI /// @notice Tests that the upgrade flow can update the Cannon and Permissioned prestate. function test_upgrade_updatePrestate_succeeds() public { - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - // Run baseline upgrade and capture the current prestates. runCurrentUpgradeV2(chainPAO); assertEq( @@ -838,8 +831,6 @@ contract OPContractsManagerV2_Upgrade_Test is OPContractsManagerV2_Upgrade_TestI /// even when the SuperchainConfig has the system globally paused. This is critical /// because upgrades may be needed during incident response when the system is paused. function test_upgrade_whenPaused_succeeds() public { - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - // First, pause the system globally using the guardian. address guardian = superchainConfig.guardian(); vm.prank(guardian); @@ -1387,11 +1378,7 @@ contract OPContractsManagerV2_IsPermittedUpgradeSequence_Test is OPContractsMana address oldOPCM = makeAddr("oldOPCM"); // Mock the current OPCM version to be 7.0.0 (below threshold). - vm.mockCall( - address(opcmV2), - abi.encodeCall(IOPContractsManagerV2.version, ()), - abi.encode(Constants.OPCM_V2_MIN_VERSION) - ); + vm.mockCall(address(opcmV2), abi.encodeCall(IOPContractsManagerV2.version, ()), abi.encode("7.0.0")); // Mock lastUsedOPCM to return the old OPCM address. vm.mockCall(address(systemConfig), abi.encodeCall(ISystemConfig.lastUsedOPCM, ()), abi.encode(oldOPCM)); @@ -2100,6 +2087,11 @@ contract OPContractsManagerV2_Migrate_Test is OPContractsManagerV2_TestInit { /// @param _owner2 The owner address for the second chain's ProxyAdmin. function testFuzz_migrate_mismatchedProxyAdminOwners_reverts(address _owner1, address _owner2) public { vm.assume(_owner1 != _owner2); + // Exclude the OPCM address itself: when the pranked delegate-call address equals + // address(opcmV2), the _onlyDelegateCall guard reverts before the owner check, + // producing a different revert selector than this test expects. + vm.assume(_owner1 != address(opcmV2)); + vm.assume(_owner2 != address(opcmV2)); assumeNotPrecompile(_owner1); assumeNotPrecompile(_owner2); assumeNotForgeAddress(_owner1); diff --git a/packages/contracts-bedrock/test/L2/L2DevFeatureFlags.t.sol b/packages/contracts-bedrock/test/L2/L2DevFeatureFlags.t.sol index bd91616d734d4..0e277961dc8fe 100644 --- a/packages/contracts-bedrock/test/L2/L2DevFeatureFlags.t.sol +++ b/packages/contracts-bedrock/test/L2/L2DevFeatureFlags.t.sol @@ -102,6 +102,5 @@ contract L2DevFeatureFlags_IsDevFeatureEnabled_Test is L2DevFeatureFlags_TestIni assertTrue(l2DevFeatureFlags.isDevFeatureEnabled(DevFeatures.OPTIMISM_PORTAL_INTEROP)); assertTrue(l2DevFeatureFlags.isDevFeatureEnabled(DevFeatures.CANNON_KONA)); - assertFalse(l2DevFeatureFlags.isDevFeatureEnabled(DevFeatures.OPCM_V2)); } } diff --git a/packages/contracts-bedrock/test/opcm/DeployImplementations.t.sol b/packages/contracts-bedrock/test/opcm/DeployImplementations.t.sol index 3696f339d2742..521be152f1eca 100644 --- a/packages/contracts-bedrock/test/opcm/DeployImplementations.t.sol +++ b/packages/contracts-bedrock/test/opcm/DeployImplementations.t.sol @@ -167,7 +167,7 @@ contract DeployImplementations_Test is Test, FeatureFlags { assertEq(address(output1.mipsSingleton), address(output2.mipsSingleton), "900"); assertEq(address(output1.disputeGameFactoryImpl), address(output2.disputeGameFactoryImpl), "1000"); assertEq(address(output1.anchorStateRegistryImpl), address(output2.anchorStateRegistryImpl), "1100"); - assertEq(address(output1.opcm), address(output2.opcm), "1200"); + assertEq(address(output1.opcmV2), address(output2.opcmV2), "1200"); assertEq(address(output1.ethLockboxImpl), address(output2.ethLockboxImpl), "1300"); assertEq(address(output1.faultDisputeGameImpl), address(output2.faultDisputeGameImpl), "1400"); assertEq(address(output1.permissionedDisputeGameImpl), address(output2.permissionedDisputeGameImpl), "1500"); @@ -248,9 +248,6 @@ contract DeployImplementations_Test is Test, FeatureFlags { DeployImplementations.Output memory output = deployImplementations.run(input); - // Check which OPCM version is deployed - bool opcmV2Enabled = DevFeatures.isDevFeatureEnabled(_devFeatureBitmap, DevFeatures.OPCM_V2); - // Basic assertions assertNotEq(address(output.anchorStateRegistryImpl), address(0), "100"); assertNotEq(address(output.delayedWETHImpl), address(0), "200"); @@ -261,25 +258,9 @@ contract DeployImplementations_Test is Test, FeatureFlags { assertNotEq(address(output.l1StandardBridgeImpl), address(0), "600"); assertNotEq(address(output.mipsSingleton), address(0), "700"); - // OPCM version-specific assertions - if (opcmV2Enabled) { - assertNotEq(address(output.opcmV2), address(0), "800"); - assertNotEq(address(output.opcmContainer), address(0), "900"); - assertNotEq(address(output.opcmStandardValidator), address(0), "1000"); - // V1 contracts should be null when V2 is enabled - assertEq(address(output.opcm), address(0), "800-v1"); - assertEq(address(output.opcmContractsContainer), address(0), "900-v1"); - assertEq(address(output.opcmDeployer), address(0), "1000-v1"); - assertEq(address(output.opcmGameTypeAdder), address(0), "1100-v1"); - } else { - assertNotEq(address(output.opcm), address(0), "800"); - assertNotEq(address(output.opcmContractsContainer), address(0), "900"); - assertNotEq(address(output.opcmDeployer), address(0), "1000"); - assertNotEq(address(output.opcmGameTypeAdder), address(0), "1100"); - // V2 contracts should be null when V1 is enabled - assertEq(address(output.opcmV2), address(0), "800-v2"); - assertEq(address(output.opcmContainer), address(0), "900-v2"); - } + assertNotEq(address(output.opcmV2), address(0), "800"); + assertNotEq(address(output.opcmContainer), address(0), "900"); + assertNotEq(address(output.opcmStandardValidator), address(0), "1000"); assertNotEq(address(output.faultDisputeGameImpl), address(0), "V2 should be deployed when enabled"); assertNotEq(address(output.permissionedDisputeGameImpl), address(0), "V2 should be deployed when enabled"); @@ -375,25 +356,9 @@ contract DeployImplementations_Test is Test, FeatureFlags { assertNotEq(address(output.l1StandardBridgeImpl).code, empty, "1800"); assertNotEq(address(output.mipsSingleton).code, empty, "1900"); - // OPCM version-specific code assertions - if (opcmV2Enabled) { - assertNotEq(address(output.opcmV2).code, empty, "2000"); - assertNotEq(address(output.opcmContainer).code, empty, "2100"); - assertNotEq(address(output.opcmStandardValidator).code, empty, "2200"); - // V1 contracts should be empty when V2 is enabled - assertEq(address(output.opcm).code, empty, "2000-v1"); - assertEq(address(output.opcmContractsContainer).code, empty, "2100-v1"); - assertEq(address(output.opcmDeployer).code, empty, "2200-v1"); - assertEq(address(output.opcmGameTypeAdder).code, empty, "2300-v1"); - } else { - assertNotEq(address(output.opcm).code, empty, "2000"); - assertNotEq(address(output.opcmContractsContainer).code, empty, "2100"); - assertNotEq(address(output.opcmDeployer).code, empty, "2200"); - assertNotEq(address(output.opcmGameTypeAdder).code, empty, "2300"); - // V2 contracts should be empty when V1 is enabled - assertEq(address(output.opcmV2).code, empty, "2000-v2"); - assertEq(address(output.opcmContainer).code, empty, "2100-v2"); - } + assertNotEq(address(output.opcmV2).code, empty, "2000"); + assertNotEq(address(output.opcmContainer).code, empty, "2100"); + assertNotEq(address(output.opcmStandardValidator).code, empty, "2200"); assertNotEq(address(output.faultDisputeGameImpl).code, empty, "V2 FDG should have code when enabled"); assertNotEq(address(output.permissionedDisputeGameImpl).code, empty, "V2 PDG should have code when enabled"); diff --git a/packages/contracts-bedrock/test/opcm/DeployOPChain.t.sol b/packages/contracts-bedrock/test/opcm/DeployOPChain.t.sol index 2e846db55bad6..78622cc284e1a 100644 --- a/packages/contracts-bedrock/test/opcm/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/DeployOPChain.t.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.15; // Testing import { Test } from "test/setup/Test.sol"; import { FeatureFlags } from "test/setup/FeatureFlags.sol"; -import { DevFeatures } from "src/libraries/DevFeatures.sol"; // Scripts import { DeploySuperchain } from "scripts/deploy/DeploySuperchain.s.sol"; @@ -15,9 +14,11 @@ import { Types } from "scripts/libraries/Types.sol"; // Libraries import { Features } from "src/libraries/Features.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; +import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; +import { IOPContractsManagerContainer } from "interfaces/L1/opcm/IOPContractsManagerContainer.sol"; import { Claim, Duration, GameType, GameTypes } from "src/dispute/lib/Types.sol"; import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; @@ -109,9 +110,7 @@ contract DeployOPChain_TestBase is Test, FeatureFlags { devFeatureBitmap: devFeatureBitmap }) ); - // Select OPCM v1 or v2 based on feature flag - opcmAddr = isDevFeatureEnabled(DevFeatures.OPCM_V2) ? address(dio.opcmV2) : address(dio.opcm); - vm.label(address(dio.opcm), "opcm"); + opcmAddr = address(dio.opcmV2); vm.label(address(dio.opcmV2), "opcmV2"); // Set superchainConfig from deployment @@ -172,19 +171,12 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { DeployOPChain.Output memory doo = deployOPChain.run(deployOPChainInput); - // Skip init bond checks for OPCM v2 (bonds are set during deployment, not zero) - if (!isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - // Verify that the initial bonds are zero for OPCM v1. - assertEq(doo.disputeGameFactoryProxy.initBonds(GameTypes.CANNON), 0, "2700"); - assertEq(doo.disputeGameFactoryProxy.initBonds(GameTypes.PERMISSIONED_CANNON), 0, "2800"); - } - // Check dispute game deployments // Validate permissionedDisputeGame (PDG) address GameType permGameType = isDevFeatureEnabled(DevFeatures.SUPER_ROOT_GAMES_MIGRATION) ? GameTypes.SUPER_PERMISSIONED_CANNON : GameTypes.PERMISSIONED_CANNON; - IOPContractsManager.Implementations memory impls = IOPContractsManager(opcmAddr).implementations(); + IOPContractsManagerContainer.Implementations memory impls = IOPContractsManagerV2(opcmAddr).implementations(); address expectedPDGAddress = isDevFeatureEnabled(DevFeatures.SUPER_ROOT_GAMES_MIGRATION) ? impls.superPermissionedDisputeGameImpl : impls.permissionedDisputeGameImpl; @@ -192,19 +184,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { assertNotEq(actualPDGAddress, address(0), "PDG address should be non-zero"); assertEq(actualPDGAddress, expectedPDGAddress, "PDG address should match expected address"); - // Skip PDG getter checks for OPCM v2 (game args are passed at creation time) - if (!isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - // Check PDG getters - IPermissionedDisputeGame pdg = IPermissionedDisputeGame(actualPDGAddress); - bytes32 expectedPrestate = bytes32(0); - assertEq(pdg.l2BlockNumber(), 0, "3000"); - assertEq(Claim.unwrap(pdg.absolutePrestate()), expectedPrestate, "3100"); - assertEq(Duration.unwrap(pdg.clockExtension()), 10800, "3200"); - assertEq(Duration.unwrap(pdg.maxClockDuration()), 302400, "3300"); - assertEq(pdg.splitDepth(), 30, "3400"); - assertEq(pdg.maxGameDepth(), 73, "3500"); - } - // Verify custom gas token feature is set as seeded assertEq( doo.systemConfigProxy.isCustomGasToken(), @@ -251,16 +230,12 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { } function test_run_cannonGameType_reverts() public { - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - deployOPChainInput.disputeGameType = GameTypes.CANNON; vm.expectRevert("DeployOPChain: only PERMISSIONED_CANNON game type is supported for initial deployment"); deployOPChain.run(deployOPChainInput); } function test_run_cannonKonaGameType_reverts() public { - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - deployOPChainInput.disputeGameType = GameTypes.CANNON_KONA; vm.expectRevert("DeployOPChain: only PERMISSIONED_CANNON game type is supported for initial deployment"); deployOPChain.run(deployOPChainInput); @@ -269,8 +244,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { /// @notice Tests that faultDisputeGame is set to address(0) and permissionedDisputeGame is set to the correct /// implementation for GameTypes.PERMISSIONED_CANNON. function test_run_faultDisputeGamePermissionedCannon_succeeds() public { - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - deployOPChainInput.disputeGameType = GameTypes.PERMISSIONED_CANNON; DeployOPChain.Output memory doo = deployOPChain.run(deployOPChainInput); @@ -317,34 +290,31 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { "superchainConfig mismatch" ); - // OPCM v2 specific assertions - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - bool isSuperRoot = isDevFeatureEnabled(DevFeatures.SUPER_ROOT_GAMES_MIGRATION); - GameType permType = isSuperRoot ? GameTypes.SUPER_PERMISSIONED_CANNON : GameTypes.PERMISSIONED_CANNON; - GameType konaType = isSuperRoot ? GameTypes.SUPER_CANNON_KONA : GameTypes.CANNON_KONA; - - // Permissioned game must always be enabled with DEFAULT_INIT_BOND init bond - assertEq(doo.disputeGameFactoryProxy.initBonds(permType), deployOPChain.DEFAULT_INIT_BOND()); - assertNotEq(address(doo.disputeGameFactoryProxy.gameImpls(permType)), address(0)); - - // CANNON must be disabled for initial deployment (not deployed for super root path) - if (!isSuperRoot) { - assertEq(doo.disputeGameFactoryProxy.initBonds(GameTypes.CANNON), 0, "CANNON init bond should be 0"); - assertEq( - address(doo.disputeGameFactoryProxy.gameImpls(GameTypes.CANNON)), - address(0), - "CANNON impl should be the zero address" - ); - } - - // Kona must be disabled for initial deployment - assertEq(doo.disputeGameFactoryProxy.initBonds(konaType), 0, "CANNON_KONA init bond should be 0"); + bool isSuperRoot = isDevFeatureEnabled(DevFeatures.SUPER_ROOT_GAMES_MIGRATION); + GameType permType = isSuperRoot ? GameTypes.SUPER_PERMISSIONED_CANNON : GameTypes.PERMISSIONED_CANNON; + GameType konaType = isSuperRoot ? GameTypes.SUPER_CANNON_KONA : GameTypes.CANNON_KONA; + + // Permissioned game must always be enabled with DEFAULT_INIT_BOND init bond + assertEq(doo.disputeGameFactoryProxy.initBonds(permType), deployOPChain.DEFAULT_INIT_BOND()); + assertNotEq(address(doo.disputeGameFactoryProxy.gameImpls(permType)), address(0)); + + // CANNON must be disabled for initial deployment (not deployed for super root path) + if (!isSuperRoot) { + assertEq(doo.disputeGameFactoryProxy.initBonds(GameTypes.CANNON), 0, "CANNON init bond should be 0"); assertEq( - address(doo.disputeGameFactoryProxy.gameImpls(konaType)), + address(doo.disputeGameFactoryProxy.gameImpls(GameTypes.CANNON)), address(0), - "CANNON_KONA impl should be the zero address" + "CANNON impl should be the zero address" ); } + + // Kona must be disabled for initial deployment + assertEq(doo.disputeGameFactoryProxy.initBonds(konaType), 0, "CANNON_KONA init bond should be 0"); + assertEq( + address(doo.disputeGameFactoryProxy.gameImpls(konaType)), + address(0), + "CANNON_KONA impl should be the zero address" + ); } } diff --git a/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol b/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol index ac909974eb2bf..8a0d39eccb728 100644 --- a/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol +++ b/packages/contracts-bedrock/test/opcm/InteropMigration.t.sol @@ -8,10 +8,9 @@ import { Test } from "test/setup/Test.sol"; import { InteropMigrationInput, InteropMigration, InteropMigrationOutput } from "scripts/deploy/InteropMigration.s.sol"; // Libraries -import { Claim, Duration, Hash, GameType, Proposal } from "src/dispute/lib/Types.sol"; +import { Hash, GameType, Proposal } from "src/dispute/lib/Types.sol"; // Interfaces -import { IOPContractsManagerInteropMigrator, IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerMigrator } from "interfaces/L1/opcm/IOPContractsManagerMigrator.sol"; import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPortal2.sol"; @@ -46,40 +45,6 @@ contract InteropMigrationInput_Test is Test { assertEq(input.opcm(), mockOPCM); } - function test_setMigrateInputV1_succeeds() public { - // Create sample V1 input - IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](1); - address systemConfig1 = makeAddr("systemConfig1"); - vm.etch(systemConfig1, hex"01"); - - configs[0] = IOPContractsManager.OpChainConfig({ - systemConfigProxy: ISystemConfig(systemConfig1), - cannonPrestate: Claim.wrap(bytes32(uint256(1))), - cannonKonaPrestate: Claim.wrap(bytes32(uint256(11))) - }); - - IOPContractsManagerInteropMigrator.MigrateInput memory migrateInput = IOPContractsManagerInteropMigrator - .MigrateInput({ - usePermissionlessGame: true, - startingAnchorRoot: Proposal({ root: Hash.wrap(bytes32(uint256(1))), l2SequenceNumber: 100 }), - gameParameters: IOPContractsManagerInteropMigrator.GameParameters({ - proposer: makeAddr("proposer"), - challenger: makeAddr("challenger"), - maxGameDepth: 73, - splitDepth: 30, - initBond: 1 ether, - clockExtension: Duration.wrap(10800), - maxClockDuration: Duration.wrap(302400) - }), - opChainConfigs: configs - }); - - input.set(input.migrateInput.selector, migrateInput); - - bytes memory storedInput = input.migrateInput(); - assertEq(storedInput, abi.encode(migrateInput)); - } - function test_setMigrateInputV2_succeeds() public { // Create sample V2 input ISystemConfig[] memory systemConfigs = new ISystemConfig[](1); @@ -124,23 +89,10 @@ contract InteropMigrationInput_Test is Test { } contract MockOPCM { - event MigrateV1Called(address indexed sysCfgProxy, bytes32 indexed cannonPrestate); event MigrateV2Called(address indexed sysCfg, uint32 indexed gameType); - bool public opcmV2Enabled; - - constructor(bool _opcmV2Enabled) { - opcmV2Enabled = _opcmV2Enabled; - } - - function version() public view returns (string memory) { - return opcmV2Enabled ? "7.0.0" : "6.0.0"; - } - - function migrate(IOPContractsManagerInteropMigrator.MigrateInput memory _input) public { - emit MigrateV1Called( - address(_input.opChainConfigs[0].systemConfigProxy), Claim.unwrap(_input.opChainConfigs[0].cannonPrestate) - ); + function version() public pure returns (string memory) { + return "7.0.0"; } function migrate(IOPContractsManagerMigrator.MigrateInput memory _input) public { @@ -149,18 +101,8 @@ contract MockOPCM { } contract MockOPCMRevert { - bool public opcmV2Enabled; - - constructor(bool _opcmV2Enabled) { - opcmV2Enabled = _opcmV2Enabled; - } - - function version() public view returns (string memory) { - return opcmV2Enabled ? "7.0.0" : "6.0.0"; - } - - function migrate(IOPContractsManagerInteropMigrator.MigrateInput memory /*_input*/ ) public pure { - revert("MockOPCMRevert: revert migrate"); + function version() public pure returns (string memory) { + return "7.0.0"; } function migrate(IOPContractsManagerMigrator.MigrateInput memory /*_input*/ ) public pure { @@ -168,101 +110,6 @@ contract MockOPCMRevert { } } -contract InteropMigrationV1_Test is Test { - MockOPCM mockOPCM; - MockOPCMRevert mockOPCMRevert; - InteropMigrationInput input; - IOPContractsManager.OpChainConfig config; - InteropMigration migration; - address prank; - - event MigrateV1Called(address indexed sysCfgProxy, bytes32 indexed cannonPrestate); - - function setUp() public { - // Create mock OPCM with V2 disabled - mockOPCM = new MockOPCM(false); - input = new InteropMigrationInput(); - input.set(input.opcm.selector, address(mockOPCM)); - - // Setup V1 migration input - address systemConfig = makeAddr("systemConfigProxy"); - vm.etch(systemConfig, hex"01"); - - config = IOPContractsManager.OpChainConfig({ - systemConfigProxy: ISystemConfig(systemConfig), - cannonPrestate: Claim.wrap(keccak256("cannonPrestate")), - cannonKonaPrestate: Claim.wrap(keccak256("cannonKonaPrestate")) - }); - - IOPContractsManager.OpChainConfig[] memory configs = new IOPContractsManager.OpChainConfig[](1); - configs[0] = config; - - IOPContractsManagerInteropMigrator.MigrateInput memory migrateInput = IOPContractsManagerInteropMigrator - .MigrateInput({ - usePermissionlessGame: true, - startingAnchorRoot: Proposal({ root: Hash.wrap(bytes32(uint256(1))), l2SequenceNumber: 100 }), - gameParameters: IOPContractsManagerInteropMigrator.GameParameters({ - proposer: makeAddr("proposer"), - challenger: makeAddr("challenger"), - maxGameDepth: 73, - splitDepth: 30, - initBond: 1 ether, - clockExtension: Duration.wrap(10800), - maxClockDuration: Duration.wrap(302400) - }), - opChainConfigs: configs - }); - - input.set(input.migrateInput.selector, migrateInput); - - prank = makeAddr("prank"); - input.set(input.prank.selector, prank); - - migration = new InteropMigration(); - } - - function test_migrateV1_succeeds() public { - // MigrateV1Called should be emitted by the prank since it's a delegatecall. - vm.expectEmit(address(prank)); - emit MigrateV1Called(address(config.systemConfigProxy), Claim.unwrap(config.cannonPrestate)); - - // mocks for post-migration checks - address portal = makeAddr("optimismPortal"); - address dgf = makeAddr("disputeGameFactory"); - vm.mockCall( - address(config.systemConfigProxy), abi.encodeCall(ISystemConfig.optimismPortal, ()), abi.encode(portal) - ); - vm.etch(dgf, hex"01"); - vm.mockCall(portal, abi.encodeCall(IOptimismPortal.disputeGameFactory, ()), abi.encode(dgf)); - - InteropMigrationOutput output = new InteropMigrationOutput(); - migration.run(input, output); - - assertEq(address(output.disputeGameFactory()), dgf); - } - - function test_migrateV1_migrate_reverts() public { - // Set mock OPCM to revert on migrate - mockOPCMRevert = new MockOPCMRevert(false); - input.set(input.opcm.selector, address(mockOPCMRevert)); - - InteropMigrationOutput output = new InteropMigrationOutput(); - vm.expectRevert("MockOPCMRevert: revert migrate"); - migration.run(input, output); - } - - function test_opcmV1_withNoCode_reverts() public { - // Set an address with no code as OPCM - address emptyOPCM = makeAddr("emptyOPCM"); - input.set(input.opcm.selector, emptyOPCM); - - InteropMigrationOutput output = new InteropMigrationOutput(); - - vm.expectRevert("InteropMigration: OPCM address has no code"); - migration.run(input, output); - } -} - contract InteropMigrationV2_Test is Test { MockOPCM mockOPCM; MockOPCMRevert mockOPCMRevert; @@ -274,8 +121,7 @@ contract InteropMigrationV2_Test is Test { event MigrateV2Called(address indexed sysCfg, uint32 indexed gameType); function setUp() public { - // Create mock OPCM with V2 enabled - mockOPCM = new MockOPCM(true); + mockOPCM = new MockOPCM(); input = new InteropMigrationInput(); input.set(input.opcm.selector, address(mockOPCM)); @@ -330,8 +176,7 @@ contract InteropMigrationV2_Test is Test { } function test_migrateV2_migrate_reverts() public { - // Set mock OPCM with V2 enabled to revert on migrate - mockOPCMRevert = new MockOPCMRevert(true); + mockOPCMRevert = new MockOPCMRevert(); input.set(input.opcm.selector, address(mockOPCMRevert)); InteropMigrationOutput output = new InteropMigrationOutput(); diff --git a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol index a428963ce29a2..fa866053bbfc1 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeOPChain.t.sol @@ -8,199 +8,15 @@ import { Test } from "test/setup/Test.sol"; import { UpgradeOPChain, UpgradeOPChainInput } from "scripts/deploy/UpgradeOPChain.s.sol"; // Contracts -import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { OPContractsManagerV2 } from "src/L1/opcm/OPContractsManagerV2.sol"; -import { UpgradeOPChain, UpgradeOPChainInput } from "scripts/deploy/UpgradeOPChain.s.sol"; // Libraries -import { Claim } from "src/dispute/lib/Types.sol"; import { GameType } from "src/dispute/lib/LibUDT.sol"; -import { Constants } from "src/libraries/Constants.sol"; // Interfaces import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -contract UpgradeOPChainInput_Test is Test { - UpgradeOPChainInput input; - MockOPCMV1 _mockOPCM; - - function setUp() public { - input = new UpgradeOPChainInput(); - _mockOPCM = new MockOPCMV1(); - input.set(input.opcm.selector, address(_mockOPCM)); - } - - /// @notice This test verifies that the UpgradeOPChain script correctly reverts when the upgrade input is not - /// completely set. - function test_getters_whenNotSet_reverts() public { - UpgradeOPChainInput freshInput = new UpgradeOPChainInput(); - - vm.expectRevert("UpgradeOPCMInput: prank not set"); - freshInput.prank(); - - vm.expectRevert("UpgradeOPCMInput: not set"); - freshInput.opcm(); - - vm.expectRevert("UpgradeOPCMInput: not set"); - freshInput.upgradeInput(); - } - - /// @notice This test verifies that the UpgradeOPChain script correctly sets the upgrade input with - /// the address type. - function testFuzz_setAddress_succeeds(address mockPrank, address mockOPCM) public { - vm.assume(mockPrank != address(0)); - vm.assume(mockOPCM != address(0)); - - UpgradeOPChainInput freshInput = new UpgradeOPChainInput(); - freshInput.set(freshInput.prank.selector, mockPrank); - freshInput.set(freshInput.opcm.selector, mockOPCM); - - assertEq(freshInput.prank(), mockPrank); - assertEq(freshInput.opcm(), mockOPCM); - } - - /// @notice This test verifies that the UpgradeOPChain script correctly sets the upgrade input with - /// the OPContractsManager.OpChainConfig[] type. - function testFuzz_setOpChainConfigs_succeeds( - address systemConfig1, - address systemConfig2, - bytes32 prestate1, - bytes32 konaPrestate1, - bytes32 prestate2, - bytes32 konaPrestate2 - ) - public - { - // Assume non-zero addresses for system configs - vm.assume(systemConfig1 != address(0)); - vm.assume(systemConfig2 != address(0)); - // Assume not precompiles for system configs - assumeNotPrecompile(systemConfig1); - assumeNotPrecompile(systemConfig2); - // Ensure system configs don't collide with test contracts - vm.assume(systemConfig1 != address(input)); - vm.assume(systemConfig1 != address(_mockOPCM)); - vm.assume(systemConfig2 != address(input)); - vm.assume(systemConfig2 != address(_mockOPCM)); - - // Create sample OpChainConfig array - OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](2); - - // Setup mock addresses and contracts for first config - vm.etch(systemConfig1, hex"01"); - - configs[0] = OPContractsManager.OpChainConfig({ - systemConfigProxy: ISystemConfig(systemConfig1), - cannonPrestate: Claim.wrap(prestate1), - cannonKonaPrestate: Claim.wrap(konaPrestate1) - }); - - // Setup mock addresses and contracts for second config - vm.etch(systemConfig2, hex"01"); - - configs[1] = OPContractsManager.OpChainConfig({ - systemConfigProxy: ISystemConfig(systemConfig2), - cannonPrestate: Claim.wrap(prestate2), - cannonKonaPrestate: Claim.wrap(konaPrestate2) - }); - - input.set(input.upgradeInput.selector, configs); - - bytes memory storedConfigs = input.upgradeInput(); - assertEq(storedConfigs, abi.encode(configs)); - - // Additional verification of stored claims if needed - OPContractsManager.OpChainConfig[] memory decodedConfigs = - abi.decode(storedConfigs, (OPContractsManager.OpChainConfig[])); - assertEq(Claim.unwrap(decodedConfigs[0].cannonPrestate), prestate1); - assertEq(Claim.unwrap(decodedConfigs[1].cannonPrestate), prestate2); - assertEq(Claim.unwrap(decodedConfigs[0].cannonKonaPrestate), konaPrestate1); - assertEq(Claim.unwrap(decodedConfigs[1].cannonKonaPrestate), konaPrestate2); - } - - /// @notice This test verifies that the UpgradeOPChain script correctly reverts when setting the upgrade input with - /// a zero address. - function test_setAddress_withZeroAddress_reverts() public { - UpgradeOPChainInput freshInput = new UpgradeOPChainInput(); - - vm.expectRevert("UpgradeOPCMInput: cannot set zero address"); - freshInput.set(freshInput.prank.selector, address(0)); - - vm.expectRevert("UpgradeOPCMInput: cannot set zero address"); - freshInput.set(freshInput.opcm.selector, address(0)); - } - - /// @notice This test verifies that the UpgradeOPChain script correctly reverts when setting the upgrade input with - /// an empty array. - function test_setOpChainConfigs_withEmptyArray_reverts() public { - OPContractsManager.OpChainConfig[] memory emptyConfigs = new OPContractsManager.OpChainConfig[](0); - - vm.expectRevert("UpgradeOPCMInput: cannot set empty array"); - input.set(input.upgradeInput.selector, emptyConfigs); - } - - /// @notice This test verifies that the UpgradeOPChain script correctly reverts when setting the upgrade input with - /// an invalid selector. - function testFuzz_set_withInvalidSelector_reverts(bytes4 invalidSelector, address testAddr) public { - // Assume the selector is not one of the valid selectors - vm.assume(invalidSelector != input.prank.selector); - vm.assume(invalidSelector != input.opcm.selector); - vm.assume(invalidSelector != input.upgradeInput.selector); - vm.assume(testAddr != address(0)); - - vm.expectRevert("UpgradeOPCMInput: unknown selector"); - input.set(invalidSelector, testAddr); - - // Create a single config for testing invalid selector - OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](1); - address mockSystemConfig = makeAddr("systemConfig"); - vm.etch(mockSystemConfig, hex"01"); - - configs[0] = OPContractsManager.OpChainConfig({ - systemConfigProxy: ISystemConfig(mockSystemConfig), - cannonPrestate: Claim.wrap(bytes32(uint256(1))), - cannonKonaPrestate: Claim.wrap(bytes32(uint256(2))) - }); - - vm.expectRevert("UpgradeOPCMInput: unknown selector"); - input.set(invalidSelector, configs); - } - - /// @notice This test verifies that the UpgradeOPChain script correctly reverts when setting the upgrade input with - /// OPCM v2 input when OPCM v1 is enabled. - function testFuzz_setUpgradeInputV2_onV1OPCM_reverts( - address systemConfig, - bool enabled, - uint256 initBond, - uint32 gameType - ) - public - { - vm.assume(systemConfig != address(0)); - vm.assume(initBond > 0); - - // Try to set V2 input when V1 is enabled - IOPContractsManagerUtils.DisputeGameConfig[] memory disputeGameConfigs = - new IOPContractsManagerUtils.DisputeGameConfig[](1); - disputeGameConfigs[0] = IOPContractsManagerUtils.DisputeGameConfig({ - enabled: enabled, - initBond: initBond, - gameType: GameType.wrap(gameType), - gameArgs: abi.encode("test") - }); - - OPContractsManagerV2.UpgradeInput memory upgradeInput = OPContractsManagerV2.UpgradeInput({ - systemConfig: ISystemConfig(systemConfig), - disputeGameConfigs: disputeGameConfigs, - extraInstructions: new IOPContractsManagerUtils.ExtraInstruction[](0) - }); - - vm.expectRevert("UpgradeOPCMInput: cannot set OPCM v2 upgrade input when OPCM v1 is enabled"); - input.set(input.upgradeInput.selector, upgradeInput); - } -} - contract UpgradeOPChainInput_TestV2 is Test { UpgradeOPChainInput input; MockOPCMV2 mockOPCM; @@ -296,47 +112,6 @@ contract UpgradeOPChainInput_TestV2 is Test { vm.expectRevert("UpgradeOPCMInput: cannot set empty dispute game configs array"); input.set(input.upgradeInput.selector, upgradeInput); } - - /// @notice This test verifies that the UpgradeOPChain script correctly reverts when setting the upgrade input with - /// OPCM v1 input when OPCM v2 is enabled. - function testFuzz_setUpgradeInputV1_onV2OPCM_reverts( - address systemConfigProxy, - bytes32 cannonPrestate, - bytes32 cannonKonaPrestate - ) - public - { - vm.assume(systemConfigProxy != address(0)); - - // Try to set V1 input when V2 is enabled - OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](1); - configs[0] = OPContractsManager.OpChainConfig({ - systemConfigProxy: ISystemConfig(systemConfigProxy), - cannonPrestate: Claim.wrap(cannonPrestate), - cannonKonaPrestate: Claim.wrap(cannonKonaPrestate) - }); - - vm.expectRevert("UpgradeOPCMInput: cannot set OPCM v1 upgrade input when OPCM v2 is enabled"); - input.set(input.upgradeInput.selector, configs); - } -} - -contract MockOPCMV1 { - event UpgradeCalled( - address indexed sysCfgProxy, bytes32 indexed absolutePrestate, bytes32 indexed cannonKonaPrestate - ); - - function version() public pure returns (string memory) { - return "6.0.0"; - } - - function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs) public { - emit UpgradeCalled( - address(_opChainConfigs[0].systemConfigProxy), - Claim.unwrap(_opChainConfigs[0].cannonPrestate), - Claim.unwrap(_opChainConfigs[0].cannonKonaPrestate) - ); - } } contract MockOPCMV2 { @@ -347,7 +122,7 @@ contract MockOPCMV2 { ); function version() public pure returns (string memory) { - return Constants.OPCM_V2_MIN_VERSION; + return "7.0.0"; } function upgrade(OPContractsManagerV2.UpgradeInput memory _upgradeInput) public { @@ -357,77 +132,6 @@ contract MockOPCMV2 { } } -contract UpgradeOPChain_Test is Test { - MockOPCMV1 mockOPCM; - UpgradeOPChainInput uoci; - OPContractsManager.OpChainConfig config; - UpgradeOPChain upgradeOPChain; - address prank; - - event UpgradeCalled( - address indexed sysCfgProxy, bytes32 indexed absolutePrestate, bytes32 indexed cannonKonaPrestate - ); - - function setUp() public { - mockOPCM = new MockOPCMV1(); - uoci = new UpgradeOPChainInput(); - uoci.set(uoci.opcm.selector, address(mockOPCM)); - prank = makeAddr("prank"); - uoci.set(uoci.prank.selector, prank); - upgradeOPChain = new UpgradeOPChain(); - } - - /// @notice This test verifies that the UpgradeOPChain script correctly encodes and passes down the upgrade input - /// arguments to the OPCM contract's upgrade function. - /// @dev It does not test the actual upgrade functionality. - function testFuzz_upgrade_succeeds( - address systemConfigProxy, - bytes32 cannonPrestate, - bytes32 cannonKonaPrestate - ) - public - { - vm.assume(systemConfigProxy != address(0)); - - config = OPContractsManager.OpChainConfig({ - systemConfigProxy: ISystemConfig(systemConfigProxy), - cannonPrestate: Claim.wrap(cannonPrestate), - cannonKonaPrestate: Claim.wrap(cannonKonaPrestate) - }); - OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](1); - configs[0] = config; - uoci.set(uoci.upgradeInput.selector, configs); - - // 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.cannonPrestate), - Claim.unwrap(config.cannonKonaPrestate) - ); - upgradeOPChain.run(uoci); - } - - /// @notice This test verifies that the UpgradeOPChain script correctly reverts when the OPCM upgrade - /// call fails - function test_upgrade_whenOPCMReverts_reverts() public { - address systemConfigProxy = makeAddr("systemConfig"); - config = OPContractsManager.OpChainConfig({ - systemConfigProxy: ISystemConfig(systemConfigProxy), - cannonPrestate: Claim.wrap(bytes32(uint256(1))), - cannonKonaPrestate: Claim.wrap(bytes32(uint256(2))) - }); - OPContractsManager.OpChainConfig[] memory configs = new OPContractsManager.OpChainConfig[](1); - configs[0] = config; - uoci.set(uoci.upgradeInput.selector, configs); - - vm.mockCallRevert(prank, OPContractsManager.upgrade.selector, abi.encode("UpgradeOPChain: upgrade failed")); - - vm.expectRevert("UpgradeOPChain: upgrade failed"); - upgradeOPChain.run(uoci); - } -} - contract UpgradeOPChain_TestV2 is Test { MockOPCMV2 mockOPCM; UpgradeOPChainInput uoci; diff --git a/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol b/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol index a4ec0153c4efd..d36ee2cc63523 100644 --- a/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol +++ b/packages/contracts-bedrock/test/opcm/UpgradeSuperchainConfig.t.sol @@ -8,35 +8,17 @@ import { Test } from "test/setup/Test.sol"; import { UpgradeSuperchainConfig } from "scripts/deploy/UpgradeSuperchainConfig.s.sol"; // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; -// Libraries -import { Constants } from "src/libraries/Constants.sol"; - -/// @title MockOPCMV1 -/// @notice This contract is used to mock the OPCM contract and emit an event which we check for in the test. -contract MockOPCMV1 { - event UpgradeCalled(address indexed superchainConfig); - - function version() public pure returns (string memory) { - return "6.0.0"; - } - - function upgradeSuperchainConfig(ISuperchainConfig _superchainConfig) public { - emit UpgradeCalled(address(_superchainConfig)); - } -} - /// @title MockOPCMV2 /// @notice This contract is used to mock the OPCM v2 contract and emit an event which we check for in the test. contract MockOPCMV2 { event UpgradeCalled(IOPContractsManagerV2.SuperchainUpgradeInput indexed superchainUpgradeInput); function version() public pure returns (string memory) { - return Constants.OPCM_V2_MIN_VERSION; + return "7.0.0"; } function upgradeSuperchain(IOPContractsManagerV2.SuperchainUpgradeInput memory _superchainUpgradeInput) public { @@ -44,72 +26,6 @@ contract MockOPCMV2 { } } -/// @title UpgradeSuperchainConfig_Test -/// @notice This test is used to test the UpgradeSuperchainConfig script. -contract UpgradeSuperchainConfigV1_Run_Test is Test { - MockOPCMV1 mockOPCM; - UpgradeSuperchainConfig.Input input; - UpgradeSuperchainConfig upgradeSuperchainConfig; - address prank; - ISuperchainConfig superchainConfig; - - event UpgradeCalled(address indexed superchainConfig); - - /// @notice Sets up the test suite. - function setUp() public virtual { - mockOPCM = new MockOPCMV1(); - - input.opcm = address(mockOPCM); - - superchainConfig = ISuperchainConfig(makeAddr("superchainConfig")); - prank = makeAddr("prank"); - - input.superchainConfig = superchainConfig; - input.prank = prank; - - upgradeSuperchainConfig = new UpgradeSuperchainConfig(); - } - - /// @notice Tests that the UpgradeSuperchainConfig script succeeds when called with non-zero input values. - 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)); - upgradeSuperchainConfig.run(input); - } - - /// @notice Tests that the UpgradeSuperchainConfig script reverts when called with zero input values. - function test_run_nullInput_reverts() public { - input.prank = address(0); - vm.expectRevert("UpgradeSuperchainConfig: prank not set"); - upgradeSuperchainConfig.run(input); - input.prank = prank; - - input.opcm = address(0); - vm.expectRevert("UpgradeSuperchainConfig: opcm not set"); - upgradeSuperchainConfig.run(input); - input.opcm = address(mockOPCM); - - input.superchainConfig = ISuperchainConfig(address(0)); - vm.expectRevert("UpgradeSuperchainConfig: superchainConfig not set"); - upgradeSuperchainConfig.run(input); - input.superchainConfig = ISuperchainConfig(address(superchainConfig)); - } - - /// @notice Tests that the UpgradeSuperchainConfig script reverts when the OPCM upgradeSuperchainConfig - /// call fails - function test_upgrade_whenOPCMReverts_reverts() public { - vm.mockCallRevert( - prank, - IOPContractsManager.upgradeSuperchainConfig.selector, - abi.encode("UpgradeSuperchainConfig: upgrade failed") - ); - - vm.expectRevert("UpgradeSuperchainConfig: upgrade failed"); - upgradeSuperchainConfig.run(input); - } -} - /// @title UpgradeSuperchainConfigV2_Run_Test /// @notice This test is used to test the UpgradeSuperchainConfig script with OPCM v2. contract UpgradeSuperchainConfigV2_Run_Test is Test { diff --git a/packages/contracts-bedrock/test/scripts/ReadImplementationAddresses.t.sol b/packages/contracts-bedrock/test/scripts/ReadImplementationAddresses.t.sol index b5b09edb45a66..3f4176ef0a205 100644 --- a/packages/contracts-bedrock/test/scripts/ReadImplementationAddresses.t.sol +++ b/packages/contracts-bedrock/test/scripts/ReadImplementationAddresses.t.sol @@ -8,13 +8,10 @@ import { CommonTest } from "test/setup/CommonTest.sol"; import { ReadImplementationAddresses } from "scripts/deploy/ReadImplementationAddresses.s.sol"; // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; +import { IOPContractsManagerContainer } from "interfaces/L1/opcm/IOPContractsManagerContainer.sol"; import { IMIPS64 } from "interfaces/cannon/IMIPS64.sol"; -// Libraries -import { DevFeatures } from "src/libraries/DevFeatures.sol"; - /// @title ReadImplementationAddressesTest /// @notice Tests that ReadImplementationAddresses correctly reads implementation addresses /// from the deployed contracts. Uses CommonTest to get real deployed contracts. @@ -26,9 +23,9 @@ contract ReadImplementationAddressesTest is CommonTest { script = new ReadImplementationAddresses(); } - /// @notice Returns the OPCM instance, handling V1 vs V2 feature flag. - function _opcm() internal view returns (IOPContractsManager) { - return isDevFeatureEnabled(DevFeatures.OPCM_V2) ? IOPContractsManager(address(opcmV2)) : opcm; + /// @notice Returns the OPCM instance. + function _opcm() internal view returns (IOPContractsManagerV2) { + return IOPContractsManagerV2(address(opcmV2)); } /// @notice Builds the input struct from the deployed contracts. @@ -49,8 +46,8 @@ contract ReadImplementationAddressesTest is CommonTest { ReadImplementationAddresses.Output memory output = script.run(input); // Get expected implementations from OPCM - IOPContractsManager opcm_ = _opcm(); - IOPContractsManager.Implementations memory impls = opcm_.implementations(); + IOPContractsManagerV2 opcm_ = _opcm(); + IOPContractsManagerContainer.Implementations memory impls = opcm_.implementations(); // Assert implementations from OPCM match output assertEq(output.delayedWETH, impls.delayedWETHImpl, "DelayedWETH should match"); @@ -70,26 +67,10 @@ contract ReadImplementationAddressesTest is CommonTest { output.opcmStandardValidator, address(opcm_.opcmStandardValidator()), "OPCM StandardValidator should match" ); - // Assert V1 vs V2 specific fields - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - // V2: deployer/upgrader/gameTypeAdder are zero, migrator comes from opcmMigrator() - assertEq(output.opcmDeployer, address(0), "OPCM Deployer should be zero in V2"); - assertEq(output.opcmUpgrader, address(0), "OPCM Upgrader should be zero in V2"); - assertEq(output.opcmGameTypeAdder, address(0), "OPCM GameTypeAdder should be zero in V2"); - assertEq( - output.opcmInteropMigrator, - address(IOPContractsManagerV2(address(opcm_)).opcmMigrator()), - "OPCM InteropMigrator should match" - ); - } else { - // V1: all component addresses come from opcm getters - assertEq(output.opcmDeployer, address(opcm_.opcmDeployer()), "OPCM Deployer should match"); - assertEq(output.opcmUpgrader, address(opcm_.opcmUpgrader()), "OPCM Upgrader should match"); - assertEq(output.opcmGameTypeAdder, address(opcm_.opcmGameTypeAdder()), "OPCM GameTypeAdder should match"); - assertEq( - output.opcmInteropMigrator, address(opcm_.opcmInteropMigrator()), "OPCM InteropMigrator should match" - ); - } + assertEq(output.opcmDeployer, address(0), "OPCM Deployer should be zero"); + assertEq(output.opcmUpgrader, address(0), "OPCM Upgrader should be zero"); + assertEq(output.opcmGameTypeAdder, address(0), "OPCM GameTypeAdder should be zero"); + assertEq(output.opcmInteropMigrator, address(opcm_.opcmMigrator()), "OPCM InteropMigrator should match"); } /// @notice Tests that ReadImplementationAddresses.runWithBytes succeeds. @@ -101,8 +82,8 @@ contract ReadImplementationAddressesTest is CommonTest { ReadImplementationAddresses.Output memory output = abi.decode(outputBytes, (ReadImplementationAddresses.Output)); // Get expected implementations from OPCM - IOPContractsManager opcm_ = _opcm(); - IOPContractsManager.Implementations memory impls = opcm_.implementations(); + IOPContractsManagerV2 opcm_ = _opcm(); + IOPContractsManagerContainer.Implementations memory impls = opcm_.implementations(); // Assert key values match assertEq(output.delayedWETH, impls.delayedWETHImpl, "DelayedWETH should match"); diff --git a/packages/contracts-bedrock/test/scripts/ReadSuperchainDeployment.t.sol b/packages/contracts-bedrock/test/scripts/ReadSuperchainDeployment.t.sol index bb85679d55def..db928b543a9d8 100644 --- a/packages/contracts-bedrock/test/scripts/ReadSuperchainDeployment.t.sol +++ b/packages/contracts-bedrock/test/scripts/ReadSuperchainDeployment.t.sol @@ -9,28 +9,18 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { ReadSuperchainDeployment } from "scripts/deploy/ReadSuperchainDeployment.s.sol"; // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; -import { IProtocolVersions, ProtocolVersion } from "interfaces/L1/IProtocolVersions.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IProxy } from "interfaces/universal/IProxy.sol"; -import { Constants } from "src/libraries/Constants.sol"; // Test addresses declared as constants for convenience. address constant TEST_SUPERCHAIN_CONFIG_IMPL = address(0x3001); address constant TEST_SUPERCHAIN_PROXY_ADMIN = address(0x3002); address constant TEST_GUARDIAN = address(0x3003); address constant TEST_SUPERCHAIN_PROXY_ADMIN_OWNER = address(0x3004); -address constant TEST_OPCM_IMPL = address(0x2000); -address constant TEST_PROTOCOL_VERSIONS_PROXY = address(0x3005); -address constant TEST_PROTOCOL_VERSIONS_IMPL = address(0x3006); -address constant TEST_PROTOCOL_VERSIONS_OWNER = address(0x3007); -uint256 constant TEST_RECOMMENDED_VERSION = 1; -uint256 constant TEST_REQUIRED_VERSION = 2; /// @title ReadSuperchainDeploymentTest -/// @notice Tests that ReadSuperchainDeployment.run and ReadSuperchainDeployment.runWithBytes succeed with OPCM V1 -/// and OPCM V2. +/// @notice Tests that ReadSuperchainDeployment.run and ReadSuperchainDeployment.runWithBytes succeed. contract ReadSuperchainDeploymentTest is Test { ReadSuperchainDeployment script; ReadSuperchainDeployment.Input input; @@ -40,35 +30,8 @@ contract ReadSuperchainDeploymentTest is Test { input.superchainConfigProxy = ISuperchainConfig(makeAddr("superchainConfigProxy")); } - /// @notice Tests that ReadSuperchainDeployment.run succeeds with OPCM V2 (opcmAddress is zero). - function test_run_withOPCMV2ZeroAddress_succeeds() public { - input.opcmAddress = IOPContractsManager(address(0)); - - _setUpSuperchainConfigProxy(); - _mockSuperchainConfigCalls(); - - ReadSuperchainDeployment.Output memory output = script.run(input); - - assertEq(address(output.superchainConfigProxy), address(input.superchainConfigProxy)); - assertEq(address(output.superchainConfigImpl), TEST_SUPERCHAIN_CONFIG_IMPL); - assertEq(address(output.superchainProxyAdmin), TEST_SUPERCHAIN_PROXY_ADMIN); - assertEq(output.guardian, TEST_GUARDIAN); - assertEq(output.superchainProxyAdminOwner, TEST_SUPERCHAIN_PROXY_ADMIN_OWNER); - assertEq(address(output.protocolVersionsImpl), address(0)); - assertEq(address(output.protocolVersionsProxy), address(0)); - assertEq(output.protocolVersionsOwner, address(0)); - assertEq(output.recommendedProtocolVersion, bytes32(0)); - assertEq(output.requiredProtocolVersion, bytes32(0)); - } - - /// @notice Tests that ReadSuperchainDeployment.run succeeds with OPCM V2 (opcm version >= 7.0.0). - function test_run_withOPCMV2VersionGteMin_succeeds() public { - input.opcmAddress = IOPContractsManager(TEST_OPCM_IMPL); - vm.etch(TEST_OPCM_IMPL, "0x01"); - _mockExpect( - TEST_OPCM_IMPL, abi.encodeCall(IOPContractsManager.version, ()), abi.encode(Constants.OPCM_V2_MIN_VERSION) - ); - + /// @notice Tests that ReadSuperchainDeployment.run succeeds. + function test_run_succeeds() public { _setUpSuperchainConfigProxy(); _mockSuperchainConfigCalls(); @@ -79,16 +42,10 @@ contract ReadSuperchainDeploymentTest is Test { assertEq(address(output.superchainProxyAdmin), TEST_SUPERCHAIN_PROXY_ADMIN); assertEq(output.guardian, TEST_GUARDIAN); assertEq(output.superchainProxyAdminOwner, TEST_SUPERCHAIN_PROXY_ADMIN_OWNER); - assertEq(address(output.protocolVersionsImpl), address(0)); - assertEq(address(output.protocolVersionsProxy), address(0)); - assertEq(output.protocolVersionsOwner, address(0)); - assertEq(output.recommendedProtocolVersion, bytes32(0)); - assertEq(output.requiredProtocolVersion, bytes32(0)); } - /// @notice Tests that ReadSuperchainDeployment.runWithBytes succeeds with OPCM V2. - function test_runWithBytes_withOPCMV2_succeeds() public { - input.opcmAddress = IOPContractsManager(address(0)); + /// @notice Tests that ReadSuperchainDeployment.runWithBytes succeeds. + function test_runWithBytes_succeeds() public { _setUpSuperchainConfigProxy(); _mockSuperchainConfigCalls(); @@ -101,67 +58,13 @@ contract ReadSuperchainDeploymentTest is Test { assertEq(address(output.superchainProxyAdmin), TEST_SUPERCHAIN_PROXY_ADMIN); assertEq(output.guardian, TEST_GUARDIAN); assertEq(output.superchainProxyAdminOwner, TEST_SUPERCHAIN_PROXY_ADMIN_OWNER); - assertEq(address(output.protocolVersionsImpl), address(0)); - assertEq(address(output.protocolVersionsProxy), address(0)); - assertEq(output.protocolVersionsOwner, address(0)); - assertEq(output.recommendedProtocolVersion, bytes32(0)); - assertEq(output.requiredProtocolVersion, bytes32(0)); } - /// @notice Tests that run reverts when OPCM V2 and superchainConfigProxy has no code. - function test_run_opcmV2SuperchainConfigNoCode_reverts() public { - input.opcmAddress = IOPContractsManager(address(0)); + /// @notice Tests that run reverts when superchainConfigProxy has no code. + function test_run_superchainConfigNoCode_reverts() public { // Do not etch code to superchainConfigProxy - vm.expectRevert("ReadSuperchainDeployment: superchainConfigProxy has no code for OPCM v2"); - script.run(input); - } - - /// @notice Tests that ReadSuperchainDeployment.run succeeds with OPCM V1. - function test_run_withOPCMV1_succeeds() public { - _mockOPCMV1(); - _setUpSuperchainConfigProxy(); - _mockSuperchainConfigCalls(); - _mockProtocolVersionsCalls(); - - ReadSuperchainDeployment.Output memory output = script.run(input); - - assertEq(address(output.superchainConfigProxy), address(input.superchainConfigProxy)); - assertEq(address(output.superchainConfigImpl), TEST_SUPERCHAIN_CONFIG_IMPL); - assertEq(address(output.superchainProxyAdmin), TEST_SUPERCHAIN_PROXY_ADMIN); - assertEq(output.guardian, TEST_GUARDIAN); - assertEq(output.superchainProxyAdminOwner, TEST_SUPERCHAIN_PROXY_ADMIN_OWNER); - assertEq(address(output.protocolVersionsImpl), TEST_PROTOCOL_VERSIONS_IMPL); - assertEq(address(output.protocolVersionsProxy), TEST_PROTOCOL_VERSIONS_PROXY); - assertEq(output.protocolVersionsOwner, TEST_PROTOCOL_VERSIONS_OWNER); - assertEq(output.recommendedProtocolVersion, bytes32(TEST_RECOMMENDED_VERSION)); - assertEq(output.requiredProtocolVersion, bytes32(TEST_REQUIRED_VERSION)); - } - - /// @notice Tests that ReadSuperchainDeployment.runWithBytes succeeds with OPCM V1. - function test_runWithBytes_withOPCMV1_succeeds() public { - _mockOPCMV1(); - vm.etch(address(input.superchainConfigProxy), "0x01"); - _setUpSuperchainConfigProxy(); - _mockSuperchainConfigCalls(); - _mockProtocolVersionsCalls(); - - bytes memory inputBytes = abi.encode(input); - bytes memory outputBytes = script.runWithBytes(inputBytes); - ReadSuperchainDeployment.Output memory output = abi.decode(outputBytes, (ReadSuperchainDeployment.Output)); - - assertEq(address(output.superchainConfigProxy), address(input.superchainConfigProxy)); - assertEq(address(output.protocolVersionsImpl), TEST_PROTOCOL_VERSIONS_IMPL); - assertEq(output.recommendedProtocolVersion, bytes32(TEST_RECOMMENDED_VERSION)); - assertEq(output.requiredProtocolVersion, bytes32(TEST_REQUIRED_VERSION)); - } - - /// @notice Tests that run reverts when OPCM address is non-zero but has no code. - function test_run_opcmCodeLengthZero_reverts() public { - input.opcmAddress = IOPContractsManager(makeAddr("opcmNoCode")); - vm.etch(address(input.superchainConfigProxy), "0x01"); - - vm.expectRevert("ReadSuperchainDeployment: OPCM address has no code"); + vm.expectRevert("ReadSuperchainDeployment: superchainConfigProxy has no code"); script.run(input); } @@ -173,7 +76,7 @@ contract ReadSuperchainDeploymentTest is Test { EIP1967Helper.setAdmin(address(input.superchainConfigProxy), TEST_SUPERCHAIN_PROXY_ADMIN); } - /// @notice Mocks SuperchainConfig proxy and ProxyAdmin calls used in both OPCM v1 and v2 paths. + /// @notice Mocks SuperchainConfig proxy and ProxyAdmin calls. function _mockSuperchainConfigCalls() internal { _mockExpect( address(input.superchainConfigProxy), @@ -192,48 +95,6 @@ contract ReadSuperchainDeploymentTest is Test { ); } - /// @notice Mocks OPCM V1: version, protocolVersions(), superchainConfig(). - function _mockOPCMV1() internal { - input.opcmAddress = IOPContractsManager(TEST_OPCM_IMPL); - vm.etch(TEST_OPCM_IMPL, "0x01"); - - _mockExpect(TEST_OPCM_IMPL, abi.encodeCall(IOPContractsManager.version, ()), abi.encode("6.0.0")); - _mockExpect( - TEST_OPCM_IMPL, - abi.encodeCall(IOPContractsManager.protocolVersions, ()), - abi.encode(TEST_PROTOCOL_VERSIONS_PROXY) - ); - _mockExpect( - TEST_OPCM_IMPL, - abi.encodeCall(IOPContractsManager.superchainConfig, ()), - abi.encode(address(input.superchainConfigProxy)) - ); - } - - /// @notice Mocks ProtocolVersions proxy: implementation(), owner(), recommended(), required(). - function _mockProtocolVersionsCalls() internal { - _mockExpect( - TEST_PROTOCOL_VERSIONS_PROXY, - abi.encodeCall(IProxy.implementation, ()), - abi.encode(TEST_PROTOCOL_VERSIONS_IMPL) - ); - _mockExpect( - TEST_PROTOCOL_VERSIONS_PROXY, - abi.encodeCall(IProtocolVersions.owner, ()), - abi.encode(TEST_PROTOCOL_VERSIONS_OWNER) - ); - _mockExpect( - TEST_PROTOCOL_VERSIONS_PROXY, - abi.encodeCall(IProtocolVersions.recommended, ()), - abi.encode(ProtocolVersion.wrap(TEST_RECOMMENDED_VERSION)) - ); - _mockExpect( - TEST_PROTOCOL_VERSIONS_PROXY, - abi.encodeCall(IProtocolVersions.required, ()), - abi.encode(ProtocolVersion.wrap(TEST_REQUIRED_VERSION)) - ); - } - /// @notice Internal helper to mock and expect calls. function _mockExpect(address _target, bytes memory _callData, bytes memory _returnData) internal { vm.mockCall(_target, _callData, _returnData); diff --git a/packages/contracts-bedrock/test/scripts/VerifyOPCM.t.sol b/packages/contracts-bedrock/test/scripts/VerifyOPCM.t.sol index 62a63d750f384..b541b898023e4 100644 --- a/packages/contracts-bedrock/test/scripts/VerifyOPCM.t.sol +++ b/packages/contracts-bedrock/test/scripts/VerifyOPCM.t.sol @@ -12,7 +12,6 @@ import { CommonTest } from "test/setup/CommonTest.sol"; import { VerifyOPCM } from "scripts/deploy/VerifyOPCM.s.sol"; // Interfaces -import { IOPContractsManager, IOPContractsManagerUpgrader } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerStandardValidator } from "interfaces/L1/IOPContractsManagerStandardValidator.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; @@ -34,12 +33,12 @@ contract VerifyOPCM_Harness is VerifyOPCM { return _loadArtifactInfo(_artifactPath); } - function getOpcmPropertyRefs(IOPContractsManager _opcm) public returns (OpcmContractRef[] memory) { + function getOpcmPropertyRefs(IOPContractsManagerV2 _opcm) public returns (OpcmContractRef[] memory) { return _getOpcmPropertyRefs(_opcm); } function getOpcmContractRefs( - IOPContractsManager _opcm, + IOPContractsManagerV2 _opcm, string memory _property, bool _blueprint ) @@ -61,7 +60,7 @@ contract VerifyOPCM_Harness is VerifyOPCM { return _verifyOpcmUtilsConsistency(_propRefs); } - function verifyOpcmImmutableVariables(IOPContractsManager _opcm) public returns (bool) { + function verifyOpcmImmutableVariables(IOPContractsManagerV2 _opcm) public returns (bool) { return _verifyOpcmImmutableVariables(_opcm); } @@ -89,7 +88,7 @@ contract VerifyOPCM_Harness is VerifyOPCM { return _verifyAnchorStateRegistryDelays(_asr); } - function verifyStandardValidatorArgs(IOPContractsManager _opcm, address _validator) public returns (bool) { + function verifyStandardValidatorArgs(IOPContractsManagerV2 _opcm, address _validator) public returns (bool) { return _verifyStandardValidatorArgs(_opcm, _validator); } @@ -102,33 +101,24 @@ contract VerifyOPCM_Harness is VerifyOPCM { /// @notice Reusable test initialization for `VerifyOPCM` tests. abstract contract VerifyOPCM_TestInit is CommonTest { VerifyOPCM_Harness internal harness; + IOPContractsManagerV2 internal opcm; function setUp() public virtual override { super.setUp(); harness = new VerifyOPCM_Harness(); harness.setUp(); - // If OPCM V2 is enabled, set up the test environment for OPCM V2. - // nosemgrep: sol-style-vm-env-only-in-config-sol - if (vm.envOr("DEV_FEATURE__OPCM_V2", false)) { - opcm = IOPContractsManager(address(opcmV2)); - } + opcm = IOPContractsManagerV2(address(opcmV2)); // Always set up the environment variables for the test. setupEnvVars(); - // Set the OPCM address so that runSingle also runs for V2 OPCM if the dev feature is enabled. + // Set the OPCM address. vm.setEnv("OPCM_ADDRESS", vm.toString(address(opcm))); } /// @notice Sets up the environment variables for the VerifyOPCM test. function setupEnvVars() public { - // If OPCM V2 is not enabled, set the environment variables for the old OPCM. - if (!isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - vm.setEnv("EXPECTED_SUPERCHAIN_CONFIG", vm.toString(address(opcm.superchainConfig()))); - vm.setEnv("EXPECTED_PROTOCOL_VERSIONS", vm.toString(address(opcm.protocolVersions()))); - } - // Grab a reference to the validator. IOPContractsManagerStandardValidator validator = IOPContractsManagerStandardValidator(opcm.opcmStandardValidator()); @@ -197,7 +187,7 @@ contract VerifyOPCM_Run_Test is VerifyOPCM_TestInit { // Mock opcm to return a non-zero dev feature bitmap. vm.mockCall( - address(opcm), abi.encodeCall(IOPContractsManager.devFeatureBitmap, ()), abi.encode(_devFeatureBitmap) + address(opcm), abi.encodeCall(IOPContractsManagerV2.devFeatureBitmap, ()), abi.encode(_devFeatureBitmap) ); // Set the chain ID to 1. @@ -432,7 +422,7 @@ contract VerifyOPCM_Run_Test is VerifyOPCM_TestInit { // Mock this specific component to return a different address vm.mockCall( propRefs[i].addr, - abi.encodeCall(IOPContractsManagerUpgrader.contractsContainer, ()), + abi.encodeCall(IOPContractsManagerV2.contractsContainer, ()), abi.encode(differentContainer) ); @@ -454,9 +444,6 @@ contract VerifyOPCM_Run_Test is VerifyOPCM_TestInit { function test_verifyOpcmUtilsConsistency_succeeds() public { skipIfUnoptimized(); - // Only run for OPCM V2 - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - // Get the property references (which include the component addresses) VerifyOPCM.OpcmContractRef[] memory propRefs = harness.getOpcmPropertyRefs(opcm); @@ -468,9 +455,6 @@ contract VerifyOPCM_Run_Test is VerifyOPCM_TestInit { function test_verifyOpcmUtilsConsistency_mismatch_reverts() public { skipIfUnoptimized(); - // Only run for OPCM V2 - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - // Get the property references (which include the component addresses) VerifyOPCM.OpcmContractRef[] memory propRefs = harness.getOpcmPropertyRefs(opcm); @@ -489,9 +473,6 @@ contract VerifyOPCM_Run_Test is VerifyOPCM_TestInit { function test_verifyOpcmUtilsConsistency_eachComponent_reverts() public { skipIfUnoptimized(); - // Only run for OPCM V2 - skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); - // Get the property references (which include the component addresses) VerifyOPCM.OpcmContractRef[] memory propRefs = harness.getOpcmPropertyRefs(opcm); @@ -535,7 +516,7 @@ contract VerifyOPCM_Run_Test is VerifyOPCM_TestInit { if (_hasContractsContainer(field)) { vm.mockCall( _propRefs[i].addr, - abi.encodeCall(IOPContractsManagerUpgrader.contractsContainer, ()), + abi.encodeCall(IOPContractsManagerV2.contractsContainer, ()), abi.encode(_mockAddress) ); return; @@ -624,19 +605,6 @@ contract VerifyOPCM_Run_Test is VerifyOPCM_TestInit { assertFalse(result, "OPCM with invalid immutable variables should fail verification"); } - /// @notice Tests that the script fails when OPCM immutable variables are invalid. - /// We test this by setting expected addresses and mocking OPCM methods to return different addresses. - function test_verifyOpcmImmutableVariables_mismatch_fails() public { - skipIfUnoptimized(); - - // If OPCM V2 is enabled because we do not use environment variables for OPCM V2. - skipIfDevFeatureEnabled(DevFeatures.OPCM_V2); - - // Test that mocking each individual getter causes verification to fail - _assertOnOpcmGetter(IOPContractsManager.superchainConfig.selector); - _assertOnOpcmGetter(IOPContractsManager.protocolVersions.selector); - } - /// @notice Tests that the ABI getter validation succeeds when all getters are accounted for. function test_validateAllGettersAccounted_succeeds() public { // This should succeed as setUp() configures all expected getters diff --git a/packages/contracts-bedrock/test/setup/FeatureFlags.sol b/packages/contracts-bedrock/test/setup/FeatureFlags.sol index 4c55191a69dfd..4cbd8070e92d1 100644 --- a/packages/contracts-bedrock/test/setup/FeatureFlags.sol +++ b/packages/contracts-bedrock/test/setup/FeatureFlags.sol @@ -41,10 +41,6 @@ abstract contract FeatureFlags { console.log("Setup: DEV_FEATURE__OPTIMISM_PORTAL_INTEROP is enabled"); devFeatureBitmap |= DevFeatures.OPTIMISM_PORTAL_INTEROP; } - if (Config.devFeatureOpcmV2()) { - console.log("Setup: DEV_FEATURE__OPCM_V2 is enabled"); - devFeatureBitmap |= DevFeatures.OPCM_V2; - } if (Config.devFeatureL2CM()) { console.log("Setup: DEV_FEATURE__L2CM is enabled"); devFeatureBitmap |= DevFeatures.L2CM; @@ -69,8 +65,6 @@ abstract contract FeatureFlags { function getFeatureName(bytes32 _feature) public pure returns (string memory) { if (_feature == DevFeatures.OPTIMISM_PORTAL_INTEROP) { return "DEV_FEATURE__OPTIMISM_PORTAL_INTEROP"; - } else if (_feature == DevFeatures.OPCM_V2) { - return "DEV_FEATURE__OPCM_V2"; } else if (_feature == DevFeatures.L2CM) { return "DEV_FEATURE__L2CM"; } else if (_feature == DevFeatures.ZK_DISPUTE_GAME) { diff --git a/packages/contracts-bedrock/test/setup/ForkL1Live.s.sol b/packages/contracts-bedrock/test/setup/ForkL1Live.s.sol index 743ceccfca2a8..fbd8ad94e2401 100644 --- a/packages/contracts-bedrock/test/setup/ForkL1Live.s.sol +++ b/packages/contracts-bedrock/test/setup/ForkL1Live.s.sol @@ -18,7 +18,6 @@ import { Config } from "scripts/libraries/Config.sol"; // Libraries import { GameType, GameTypes, Claim, Proposal, Hash } from "src/dispute/lib/Types.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; -import { DevFeatures } from "src/libraries/DevFeatures.sol"; import { LibString } from "@solady/utils/LibString.sol"; import { LibGameArgs } from "src/dispute/lib/LibGameArgs.sol"; @@ -30,11 +29,9 @@ 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 { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; -import { IOPContractsManagerUpgrader } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; @@ -135,10 +132,6 @@ contract ForkL1Live is Deployer, StdAssertions, FeatureFlags { // Superchain shared contracts saveProxyAndImpl("SuperchainConfig", superchainToml, ".superchain_config_addr"); saveProxyAndImpl("ProtocolVersions", superchainToml, ".protocol_versions_addr"); - artifacts.save( - "OPContractsManager", vm.parseTomlAddress(standardVersionsToml, "$.RELEASE.op_contracts_manager.address") - ); - // Core contracts artifacts.save("ProxyAdmin", vm.parseJsonAddress(addressesJson, string.concat("$.", chainId, ".ProxyAdmin"))); saveProxyAndImpl("SystemConfig", opToml, ".addresses.SystemConfigProxy"); @@ -212,41 +205,6 @@ contract ForkL1Live is Deployer, StdAssertions, FeatureFlags { deploy.deployImplementations(); } - /// @notice Performs a single OPCM upgrade. - /// @param _opcm The OPCM contract to upgrade. - /// @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")); - IOPContractsManager.OpChainConfig[] memory opChains = new IOPContractsManager.OpChainConfig[](1); - opChains[0] = IOPContractsManager.OpChainConfig({ - systemConfigProxy: systemConfig, - cannonPrestate: Claim.wrap(bytes32(keccak256("cannonPrestate"))), - cannonKonaPrestate: Claim.wrap(bytes32(keccak256("cannonKonaPrestate"))) - }); - - // Execute the SuperchainConfig upgrade. - // Always try to upgrade the SuperchainConfig. Not always necessary but easier to do it - // every time rather than adding or removing this code for each upgrade. - ISuperchainConfig superchainConfig = ISuperchainConfig(artifacts.mustGetAddress("SuperchainConfigProxy")); - IProxyAdmin superchainProxyAdmin = IProxyAdmin(EIP1967Helper.getAdmin(address(superchainConfig))); - address superchainPAO = superchainProxyAdmin.owner(); - vm.prank(superchainPAO, true); - (bool success, bytes memory reason) = - address(_opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig))); - if (success == false) { - assertTrue( - bytes4(reason) - == IOPContractsManagerUpgrader.OPContractsManagerUpgrader_SuperchainConfigAlreadyUpToDate.selector, - "Revert reason other than SuperchainConfigAlreadyUpToDate" - ); - } - - // Upgrade the chain. - vm.prank(_delegateCaller, true); - (bool upgradeSuccess,) = address(_opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgrade, (opChains))); - assertTrue(upgradeSuccess, "upgrade failed"); - } - /// @notice Performs a single OPCM V2 upgrade. /// @param _opcm The OPCM V2 contract to upgrade. /// @param _delegateCaller The address of the upgrader to use for the upgrade. @@ -473,13 +431,8 @@ contract ForkL1Live is Deployer, StdAssertions, FeatureFlags { PastUpgrades.runPastUpgrades(upgrader, systemConfig, superchainConfig, disputeGameFactoryForPastUpgrades); // Current upgrade. - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - IOPContractsManagerV2 opcmV2 = IOPContractsManagerV2(artifacts.mustGetAddress("OPContractsManagerV2")); - _doUpgradeV2(opcmV2, upgrader); - } else { - IOPContractsManager opcm = IOPContractsManager(artifacts.mustGetAddress("OPContractsManager")); - _doUpgrade(opcm, upgrader); - } + IOPContractsManagerV2 opcmV2 = IOPContractsManagerV2(artifacts.mustGetAddress("OPContractsManagerV2")); + _doUpgradeV2(opcmV2, upgrader); console.log("ForkL1Live: Saving newly deployed contracts"); diff --git a/packages/contracts-bedrock/test/setup/PastUpgrades.sol b/packages/contracts-bedrock/test/setup/PastUpgrades.sol index 54662bd751496..4a56b612a42c0 100644 --- a/packages/contracts-bedrock/test/setup/PastUpgrades.sol +++ b/packages/contracts-bedrock/test/setup/PastUpgrades.sol @@ -17,7 +17,6 @@ import { Claim, GameTypes } from "src/dispute/lib/Types.sol"; import { SemverComp } from "src/libraries/SemverComp.sol"; // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; import { IOPContractsManagerV2 } from "interfaces/L1/opcm/IOPContractsManagerV2.sol"; import { IOPContractsManagerUtils } from "interfaces/L1/opcm/IOPContractsManagerUtils.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; @@ -111,11 +110,12 @@ library PastUpgrades { return; } - // Resolve on-chain versions and filter to >= 6.x.x + // Resolve on-chain versions and filter to >= 7.x.x (V2 OPCMs only). + // V1 OPCMs (6.x.x) use the IOPContractsManager interface and are not supported. ResolvedOPCM[] memory resolved = _resolveAndFilterOPCMs(opcms); if (resolved.length == 0) { - console.log("PastUpgrades: No OPCMs >= 6.x.x found for chain %d", block.chainid); + console.log("PastUpgrades: No OPCMs >= 7.x.x found for chain %d", block.chainid); return; } @@ -147,52 +147,10 @@ library PastUpgrades { console.log("PastUpgrades: Running upgrade with OPCM %s (v%s)", opcm.addr, opcm.opcmVersion); - if (opcm.semver.major == 6) { - executeV1Upgrade(opcm.addr, _delegateCaller, _systemConfig, _superchainConfig); - } else { - executeV2Upgrade(opcm.addr, _delegateCaller, _systemConfig, _superchainConfig, _disputeGameFactory); - } + executeV2Upgrade(opcm.addr, _delegateCaller, _systemConfig, _superchainConfig, _disputeGameFactory); } } - /// @notice Executes a single V1 OPCM upgrade. - /// @param _opcm The V1 OPCM contract address. - /// @param _delegateCaller The address to use as the delegate caller. - /// @param _systemConfig The SystemConfig proxy address. - /// @param _superchainConfig The SuperchainConfig proxy address. - function executeV1Upgrade( - address _opcm, - address _delegateCaller, - ISystemConfig _systemConfig, - ISuperchainConfig _superchainConfig - ) - internal - { - // Get the superchain PAO - IProxyAdmin superchainProxyAdmin = IProxyAdmin(EIP1967Helper.getAdmin(address(_superchainConfig))); - address superchainPAO = superchainProxyAdmin.owner(); - - // Upgrade the SuperchainConfig first - vm.prank(superchainPAO, true); - (bool scSuccess,) = - _opcm.delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (_superchainConfig))); - // Acceptable to fail if already up to date - scSuccess; - - // Build the OpChainConfig for the chain being upgraded - IOPContractsManager.OpChainConfig[] memory opChainConfigs = new IOPContractsManager.OpChainConfig[](1); - opChainConfigs[0] = IOPContractsManager.OpChainConfig({ - systemConfigProxy: _systemConfig, - cannonPrestate: Claim.wrap(DUMMY_CANNON_PRESTATE), - cannonKonaPrestate: Claim.wrap(DUMMY_CANNON_KONA_PRESTATE) - }); - - // Execute the OPCMv1 chain upgrade - vm.prank(_delegateCaller, true); - (bool upgradeSuccess,) = _opcm.delegatecall(abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs))); - require(upgradeSuccess, "PastUpgrades: OPCMv1 upgrade failed"); - } - /// @notice Executes a single V2 OPCM upgrade. /// @param _opcm The V2 OPCM contract address. /// @param _delegateCaller The address to use as the delegate caller. @@ -325,7 +283,8 @@ library PastUpgrades { } } - /// @notice Resolves on-chain versions for OPCMs and filters to >= 6.x.x + /// @notice Resolves on-chain versions for OPCMs and filters to >= 7.x.x (V2 OPCMs only). + /// V1 OPCMs (6.x.x) use the IOPContractsManager interface and are not compatible. /// @param _opcms The OPCMs from FFI /// @return resolved_ The resolved and filtered OPCMs function _resolveAndFilterOPCMs(OPCMInfo[] memory _opcms) private view returns (ResolvedOPCM[] memory resolved_) { @@ -334,7 +293,7 @@ library PastUpgrades { for (uint256 i = 0; i < _opcms.length; i++) { string memory opcmVersion = ISemver(_opcms[i].addr).version(); SemverComp.Semver memory sv = SemverComp.parse(opcmVersion); - if (sv.major >= 6) { + if (sv.major >= 7) { count++; } } @@ -345,7 +304,7 @@ library PastUpgrades { for (uint256 i = 0; i < _opcms.length; i++) { string memory opcmVersion = ISemver(_opcms[i].addr).version(); SemverComp.Semver memory sv = SemverComp.parse(opcmVersion); - if (sv.major >= 6) { + if (sv.major >= 7) { resolved_[idx] = ResolvedOPCM({ addr: _opcms[i].addr, opcmVersion: opcmVersion, semver: sv }); idx++; } diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 0882193995ac6..256b9d97a4ea5 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -26,10 +26,8 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { Preinstalls } from "src/libraries/Preinstalls.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { Chains } from "scripts/libraries/Chains.sol"; -import { DevFeatures } from "src/libraries/DevFeatures.sol"; - // Interfaces -import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol"; + import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPortal2.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol"; @@ -137,7 +135,6 @@ abstract contract Setup is FeatureFlags { IProtocolVersions protocolVersions; ISuperchainConfig superchainConfig; IDataAvailabilityChallenge dataAvailabilityChallenge; - IOPContractsManager opcm; IOPContractsManagerV2 opcmV2; IBigStepper mips; @@ -394,11 +391,7 @@ abstract contract Setup is FeatureFlags { anchorStateRegistry = IAnchorStateRegistry(artifacts.mustGetAddress("AnchorStateRegistryProxy")); disputeGameFactory = IDisputeGameFactory(artifacts.mustGetAddress("DisputeGameFactoryProxy")); delayedWeth = IDelayedWETH(artifacts.mustGetAddress("DelayedWETHProxy")); - if (isDevFeatureEnabled(DevFeatures.OPCM_V2)) { - opcmV2 = IOPContractsManagerV2(artifacts.mustGetAddress("OPContractsManagerV2")); - } else { - opcm = IOPContractsManager(artifacts.mustGetAddress("OPContractsManager")); - } + opcmV2 = IOPContractsManagerV2(artifacts.mustGetAddress("OPContractsManagerV2")); proxyAdmin = IProxyAdmin(artifacts.mustGetAddress("ProxyAdmin")); proxyAdminOwner = proxyAdmin.owner(); superchainProxyAdmin = IProxyAdmin(EIP1967Helper.getAdmin(address(superchainConfig))); diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index c68145c82262e..e135a75dc9063 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -383,7 +383,7 @@ contract Initializer_Test is CommonTest { function test_cannotReinitialize_succeeds() public { // Collect exclusions. uint256 j; - string[] memory excludes = new string[](11); + string[] memory excludes = new string[](10); // Contract is currently not being deployed as part of the standard deployment script. excludes[j++] = "src/L2/OptimismSuperchainERC20.sol"; // Periphery contracts don't get deployed as part of the standard deployment script. @@ -399,8 +399,6 @@ contract Initializer_Test is CommonTest { excludes[j++] = "src/dispute/SuperPermissionedDisputeGame.sol"; excludes[j++] = "src/dispute/zk/ZKDisputeGame.sol"; // TODO: Eventually remove this exclusion. Same reason as above dispute contracts. - excludes[j++] = "src/L1/OPContractsManager.sol"; - // TODO: Eventually remove this exclusion. Same reason as above dispute contracts. excludes[j++] = "src/L1/OptimismPortalInterop.sol"; // L2 contract initialization is tested in Predeploys.t.sol excludes[j++] = "src/L2/*";