Skip to content
2 changes: 2 additions & 0 deletions pages/operators/chain-operators/tutorials.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ This section provides information on adding attributes to the derivation functio

<Card title="Running a Local Development Environment" href="/operators/chain-operators/tutorials/chain-dev-net" />

<Card title="Deploying new dispute games with OPCM" href="/operators/chain-operators/tutorials/dispute-games" />

<Card title="Integrating a new da layer with alt Da" href="/operators/chain-operators/tutorials/integrating-da-layer" />

<Card title="Migrating to permissionless fault proofs on OP Stack" href="/operators/chain-operators/tutorials/migrating-permissionless" />
Expand Down
150 changes: 150 additions & 0 deletions pages/operators/chain-operators/tutorials/dispute-games.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
---
title: Deploying new dispute games with OPCM
description: Learn how to deploy new dispute games to an OP Stack chain using OPCM
lang: en-US
content_type: tutorial
topic: deploying-dispute-games-opcm
personas:
- chain-operator
- protocol-developer
categories:
- fault proofs
- smart contracts upgrades
- OPCM upgrade
- OPCM contracts
- dispute game
is_imported_content: 'false'
---

import { Callout } from 'nextra/components'

# Deploying new dispute games with OPCM

This guide provides instructions on how to deploy new dispute games to an OP Stack chain using the [OPCM (OP Contracts Manager)](/stack/opcm). This process is particularly relevant for teams looking to upgrade their chains to support permissionless dispute games.

## Prerequisites

Before you begin, ensure that:

* Run op-contracts/v2.0.0 or higher on your chain
* Own the chain's L1 `ProxyAdmin` contract
* Install the Forge toolkit (see [Foundry docs](https://getfoundry.sh/))

## Understanding dispute games

The OP Stack uses two types of dispute games:

* **Permissioned dispute game**: Limited to specific proposer and challenger addresses
* **Permissionless dispute game**: Open to anyone to propose or challenge

<Callout type="warning">
In the Permissioned dispute game (PDG), the [challenger role](/superchain/privileged-roles#challenger) is a protocol-level permission assigned to specific addresses, allowing them to initiate or respond to disputes. This role is distinct from the op-challenger service, which is an off-chain monitoring service responsible for automatically detecting discrepancies and submitting challenges.
While the op-challenger service typically operates using an address that has been assigned the challenger role, the protocol-level role itself can be independently assigned, regardless of whether the op-challenger service is in use.
Refer to the [OP Stack configurability spec](https://specs.optimism.io/protocol/configurability.html) for more details.
</Callout>

All chains deployed with `op-deployer` only initially include the permissioned dispute game.
This guide explains how to add the permissionless game.

## The `addGameType` function

The OPCM contract contains an `addGameType` function that handles the deployment of new dispute games. This function:

1. Deploys a new dispute game implementation
2. Optionally deploys a new [`DelayedWETH`](https://github.com/ethereum-optimism/optimism/blob/6dc586d551f55b2b3a607cfcca9d3d272dec84d7/packages/contracts-bedrock/src/dispute/DelayedWETH.sol) contract
3. Registers the game with the `DisputeGameFactory`
4. Sets the initial bond amount

### 1. Finding the correct OPCM instance

Each OP Contracts release has its own OPCM instance. You must use the OPCM corresponding exactly to your chain's contract version. For example, if your system uses contracts version **v3.0.0**, you must use the OPCM for **v3.0.0**.

To find the correct OPCM address:

* For **Mainnet**, refer to the [standard-versions-mainnet.toml](https://github.com/ethereum-optimism/superchain-registry/blob/main/validation/standard/standard-versions-mainnet.toml) file in the Superchain Registry.
* For **Sepolia**, refer to the [standard-versions-sepolia.toml](https://github.com/ethereum-optimism/superchain-registry/blob/main/validation/standard/standard-versions-sepolia.toml) file in the Superchain Registry.

These registry files contain mappings between OP contract versions and their corresponding OPCM addresses.

### 2. Preparing the `addGameType` Call

The `addGameType` function expects an array of `AddGameInput` structs. Here is the structure:

```solidity
struct AddGameInput {
string saltMixer;
ISystemConfig systemConfig;
IProxyAdmin proxyAdmin;
IDelayedWETH delayedWETH;
GameType disputeGameType;
Claim disputeAbsolutePrestate;
uint256 disputeMaxGameDepth;
uint256 disputeSplitDepth;
Duration disputeClockExtension;
Duration disputeMaxClockDuration;
uint256 initialBond;
IBigStepper vm;
bool permissioned;
}
```

**Key parameters explained:**

* **saltMixer:** A string used to create unique contract addresses
* **systemConfig:** The address of your chain's `SystemConfig` contract
* **proxyAdmin:** The Address of your chain's `ProxyAdmin` contract
* **delayedWETH:** The Address of the `DelayedWETH` contract (use zero address to deploy a new one)
* **disputeGameType:** For permissionless games, use `GameTypes.CANNON`
* **disputeAbsolutePrestate:** The absolute prestate hash for the game
* **permissioned:** Set to `false` for a permissionless game

For a permissionless game, you'll generally want to mirror most parameters from your existing permissioned game, but set permissioned to `false` and use the GameType `CANNON`.

3. Execute the addGameType function
The following is a template for calling the addGameType function using Forge's cast:

<Callout type="info">
The most recommended way is to use a script to execute this call, rather than manual execution.
</Callout>

```bash
# Retrieve existing values from chain for reference
# Get permissioned game implementation
PERMISSIONED_GAME=$(cast call --rpc-url $RPC_URL $DISPUTE_GAME_FACTORY "gameImpls(uint32)" $PERMISSIONED_GAME_TYPE)

# Retrieve parameters from existing permissioned game
ABSOLUTE_PRESTATE=$(cast call --rpc-url $RPC_URL $PERMISSIONED_GAME "absolutePrestate()")
MAX_GAME_DEPTH=$(cast call --rpc-url $RPC_URL $PERMISSIONED_GAME "maxGameDepth()")
SPLIT_DEPTH=$(cast call --rpc-url $RPC_URL $PERMISSIONED_GAME "splitDepth()")
CLOCK_EXTENSION=$(cast call --rpc-url $RPC_URL $PERMISSIONED_GAME "clockExtension()")
MAX_CLOCK_DURATION=$(cast call --rpc-url $RPC_URL $PERMISSIONED_GAME "maxClockDuration()")
VM=$(cast call --rpc-url $RPC_URL $PERMISSIONED_GAME "vm()")
ANCHOR_STATE_REGISTRY=$(cast call --rpc-url $RPC_URL $PERMISSIONED_GAME "anchorStateRegistry()")
L2_CHAIN_ID=$(cast call --rpc-url $RPC_URL $PERMISSIONED_GAME "l2ChainId()")

# Create call data for addGameType function
# Note: Set delayedWETH to 0x0 to deploy a new one
CALLDATA=$(cast calldata "addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[])" \
"[(\
\"unique_salt_mixer\",\
$SYSTEM_CONFIG,\
$PROXY_ADMIN,\
0x0000000000000000000000000000000000000000,\
$CANNON_GAME_TYPE,\
$ABSOLUTE_PRESTATE,\
$MAX_GAME_DEPTH,\
$SPLIT_DEPTH,\
$CLOCK_EXTENSION,\
$MAX_CLOCK_DURATION,\
$INITIAL_BOND,\
$VM,\
false\
)]")

# Execute the transaction
cast send --rpc-url $RPC_URL --private-key $PRIVATE_KEY $OPCM_ADDRESS $CALLDATA
```

4. Setting the respected game type
After deploying the permissionless dispute game, you'll need to update the respectedGameType in the OptimismPortal to start using it.
For detailed instructions on setting the respected game type and migrating your chain from permissioned to permissionless fault proofs, refer to the [migrating to permissionless fault proofs guide](/operators/chain-operators/tutorials/migrating-permissionless).
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ Before beginning this transition, your chain should:

* Be running a standard OP Stack implementation
* Use contracts version [**v2.0.0**](https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv2.0.0).
* Be operating with the required infrastructure services including [`op-challenger`](/operators/chain-operators/tools/op-challenger) and [`op-dispute-mon`](/operators/chain-operators/tools/chain-monitoring#dispute-mon).
* Be operating with the required infrastructure services including [`op-challenger`](/stack/fault-proofs/challenger) and [`op-dispute-mon`](/operators/chain-operators/tools/chain-monitoring#dispute-mon).

## Migration steps

The process of migrating from permissioned to permissionless fault proofs involves four main phases: configuring off-chain dispute components, deploying the necessary smart contracts, testing the system thoroughly, and finally switching the chain to use permissionless proofs. Each step builds on the previous one to ensure a smooth and secure transition.
Expand Down Expand Up @@ -201,7 +202,7 @@ This method will:
2. Setup the `DelayedWethProxy` for the new game
3. Reinitialize the `AnchorStateRegistry` to add the new game type.

See a high‐level implementation from this [todo:add the docs later](/superchain/privileged-roles).
See a high‐level implementation from this [docs](/operators/chain-operators/tutorials/dispute-games).

## 3. Testing off-chain agents

Expand Down Expand Up @@ -378,9 +379,6 @@ OP_PROPOSER_GAME_TYPE=0
This action requires all in-progress withdrawals to be re-proven against a new `FaultDisputeGame` created after this update occurs.
</Callout>

## Todo: Update the next steps
## Next steps

* [Optimism Fault Proof Documentation](/operators/chain-operators/tools/op-challenger)
* [Privileged Roles Documentation](/superchain/privileged-roles)
* [op-challenger GitHub](https://github.com/ethereum-optimism/optimism/tree/develop/op-challenger)
* [op-dispute-mon GitHub](https://github.com/ethereum-optimism/optimism/tree/develop/op-dispute-mon)
* For more detail on deploying new dispute games with OPCM, [see the docs](/operators/chain-operators/tutorials/dispute-games).
4 changes: 2 additions & 2 deletions words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ Devnet
devnet
Devnets
devnets
Devs

direnv
DISABLETXPOOLGOSSIP
disabletxpoolgossip
Expand Down Expand Up @@ -270,6 +268,7 @@ offchain
opchaina
opchainb
OPCM
opcm
Openfort
oplabs
opnode's
Expand Down Expand Up @@ -386,6 +385,7 @@ SRLV
Stablecoins
stablecoins
statefulset
structs
subcomponents
subgame
subheaders
Expand Down