From 29d0aadc0c9e058459cef5da2387246897298cd2 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Tue, 11 Mar 2025 09:41:37 -0600 Subject: [PATCH 1/8] op-deployer: Add addGameType command --- op-deployer/cmd/op-deployer/main.go | 6 + .../pkg/deployer/manage/add_game_type.go | 143 ++++++++++++++++++ .../pkg/deployer/manage/add_game_type_test.go | 63 ++++++++ op-deployer/pkg/deployer/manage/flags.go | 27 ++++ .../pkg/deployer/opcm/add_game_type.go | 92 +++++++++++ .../scripts/deploy/AddGameType.s.sol | 119 +++++++++++++++ 6 files changed, 450 insertions(+) create mode 100644 op-deployer/pkg/deployer/manage/add_game_type.go create mode 100644 op-deployer/pkg/deployer/manage/add_game_type_test.go create mode 100644 op-deployer/pkg/deployer/manage/flags.go create mode 100644 op-deployer/pkg/deployer/opcm/add_game_type.go create mode 100644 packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol diff --git a/op-deployer/cmd/op-deployer/main.go b/op-deployer/cmd/op-deployer/main.go index 2560d6a0c025c..633f27636620f 100644 --- a/op-deployer/cmd/op-deployer/main.go +++ b/op-deployer/cmd/op-deployer/main.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/bootstrap" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/inspect" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/manage" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/version" opservice "github.com/ethereum-optimism/optimism/op-service" @@ -73,6 +74,11 @@ func main() { Flags: cliapp.ProtectFlags(deployer.VerifyFlags), Action: verify.VerifyCLI, }, + { + Name: "manage", + Usage: "manages the chain", + Subcommands: manage.Commands, + }, } app.Writer = os.Stdout app.ErrWriter = os.Stderr diff --git a/op-deployer/pkg/deployer/manage/add_game_type.go b/op-deployer/pkg/deployer/manage/add_game_type.go new file mode 100644 index 0000000000000..ced4a536cdf39 --- /dev/null +++ b/op-deployer/pkg/deployer/manage/add_game_type.go @@ -0,0 +1,143 @@ +package manage + +import ( + "context" + "encoding/json" + "fmt" + "os" + + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/env" + "github.com/ethereum-optimism/optimism/op-service/ctxinterrupt" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + "github.com/urfave/cli/v2" +) + +type AddGameTypeConfig struct { + L1RPCUrl string + Logger log.Logger + ArtifactsLocator *artifacts.Locator + Input opcm.AddGameTypeInput + CacheDir string +} + +func (c *AddGameTypeConfig) Check() error { + if c.L1RPCUrl == "" { + return fmt.Errorf("l1RPCUrl must be specified") + } + + if c.Logger == nil { + return fmt.Errorf("logger must be specified") + } + + if c.ArtifactsLocator == nil { + return fmt.Errorf("artifacts locator must be specified") + } + + return nil +} + +func AddGameTypeCLI(cliCtx *cli.Context) error { + logCfg := oplog.ReadCLIConfig(cliCtx) + l := oplog.NewLogger(oplog.AppOut(cliCtx), logCfg) + oplog.SetGlobalLogHandler(l.Handler()) + + l1RPCUrl := cliCtx.String(deployer.L1RPCURLFlagName) + configFile := cliCtx.String(ConfigFlag.Name) + artifactsLocatorStr := cliCtx.String(deployer.ArtifactsLocatorFlag.Name) + cacheDir := cliCtx.String(deployer.CacheDirFlag.Name) + + artifactsLocator := new(artifacts.Locator) + if err := artifactsLocator.UnmarshalText([]byte(artifactsLocatorStr)); err != nil { + return fmt.Errorf("failed to parse artifacts locator: %w", err) + } + + // Read the input configuration from file + configData, err := os.ReadFile(configFile) + if err != nil { + return fmt.Errorf("failed to read config file: %w", err) + } + + var input opcm.AddGameTypeInput + if err := json.Unmarshal(configData, &input); err != nil { + return fmt.Errorf("failed to parse config file: %w", err) + } + + ctx := ctxinterrupt.WithCancelOnInterrupt(cliCtx.Context) + + _, calldata, err := AddGameType(ctx, AddGameTypeConfig{ + L1RPCUrl: l1RPCUrl, + Logger: l, + ArtifactsLocator: artifactsLocator, + Input: input, + CacheDir: cacheDir, + }) + if err != nil { + return fmt.Errorf("failed to add game type: %w", err) + } + + enc := json.NewEncoder(os.Stdout) + enc.SetIndent("", " ") + if err := enc.Encode(calldata); err != nil { + return fmt.Errorf("failed to encode calldata: %w", err) + } + + return nil +} + +func AddGameType(ctx context.Context, cfg AddGameTypeConfig) (opcm.AddGameTypeOutput, []broadcaster.CalldataDump, error) { + var output opcm.AddGameTypeOutput + if err := cfg.Check(); err != nil { + return output, nil, fmt.Errorf("invalid config for AddGameType: %w", err) + } + + lgr := cfg.Logger + + artifactsFS, err := artifacts.Download(ctx, cfg.ArtifactsLocator, artifacts.BarProgressor(), cfg.CacheDir) + if err != nil { + return output, nil, fmt.Errorf("failed to download artifacts: %w", err) + } + + bcaster := new(broadcaster.CalldataBroadcaster) + + l1RPC, err := rpc.Dial(cfg.L1RPCUrl) + if err != nil { + return output, nil, fmt.Errorf("failed to connect to L1 RPC: %w", err) + } + + l1Host, err := env.DefaultForkedScriptHost( + ctx, + bcaster, + lgr, + common.Address{'D'}, + artifactsFS, + l1RPC, + ) + if err != nil { + return output, nil, fmt.Errorf("failed to create script host: %w", err) + } + + script, err := opcm.NewAddGameTypeScript(l1Host) + if err != nil { + return output, nil, fmt.Errorf("failed to create L2 genesis script: %w", err) + } + + output, err = script.Run(cfg.Input) + if err != nil { + return output, nil, fmt.Errorf("error adding game type: %w", err) + } + + // Get the calldata + calldata, err := bcaster.Dump() + if err != nil { + return output, nil, fmt.Errorf("failed to get calldata: %w", err) + } + + return output, calldata, nil +} diff --git a/op-deployer/pkg/deployer/manage/add_game_type_test.go b/op-deployer/pkg/deployer/manage/add_game_type_test.go new file mode 100644 index 0000000000000..0a46ecb023db5 --- /dev/null +++ b/op-deployer/pkg/deployer/manage/add_game_type_test.go @@ -0,0 +1,63 @@ +package manage + +import ( + "context" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum-optimism/superchain-registry/validation" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + "log/slog" + "math/big" + "os" + "testing" + "time" +) + +func TestAddGameType(t *testing.T) { + rpcURL := os.Getenv("SEPOLIA_RPC_URL") + require.NotEmpty(t, rpcURL, "must specify RPC url via SEPOLIA_RPC_URL env var") + + afacts, _ := testutil.LocalArtifacts(t) + v200SepoliaAddrs := validation.StandardVersionsSepolia["op-contracts/v2.0.0-rc.1"] + testCacheDir := testutils.IsolatedTestDirWithAutoCleanup(t) + + cfg := AddGameTypeConfig{ + L1RPCUrl: rpcURL, + Logger: testlog.Logger(t, slog.LevelInfo), + ArtifactsLocator: afacts, + Input: opcm.AddGameTypeInput{ + SaltMixer: "foo", + // The values below were pulled from the Superchain Registry. + SystemConfig: common.HexToAddress("0x034edD2A225f7f429A63E0f1D2084B9E0A93b538"), + ProxyAdmin: common.HexToAddress("0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc"), + DelayedWETH: common.HexToAddress("0x9C7750C1c7b39E6b0eFeec06A1F2cf06190f6018"), + DisputeGameType: 999, + DisputeAbsolutePrestate: common.HexToHash("0x1234"), + DisputeMaxGameDepth: big.NewInt(73), + DisputeSplitDepth: big.NewInt(30), + DisputeClockExtension: 10800, + DisputeMaxClockDuration: 302400, + InitialBond: big.NewInt(0), + VM: common.Address(*v200SepoliaAddrs.Mips.Address), + Permissioned: false, + Prank: common.HexToAddress("0x1Eb2fFc903729a0F03966B917003800b145F56E2"), + OPCM: common.Address(*v200SepoliaAddrs.OPContractsManager.Address), + }, + CacheDir: testCacheDir, + } + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + output, broadcasts, err := AddGameType(ctx, cfg) + require.NoError(t, err) + + require.Equal(t, 1, len(broadcasts)) + // Selector for addGameType + require.EqualValues(t, []byte{0x16, 0x61, 0xa2, 0xe9}, broadcasts[0].Data[0:4]) + + require.NotEqual(t, common.Address{}, output.DelayedWETH) + require.NotEqual(t, common.Address{}, output.FaultDisputeGame) +} diff --git a/op-deployer/pkg/deployer/manage/flags.go b/op-deployer/pkg/deployer/manage/flags.go new file mode 100644 index 0000000000000..bd6115d6923bc --- /dev/null +++ b/op-deployer/pkg/deployer/manage/flags.go @@ -0,0 +1,27 @@ +package manage + +import ( + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/urfave/cli/v2" +) + +var ( + ConfigFlag = &cli.StringFlag{ + Name: "config", + Usage: "path to the config file", + } +) + +var Commands = cli.Commands{ + &cli.Command{ + Name: "add-game-type", + Usage: "adds a new game type to the chain", + Flags: append([]cli.Flag{ + deployer.L1RPCURLFlag, + deployer.ArtifactsLocatorFlag, + ConfigFlag, + }, oplog.CLIFlags(deployer.EnvVarPrefix)...), + Action: AddGameTypeCLI, + }, +} diff --git a/op-deployer/pkg/deployer/opcm/add_game_type.go b/op-deployer/pkg/deployer/opcm/add_game_type.go new file mode 100644 index 0000000000000..27fdaebeba935 --- /dev/null +++ b/op-deployer/pkg/deployer/opcm/add_game_type.go @@ -0,0 +1,92 @@ +package opcm + +import ( + "encoding/json" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "math/big" +) + +type AddGameTypeInput struct { + Prank common.Address + OPCM common.Address `abi:"opcm"` + SystemConfig common.Address + ProxyAdmin common.Address + DelayedWETH common.Address + DisputeGameType uint32 + DisputeAbsolutePrestate common.Hash + DisputeMaxGameDepth *big.Int + DisputeSplitDepth *big.Int + DisputeClockExtension uint64 + DisputeMaxClockDuration uint64 + InitialBond *big.Int + VM common.Address `abi:"vm"` + Permissioned bool + SaltMixer string +} + +func (a *AddGameTypeInput) UnmarshalJSON(b []byte) error { + type addGameTypeInputJSON struct { + Prank common.Address `json:"prank"` + OPCM common.Address `json:"opcm"` + SystemConfig common.Address `json:"systemConfig"` + ProxyAdmin common.Address `json:"proxyAdmin"` + DelayedWETH common.Address `json:"delayedWETH"` + DisputeGameType uint32 `json:"disputeGameType"` + DisputeAbsolutePrestate common.Hash `json:"disputeAbsolutePrestate"` + DisputeMaxGameDepth *hexutil.Big `json:"disputeMaxGameDepth"` + DisputeSplitDepth *hexutil.Big `json:"disputeSplitDepth"` + DisputeClockExtension uint64 `json:"disputeClockExtension"` + DisputeMaxClockDuration uint64 `json:"disputeMaxClockDuration"` + InitialBond *hexutil.Big `json:"initialBond"` + VM common.Address `json:"vm"` + Permissioned bool `json:"permissioned"` + SaltMixer string `json:"saltMixer"` + } + + var alias addGameTypeInputJSON + if err := json.Unmarshal(b, &alias); err != nil { + return err + } + + a.Prank = alias.Prank + a.OPCM = alias.OPCM + a.SystemConfig = alias.SystemConfig + a.ProxyAdmin = alias.ProxyAdmin + a.DelayedWETH = alias.DelayedWETH + a.DisputeGameType = alias.DisputeGameType + a.DisputeAbsolutePrestate = alias.DisputeAbsolutePrestate + + if alias.DisputeMaxGameDepth != nil { + a.DisputeMaxGameDepth = (*big.Int)(alias.DisputeMaxGameDepth) + } + + if alias.DisputeSplitDepth != nil { + a.DisputeSplitDepth = (*big.Int)(alias.DisputeSplitDepth) + } + + a.DisputeClockExtension = alias.DisputeClockExtension + a.DisputeMaxClockDuration = alias.DisputeMaxClockDuration + + if alias.InitialBond != nil { + a.InitialBond = (*big.Int)(alias.InitialBond) + } + + a.VM = alias.VM + a.Permissioned = alias.Permissioned + a.SaltMixer = alias.SaltMixer + + return nil +} + +type AddGameTypeOutput struct { + DelayedWETH common.Address `json:"delayedWETH"` + FaultDisputeGame common.Address `json:"faultDisputeGame"` +} + +type AddGameTypeScript script.DeployScriptWithOutput[AddGameTypeInput, AddGameTypeOutput] + +func NewAddGameTypeScript(host *script.Host) (AddGameTypeScript, error) { + return script.NewDeployScriptWithOutputFromFile[AddGameTypeInput, AddGameTypeOutput](host, "AddGameType.s.sol", "AddGameType") +} diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol new file mode 100644 index 0000000000000..96f1452d2c007 --- /dev/null +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +// Forge +import { Script } from "forge-std/Script.sol"; + +// Scripts +import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; +import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; + +// Interfaces +import { OPContractsManager } from "src/L1/OPContractsManager.sol"; +import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; +import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; +import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; +import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; +import { GameType, Duration, Claim } from "src/dispute/lib/Types.sol"; +import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; + +/// @title AddGameType +contract AddGameType is Script { + struct Input { + // Address that will be used for the DummyCaller contract + address prank; + // OPCM contract address + OPContractsManager opcm; + // SystemConfig contract address + ISystemConfig systemConfig; + // ProxyAdmin contract address + IProxyAdmin proxyAdmin; + // DelayedWETH contract address (optional) + IDelayedWETH delayedWETH; + // 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 delayedWETH; + IFaultDisputeGame faultDisputeGame; + } + + function run(Input memory _agi) public returns (Output memory _ago) { + addGameType(_agi, _ago); + checkOutput(_ago); + return _ago; + } + + function addGameType(Input memory _agi, Output memory _ago) internal { + // Create the game input + OPContractsManager.AddGameInput[] memory gameConfigs = new OPContractsManager.AddGameInput[](1); + gameConfigs[0] = OPContractsManager.AddGameInput({ + saltMixer: _agi.saltMixer, + systemConfig: _agi.systemConfig, + proxyAdmin: _agi.proxyAdmin, + delayedWETH: _agi.delayedWETH, + disputeGameType: _agi.disputeGameType, + disputeAbsolutePrestate: _agi.disputeAbsolutePrestate, + disputeMaxGameDepth: _agi.disputeMaxGameDepth, + disputeSplitDepth: _agi.disputeSplitDepth, + disputeClockExtension: _agi.disputeClockExtension, + disputeMaxClockDuration: _agi.disputeMaxClockDuration, + initialBond: _agi.initialBond, + vm: _agi.vm, + permissioned: _agi.permissioned + }); + + // Etch DummyCaller contract + address prank = _agi.prank; + bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCaller"); + vm.etch(prank, code); + vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcm))))); + vm.label(prank, "DummyCaller"); + + // Call into the DummyCaller to perform the delegatecall + vm.broadcast(msg.sender); + (bool success, bytes memory result) = DummyCaller(prank).addGameType(gameConfigs); + require(success, "AddGameType: addGameType failed"); + + // Decode the result and set it in the output + OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); + require(outputs.length == 1, "AddGameType: unexpected number of outputs"); + _ago.delayedWETH = outputs[0].delayedWETH; + _ago.faultDisputeGame = outputs[0].faultDisputeGame; + } + + function checkOutput(Output memory _ago) internal view { + DeployUtils.assertValidContractAddress(address(_ago.delayedWETH)); + DeployUtils.assertValidContractAddress(address(_ago.faultDisputeGame)); + } +} + +/// @title DummyCaller +contract DummyCaller { + address internal _opcmAddr; + + function addGameType(OPContractsManager.AddGameInput[] memory _gameConfigs) external returns (bool, bytes memory) { + bytes memory data = abi.encodeCall(DummyCaller.addGameType, _gameConfigs); + (bool success, bytes memory result) = _opcmAddr.delegatecall(data); + return (success, result); + } +} From ec1fe0eb91ad10a5af682ad0711719e5c4b107f7 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Tue, 6 May 2025 23:24:48 -0600 Subject: [PATCH 2/8] lint --- op-deployer/pkg/deployer/manage/add_game_type_test.go | 11 ++++++----- op-deployer/pkg/deployer/opcm/add_game_type.go | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/op-deployer/pkg/deployer/manage/add_game_type_test.go b/op-deployer/pkg/deployer/manage/add_game_type_test.go index 0a46ecb023db5..8b721e9197ce1 100644 --- a/op-deployer/pkg/deployer/manage/add_game_type_test.go +++ b/op-deployer/pkg/deployer/manage/add_game_type_test.go @@ -2,6 +2,12 @@ package manage import ( "context" + "log/slog" + "math/big" + "os" + "testing" + "time" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil" "github.com/ethereum-optimism/optimism/op-service/testlog" @@ -9,11 +15,6 @@ import ( "github.com/ethereum-optimism/superchain-registry/validation" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" - "log/slog" - "math/big" - "os" - "testing" - "time" ) func TestAddGameType(t *testing.T) { diff --git a/op-deployer/pkg/deployer/opcm/add_game_type.go b/op-deployer/pkg/deployer/opcm/add_game_type.go index 27fdaebeba935..1c404efa696b6 100644 --- a/op-deployer/pkg/deployer/opcm/add_game_type.go +++ b/op-deployer/pkg/deployer/opcm/add_game_type.go @@ -2,10 +2,11 @@ package opcm import ( "encoding/json" + "math/big" + "github.com/ethereum-optimism/optimism/op-chain-ops/script" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "math/big" ) type AddGameTypeInput struct { From 633cd8266bf2d8484588afd6ce6821d404b7d05f Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Tue, 6 May 2025 23:34:34 -0600 Subject: [PATCH 3/8] add unmarshal test --- .../pkg/deployer/opcm/add_game_type.go | 67 ++++++++--- .../pkg/deployer/opcm/add_game_type_test.go | 110 ++++++++++++++++++ 2 files changed, 159 insertions(+), 18 deletions(-) create mode 100644 op-deployer/pkg/deployer/opcm/add_game_type_test.go diff --git a/op-deployer/pkg/deployer/opcm/add_game_type.go b/op-deployer/pkg/deployer/opcm/add_game_type.go index 1c404efa696b6..d2e4966e00c23 100644 --- a/op-deployer/pkg/deployer/opcm/add_game_type.go +++ b/op-deployer/pkg/deployer/opcm/add_game_type.go @@ -27,25 +27,25 @@ type AddGameTypeInput struct { SaltMixer string } -func (a *AddGameTypeInput) UnmarshalJSON(b []byte) error { - type addGameTypeInputJSON struct { - Prank common.Address `json:"prank"` - OPCM common.Address `json:"opcm"` - SystemConfig common.Address `json:"systemConfig"` - ProxyAdmin common.Address `json:"proxyAdmin"` - DelayedWETH common.Address `json:"delayedWETH"` - DisputeGameType uint32 `json:"disputeGameType"` - DisputeAbsolutePrestate common.Hash `json:"disputeAbsolutePrestate"` - DisputeMaxGameDepth *hexutil.Big `json:"disputeMaxGameDepth"` - DisputeSplitDepth *hexutil.Big `json:"disputeSplitDepth"` - DisputeClockExtension uint64 `json:"disputeClockExtension"` - DisputeMaxClockDuration uint64 `json:"disputeMaxClockDuration"` - InitialBond *hexutil.Big `json:"initialBond"` - VM common.Address `json:"vm"` - Permissioned bool `json:"permissioned"` - SaltMixer string `json:"saltMixer"` - } +type addGameTypeInputJSON struct { + Prank common.Address `json:"prank"` + OPCM common.Address `json:"opcm"` + SystemConfig common.Address `json:"systemConfig"` + ProxyAdmin common.Address `json:"proxyAdmin"` + DelayedWETH common.Address `json:"delayedWETH"` + DisputeGameType uint32 `json:"disputeGameType"` + DisputeAbsolutePrestate common.Hash `json:"disputeAbsolutePrestate"` + DisputeMaxGameDepth *hexutil.Big `json:"disputeMaxGameDepth"` + DisputeSplitDepth *hexutil.Big `json:"disputeSplitDepth"` + DisputeClockExtension uint64 `json:"disputeClockExtension"` + DisputeMaxClockDuration uint64 `json:"disputeMaxClockDuration"` + InitialBond *hexutil.Big `json:"initialBond"` + VM common.Address `json:"vm"` + Permissioned bool `json:"permissioned"` + SaltMixer string `json:"saltMixer"` +} +func (a *AddGameTypeInput) UnmarshalJSON(b []byte) error { var alias addGameTypeInputJSON if err := json.Unmarshal(b, &alias); err != nil { return err @@ -81,6 +81,37 @@ func (a *AddGameTypeInput) UnmarshalJSON(b []byte) error { return nil } +func (a AddGameTypeInput) MarshalJSON() ([]byte, error) { + alias := addGameTypeInputJSON{ + Prank: a.Prank, + OPCM: a.OPCM, + SystemConfig: a.SystemConfig, + ProxyAdmin: a.ProxyAdmin, + DelayedWETH: a.DelayedWETH, + DisputeGameType: a.DisputeGameType, + DisputeAbsolutePrestate: a.DisputeAbsolutePrestate, + DisputeClockExtension: a.DisputeClockExtension, + DisputeMaxClockDuration: a.DisputeMaxClockDuration, + VM: a.VM, + Permissioned: a.Permissioned, + SaltMixer: a.SaltMixer, + } + + if a.DisputeMaxGameDepth != nil { + alias.DisputeMaxGameDepth = (*hexutil.Big)(a.DisputeMaxGameDepth) + } + + if a.DisputeSplitDepth != nil { + alias.DisputeSplitDepth = (*hexutil.Big)(a.DisputeSplitDepth) + } + + if a.InitialBond != nil { + alias.InitialBond = (*hexutil.Big)(a.InitialBond) + } + + return json.Marshal(alias) +} + type AddGameTypeOutput struct { DelayedWETH common.Address `json:"delayedWETH"` FaultDisputeGame common.Address `json:"faultDisputeGame"` diff --git a/op-deployer/pkg/deployer/opcm/add_game_type_test.go b/op-deployer/pkg/deployer/opcm/add_game_type_test.go new file mode 100644 index 0000000000000..47328e5cac8de --- /dev/null +++ b/op-deployer/pkg/deployer/opcm/add_game_type_test.go @@ -0,0 +1,110 @@ +package opcm + +import ( + "encoding/json" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func compareBigInt(a, b *big.Int) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return a.Cmp(b) == 0 +} + +// compareAddGameTypeInputs compares two AddGameTypeInput structs with special handling for *big.Int fields. We can't +// use require.Equal directly because zero *big.Int structs can either be nil or a zero value, which trips up the +// equality checker. +func compareAddGameTypeInputs(t *testing.T, expected, actual AddGameTypeInput) { + require.Equal(t, expected.Prank, actual.Prank) + require.Equal(t, expected.OPCM, actual.OPCM) + require.Equal(t, expected.SystemConfig, actual.SystemConfig) + require.Equal(t, expected.ProxyAdmin, actual.ProxyAdmin) + require.Equal(t, expected.DelayedWETH, actual.DelayedWETH) + require.Equal(t, expected.DisputeGameType, actual.DisputeGameType) + require.Equal(t, expected.DisputeAbsolutePrestate, actual.DisputeAbsolutePrestate) + require.Equal(t, expected.DisputeClockExtension, actual.DisputeClockExtension) + require.Equal(t, expected.DisputeMaxClockDuration, actual.DisputeMaxClockDuration) + require.Equal(t, expected.VM, actual.VM) + require.Equal(t, expected.Permissioned, actual.Permissioned) + require.Equal(t, expected.SaltMixer, actual.SaltMixer) + + // Special handling for *big.Int fields + require.True(t, compareBigInt(expected.DisputeMaxGameDepth, actual.DisputeMaxGameDepth)) + require.True(t, compareBigInt(expected.DisputeSplitDepth, actual.DisputeSplitDepth)) + require.True(t, compareBigInt(expected.InitialBond, actual.InitialBond)) +} + +func TestAddGameTypeInput_MarshalUnmarshalJSON(t *testing.T) { + // Define test cases + testCases := []struct { + name string + input AddGameTypeInput + }{ + { + name: "basic", + input: AddGameTypeInput{ + Prank: common.HexToAddress("0x1111111111111111111111111111111111111111"), + OPCM: common.HexToAddress("0x2222222222222222222222222222222222222222"), + SystemConfig: common.HexToAddress("0x3333333333333333333333333333333333333333"), + ProxyAdmin: common.HexToAddress("0x4444444444444444444444444444444444444444"), + DelayedWETH: common.HexToAddress("0x5555555555555555555555555555555555555555"), + DisputeGameType: 1, + DisputeAbsolutePrestate: common.HexToHash("0x6666666666666666666666666666666666666666666666666666666666666666"), + DisputeMaxGameDepth: big.NewInt(100), + DisputeSplitDepth: big.NewInt(10), + DisputeClockExtension: 1000, + DisputeMaxClockDuration: 2000, + InitialBond: big.NewInt(5000000000000000000), // 5 ETH + VM: common.HexToAddress("0x7777777777777777777777777777777777777777"), + Permissioned: true, + SaltMixer: "salt_mixer_value", + }, + }, + { + name: "nil big.Int fields", + input: AddGameTypeInput{ + Prank: common.HexToAddress("0x1111111111111111111111111111111111111111"), + OPCM: common.HexToAddress("0x2222222222222222222222222222222222222222"), + SystemConfig: common.HexToAddress("0x3333333333333333333333333333333333333333"), + ProxyAdmin: common.HexToAddress("0x4444444444444444444444444444444444444444"), + DelayedWETH: common.HexToAddress("0x5555555555555555555555555555555555555555"), + DisputeGameType: 1, + DisputeAbsolutePrestate: common.HexToHash("0x6666666666666666666666666666666666666666666666666666666666666666"), + DisputeMaxGameDepth: nil, // nil big.Int + DisputeSplitDepth: nil, // nil big.Int + DisputeClockExtension: 1000, + DisputeMaxClockDuration: 2000, + InitialBond: nil, // nil big.Int + VM: common.HexToAddress("0x7777777777777777777777777777777777777777"), + Permissioned: false, + SaltMixer: "salt_mixer_value", + }, + }, + } + + // Run test cases + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + data, err := json.Marshal(tc.input) + require.NoError(t, err) + + var unmarshaled AddGameTypeInput + err = json.Unmarshal(data, &unmarshaled) + require.NoError(t, err) + + compareAddGameTypeInputs(t, tc.input, unmarshaled) + + newData, err := json.Marshal(unmarshaled) + require.NoError(t, err) + require.JSONEq(t, string(data), string(newData)) + }) + } +} From 51ceac09437560242deb930606a862174d6c6b2e Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Tue, 6 May 2025 23:36:05 -0600 Subject: [PATCH 4/8] contracts nits --- .../contracts-bedrock/scripts/deploy/AddGameType.s.sol | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index 96f1452d2c007..2aaf974f9756f 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -5,7 +5,6 @@ pragma solidity ^0.8.15; import { Script } from "forge-std/Script.sol"; // Scripts -import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; // Interfaces @@ -57,10 +56,10 @@ contract AddGameType is Script { IFaultDisputeGame faultDisputeGame; } - function run(Input memory _agi) public returns (Output memory _ago) { - addGameType(_agi, _ago); - checkOutput(_ago); - return _ago; + function run(Input memory _agi) public returns (Output memory ago_) { + addGameType(_agi, ago_); + checkOutput(ago_); + return ago_; } function addGameType(Input memory _agi, Output memory _ago) internal { From 19194ae1a09f0386b575b89a8172b77a4961a173 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Wed, 7 May 2025 12:50:19 -0600 Subject: [PATCH 5/8] CR items --- .../pkg/deployer/manage/add_game_type_test.go | 25 ++++++++----- .../pkg/deployer/opcm/add_game_type.go | 36 +++++++++---------- .../pkg/deployer/opcm/add_game_type_test.go | 24 ++++++------- .../scripts/deploy/AddGameType.s.sol | 28 +++++++-------- 4 files changed, 60 insertions(+), 53 deletions(-) diff --git a/op-deployer/pkg/deployer/manage/add_game_type_test.go b/op-deployer/pkg/deployer/manage/add_game_type_test.go index 8b721e9197ce1..f1daf89e01266 100644 --- a/op-deployer/pkg/deployer/manage/add_game_type_test.go +++ b/op-deployer/pkg/deployer/manage/add_game_type_test.go @@ -2,6 +2,8 @@ package manage import ( "context" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard" + "github.com/ethereum/go-ethereum/superchain" "log/slog" "math/big" "os" @@ -22,19 +24,24 @@ func TestAddGameType(t *testing.T) { require.NotEmpty(t, rpcURL, "must specify RPC url via SEPOLIA_RPC_URL env var") afacts, _ := testutil.LocalArtifacts(t) - v200SepoliaAddrs := validation.StandardVersionsSepolia["op-contracts/v2.0.0-rc.1"] + v200SepoliaAddrs := validation.StandardVersionsSepolia[standard.ContractsV200Tag] testCacheDir := testutils.IsolatedTestDirWithAutoCleanup(t) + supChain, err := superchain.GetChain(11155420) + require.NoError(t, err) + supChainConfig, err := supChain.Config() + require.NoError(t, err) + cfg := AddGameTypeConfig{ L1RPCUrl: rpcURL, Logger: testlog.Logger(t, slog.LevelInfo), ArtifactsLocator: afacts, Input: opcm.AddGameTypeInput{ SaltMixer: "foo", - // The values below were pulled from the Superchain Registry. - SystemConfig: common.HexToAddress("0x034edD2A225f7f429A63E0f1D2084B9E0A93b538"), - ProxyAdmin: common.HexToAddress("0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc"), - DelayedWETH: common.HexToAddress("0x9C7750C1c7b39E6b0eFeec06A1F2cf06190f6018"), + // The values below were pulled from the Superchain Registry for OP Sepolia. + SystemConfigProxy: *supChainConfig.Addresses.SystemConfigProxy, + OPChainProxyAdmin: *supChainConfig.Addresses.ProxyAdmin, + DelayedWETHProxy: *supChainConfig.Addresses.DelayedWETHProxy, DisputeGameType: 999, DisputeAbsolutePrestate: common.HexToHash("0x1234"), DisputeMaxGameDepth: big.NewInt(73), @@ -44,8 +51,8 @@ func TestAddGameType(t *testing.T) { InitialBond: big.NewInt(0), VM: common.Address(*v200SepoliaAddrs.Mips.Address), Permissioned: false, - Prank: common.HexToAddress("0x1Eb2fFc903729a0F03966B917003800b145F56E2"), - OPCM: common.Address(*v200SepoliaAddrs.OPContractsManager.Address), + Prank: *supChainConfig.Roles.ProxyAdminOwner, + OPCMImpl: common.Address(*v200SepoliaAddrs.OPContractsManager.Address), }, CacheDir: testCacheDir, } @@ -59,6 +66,6 @@ func TestAddGameType(t *testing.T) { // Selector for addGameType require.EqualValues(t, []byte{0x16, 0x61, 0xa2, 0xe9}, broadcasts[0].Data[0:4]) - require.NotEqual(t, common.Address{}, output.DelayedWETH) - require.NotEqual(t, common.Address{}, output.FaultDisputeGame) + require.NotEqual(t, common.Address{}, output.DelayedWETHProxy) + require.NotEqual(t, common.Address{}, output.FaultDisputeGameProxy) } diff --git a/op-deployer/pkg/deployer/opcm/add_game_type.go b/op-deployer/pkg/deployer/opcm/add_game_type.go index d2e4966e00c23..96d25d7a172bb 100644 --- a/op-deployer/pkg/deployer/opcm/add_game_type.go +++ b/op-deployer/pkg/deployer/opcm/add_game_type.go @@ -11,10 +11,10 @@ import ( type AddGameTypeInput struct { Prank common.Address - OPCM common.Address `abi:"opcm"` - SystemConfig common.Address - ProxyAdmin common.Address - DelayedWETH common.Address + OPCMImpl common.Address `abi:"opcmImpl"` + SystemConfigProxy common.Address + OPChainProxyAdmin common.Address `abi:"opChainProxyAdmin"` + DelayedWETHProxy common.Address DisputeGameType uint32 DisputeAbsolutePrestate common.Hash DisputeMaxGameDepth *big.Int @@ -29,10 +29,10 @@ type AddGameTypeInput struct { type addGameTypeInputJSON struct { Prank common.Address `json:"prank"` - OPCM common.Address `json:"opcm"` - SystemConfig common.Address `json:"systemConfig"` - ProxyAdmin common.Address `json:"proxyAdmin"` - DelayedWETH common.Address `json:"delayedWETH"` + OPCMImpl common.Address `json:"opcmimpl"` + SystemConfigProxy common.Address `json:"systemConfigProxy"` + OPChainProxyAdmin common.Address `json:"opChainProxyAdmin"` + DelayedWETHProxy common.Address `json:"delayedWETHProxy"` DisputeGameType uint32 `json:"disputeGameType"` DisputeAbsolutePrestate common.Hash `json:"disputeAbsolutePrestate"` DisputeMaxGameDepth *hexutil.Big `json:"disputeMaxGameDepth"` @@ -52,10 +52,10 @@ func (a *AddGameTypeInput) UnmarshalJSON(b []byte) error { } a.Prank = alias.Prank - a.OPCM = alias.OPCM - a.SystemConfig = alias.SystemConfig - a.ProxyAdmin = alias.ProxyAdmin - a.DelayedWETH = alias.DelayedWETH + a.OPCMImpl = alias.OPCMImpl + a.SystemConfigProxy = alias.SystemConfigProxy + a.OPChainProxyAdmin = alias.OPChainProxyAdmin + a.DelayedWETHProxy = alias.DelayedWETHProxy a.DisputeGameType = alias.DisputeGameType a.DisputeAbsolutePrestate = alias.DisputeAbsolutePrestate @@ -84,10 +84,10 @@ func (a *AddGameTypeInput) UnmarshalJSON(b []byte) error { func (a AddGameTypeInput) MarshalJSON() ([]byte, error) { alias := addGameTypeInputJSON{ Prank: a.Prank, - OPCM: a.OPCM, - SystemConfig: a.SystemConfig, - ProxyAdmin: a.ProxyAdmin, - DelayedWETH: a.DelayedWETH, + OPCMImpl: a.OPCMImpl, + SystemConfigProxy: a.SystemConfigProxy, + OPChainProxyAdmin: a.OPChainProxyAdmin, + DelayedWETHProxy: a.DelayedWETHProxy, DisputeGameType: a.DisputeGameType, DisputeAbsolutePrestate: a.DisputeAbsolutePrestate, DisputeClockExtension: a.DisputeClockExtension, @@ -113,8 +113,8 @@ func (a AddGameTypeInput) MarshalJSON() ([]byte, error) { } type AddGameTypeOutput struct { - DelayedWETH common.Address `json:"delayedWETH"` - FaultDisputeGame common.Address `json:"faultDisputeGame"` + DelayedWETHProxy common.Address `json:"delayedWETHProxy"` + FaultDisputeGameProxy common.Address `json:"faultDisputeGameProxy"` } type AddGameTypeScript script.DeployScriptWithOutput[AddGameTypeInput, AddGameTypeOutput] diff --git a/op-deployer/pkg/deployer/opcm/add_game_type_test.go b/op-deployer/pkg/deployer/opcm/add_game_type_test.go index 47328e5cac8de..c22d90274e6c6 100644 --- a/op-deployer/pkg/deployer/opcm/add_game_type_test.go +++ b/op-deployer/pkg/deployer/opcm/add_game_type_test.go @@ -24,10 +24,10 @@ func compareBigInt(a, b *big.Int) bool { // equality checker. func compareAddGameTypeInputs(t *testing.T, expected, actual AddGameTypeInput) { require.Equal(t, expected.Prank, actual.Prank) - require.Equal(t, expected.OPCM, actual.OPCM) - require.Equal(t, expected.SystemConfig, actual.SystemConfig) - require.Equal(t, expected.ProxyAdmin, actual.ProxyAdmin) - require.Equal(t, expected.DelayedWETH, actual.DelayedWETH) + require.Equal(t, expected.OPCMImpl, actual.OPCMImpl) + require.Equal(t, expected.SystemConfigProxy, actual.SystemConfigProxy) + require.Equal(t, expected.OPChainProxyAdmin, actual.OPChainProxyAdmin) + require.Equal(t, expected.DelayedWETHProxy, actual.DelayedWETHProxy) require.Equal(t, expected.DisputeGameType, actual.DisputeGameType) require.Equal(t, expected.DisputeAbsolutePrestate, actual.DisputeAbsolutePrestate) require.Equal(t, expected.DisputeClockExtension, actual.DisputeClockExtension) @@ -52,10 +52,10 @@ func TestAddGameTypeInput_MarshalUnmarshalJSON(t *testing.T) { name: "basic", input: AddGameTypeInput{ Prank: common.HexToAddress("0x1111111111111111111111111111111111111111"), - OPCM: common.HexToAddress("0x2222222222222222222222222222222222222222"), - SystemConfig: common.HexToAddress("0x3333333333333333333333333333333333333333"), - ProxyAdmin: common.HexToAddress("0x4444444444444444444444444444444444444444"), - DelayedWETH: common.HexToAddress("0x5555555555555555555555555555555555555555"), + OPCMImpl: common.HexToAddress("0x2222222222222222222222222222222222222222"), + SystemConfigProxy: common.HexToAddress("0x3333333333333333333333333333333333333333"), + OPChainProxyAdmin: common.HexToAddress("0x4444444444444444444444444444444444444444"), + DelayedWETHProxy: common.HexToAddress("0x5555555555555555555555555555555555555555"), DisputeGameType: 1, DisputeAbsolutePrestate: common.HexToHash("0x6666666666666666666666666666666666666666666666666666666666666666"), DisputeMaxGameDepth: big.NewInt(100), @@ -72,10 +72,10 @@ func TestAddGameTypeInput_MarshalUnmarshalJSON(t *testing.T) { name: "nil big.Int fields", input: AddGameTypeInput{ Prank: common.HexToAddress("0x1111111111111111111111111111111111111111"), - OPCM: common.HexToAddress("0x2222222222222222222222222222222222222222"), - SystemConfig: common.HexToAddress("0x3333333333333333333333333333333333333333"), - ProxyAdmin: common.HexToAddress("0x4444444444444444444444444444444444444444"), - DelayedWETH: common.HexToAddress("0x5555555555555555555555555555555555555555"), + OPCMImpl: common.HexToAddress("0x2222222222222222222222222222222222222222"), + SystemConfigProxy: common.HexToAddress("0x3333333333333333333333333333333333333333"), + OPChainProxyAdmin: common.HexToAddress("0x4444444444444444444444444444444444444444"), + DelayedWETHProxy: common.HexToAddress("0x5555555555555555555555555555555555555555"), DisputeGameType: 1, DisputeAbsolutePrestate: common.HexToHash("0x6666666666666666666666666666666666666666666666666666666666666666"), DisputeMaxGameDepth: nil, // nil big.Int diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index 2aaf974f9756f..489885315cbe6 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -22,13 +22,13 @@ contract AddGameType is Script { // Address that will be used for the DummyCaller contract address prank; // OPCM contract address - OPContractsManager opcm; + OPContractsManager opcmImpl; // SystemConfig contract address - ISystemConfig systemConfig; + ISystemConfig systemConfigProxy; // ProxyAdmin contract address - IProxyAdmin proxyAdmin; + IProxyAdmin opChainProxyAdmin; // DelayedWETH contract address (optional) - IDelayedWETH delayedWETH; + IDelayedWETH delayedWETHProxy; // Game type to add GameType disputeGameType; // Absolute prestate for the game @@ -52,8 +52,8 @@ contract AddGameType is Script { } struct Output { - IDelayedWETH delayedWETH; - IFaultDisputeGame faultDisputeGame; + IDelayedWETH delayedWETHProxy; + IFaultDisputeGame faultDisputeGameProxy; } function run(Input memory _agi) public returns (Output memory ago_) { @@ -67,9 +67,9 @@ contract AddGameType is Script { OPContractsManager.AddGameInput[] memory gameConfigs = new OPContractsManager.AddGameInput[](1); gameConfigs[0] = OPContractsManager.AddGameInput({ saltMixer: _agi.saltMixer, - systemConfig: _agi.systemConfig, - proxyAdmin: _agi.proxyAdmin, - delayedWETH: _agi.delayedWETH, + systemConfig: _agi.systemConfigProxy, + proxyAdmin: _agi.opChainProxyAdmin, + delayedWETH: _agi.delayedWETHProxy, disputeGameType: _agi.disputeGameType, disputeAbsolutePrestate: _agi.disputeAbsolutePrestate, disputeMaxGameDepth: _agi.disputeMaxGameDepth, @@ -85,7 +85,7 @@ contract AddGameType is Script { address prank = _agi.prank; bytes memory code = vm.getDeployedCode("AddGameType.s.sol:DummyCaller"); vm.etch(prank, code); - vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcm))))); + vm.store(prank, bytes32(0), bytes32(uint256(uint160(address(_agi.opcmImpl))))); vm.label(prank, "DummyCaller"); // Call into the DummyCaller to perform the delegatecall @@ -96,13 +96,13 @@ contract AddGameType is Script { // Decode the result and set it in the output OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); require(outputs.length == 1, "AddGameType: unexpected number of outputs"); - _ago.delayedWETH = outputs[0].delayedWETH; - _ago.faultDisputeGame = outputs[0].faultDisputeGame; + _ago.delayedWETHProxy = outputs[0].delayedWETH; + _ago.faultDisputeGameProxy = outputs[0].faultDisputeGame; } function checkOutput(Output memory _ago) internal view { - DeployUtils.assertValidContractAddress(address(_ago.delayedWETH)); - DeployUtils.assertValidContractAddress(address(_ago.faultDisputeGame)); + DeployUtils.assertValidContractAddress(address(_ago.delayedWETHProxy)); + DeployUtils.assertValidContractAddress(address(_ago.faultDisputeGameProxy)); } } From d1519a4c1406c8d2cb91eb64be665b584814a4c0 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Wed, 7 May 2025 12:59:19 -0600 Subject: [PATCH 6/8] lint --- op-deployer/pkg/deployer/manage/add_game_type_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/op-deployer/pkg/deployer/manage/add_game_type_test.go b/op-deployer/pkg/deployer/manage/add_game_type_test.go index f1daf89e01266..4bf8e47b0ef37 100644 --- a/op-deployer/pkg/deployer/manage/add_game_type_test.go +++ b/op-deployer/pkg/deployer/manage/add_game_type_test.go @@ -2,14 +2,15 @@ package manage import ( "context" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard" - "github.com/ethereum/go-ethereum/superchain" "log/slog" "math/big" "os" "testing" "time" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard" + "github.com/ethereum/go-ethereum/superchain" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil" "github.com/ethereum-optimism/optimism/op-service/testlog" From 7417eb6115271e4fb286640c327af91e8cb0d137 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Fri, 9 May 2025 10:48:17 -0600 Subject: [PATCH 7/8] cr updates --- .../scripts/deploy/AddGameType.s.sol | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index 489885315cbe6..abf1fc24aa046 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -56,13 +56,7 @@ contract AddGameType is Script { IFaultDisputeGame faultDisputeGameProxy; } - function run(Input memory _agi) public returns (Output memory ago_) { - addGameType(_agi, ago_); - checkOutput(ago_); - return ago_; - } - - function addGameType(Input memory _agi, Output memory _ago) internal { + function run(Input memory _agi) public returns (Output memory) { // Create the game input OPContractsManager.AddGameInput[] memory gameConfigs = new OPContractsManager.AddGameInput[](1); gameConfigs[0] = OPContractsManager.AddGameInput({ @@ -96,8 +90,10 @@ contract AddGameType is Script { // Decode the result and set it in the output OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); require(outputs.length == 1, "AddGameType: unexpected number of outputs"); - _ago.delayedWETHProxy = outputs[0].delayedWETH; - _ago.faultDisputeGameProxy = outputs[0].faultDisputeGame; + return Output({ + delayedWETHProxy: outputs[0].delayedWETH, + faultDisputeGameProxy: outputs[0].faultDisputeGame + }); } function checkOutput(Output memory _ago) internal view { From 0f2f20ae7504ddbdfc83deecfe68904a0d33e611 Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Mon, 12 May 2025 16:24:35 -0600 Subject: [PATCH 8/8] lint --- packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol index abf1fc24aa046..5d65d1111cdcc 100644 --- a/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/AddGameType.s.sol @@ -90,10 +90,7 @@ contract AddGameType is Script { // Decode the result and set it in the output OPContractsManager.AddGameOutput[] memory outputs = abi.decode(result, (OPContractsManager.AddGameOutput[])); require(outputs.length == 1, "AddGameType: unexpected number of outputs"); - return Output({ - delayedWETHProxy: outputs[0].delayedWETH, - faultDisputeGameProxy: outputs[0].faultDisputeGame - }); + return Output({ delayedWETHProxy: outputs[0].delayedWETH, faultDisputeGameProxy: outputs[0].faultDisputeGame }); } function checkOutput(Output memory _ago) internal view {