DisputeGameFactory
Table of Contents
Overview
The DisputeGameFactory serves as the central registry and factory for creating dispute game contracts in the OP Stack fault proof system. It manages game type implementations, tracks all created games, and enforces bond requirements for game creation.
Definitions
Game UUID
A unique identifier for a dispute game computed as keccak256(gameType || rootClaim || extraData). This identifier
ensures that each unique combination of game parameters can only result in one game instance.
Game Implementation
A template contract that implements the IDisputeGame interface. The factory clones this implementation using the Clone With Immutable Args (CWIA) pattern to create new game instances efficiently.
Initialization Bond
The amount of ETH (in wei) required to create a dispute game of a specific game type. This bond is forwarded to the created game's initialize function and serves as the initial stake in the dispute.
Game Clone
A minimal proxy contract created using the CWIA pattern that delegates all calls to a Game Implementation while storing immutable game-specific parameters (creator address, root claim, parent hash, extra data) in its bytecode.
Assumptions
aDGF-001: Owner operates within governance constraints
The owner of the DisputeGameFactory is trusted to set Game Implementations and Initialization Bonds according to governance processes. Malicious or incorrect configuration by the owner could compromise the security of the dispute system.
Mitigations
- Owner is controlled by governance multisig
- Configuration changes are subject to governance review
- Monitoring of owner actions
aDGF-002: Implementation contracts are valid IDisputeGame Implementations
Implementation contracts registered via setImplementation are assumed to correctly implement the IDisputeGame interface and initialize properly when cloned. Invalid implementations could cause game creation to fail or games to behave incorrectly.
Mitigations
- Implementation contracts undergo security audits
- Testing of implementations before registration
- Gradual rollout of new game types
Invariants
iDGF-001: Dispute game factory properly creates dispute games
The factory successfully creates functional dispute Game Clones when provided with valid parameters. Created games are properly initialized with the correct immutable arguments (creator, root claim, parent hash, extra data) and can be queried through the factory's lookup functions.
Impact
Severity: Critical
If this invariant is violated, the factory could create non-functional or incorrectly configured games, breaking the entire dispute resolution system and potentially allowing invalid withdrawals.
iDGF-002: Dispute game factory allows anyone to create dispute games
Any address can create a dispute game by calling the create function with valid parameters and the required Initialization Bond. There are no access restrictions on game creation beyond the bond requirement.
Impact
Severity: High
If this invariant is violated, the permissionless nature of the dispute system would be compromised, potentially preventing legitimate challengers from creating games to dispute invalid claims.
iDGF-003: Dispute game factory games are unique
For any given combination of game type, root claim, and extra data, at most one dispute game can be created. Once a game exists for a specific Game UUID, attempting to create another game with the same parameters will revert.
Impact
Severity: High
If this invariant is violated, multiple games could exist for the same dispute parameters, leading to ambiguity about which game result should be considered authoritative. This could enable attackers to create duplicate games and potentially exploit race conditions in systems that consume game results.
iDGF-004: Dispute game factory can create games for any game type
The factory can create games for any game type that has a registered implementation, regardless of the specific game type value. The factory does not restrict which game types can be used, only requiring that an implementation exists.
Impact
Severity: Medium
If this invariant is violated, the factory could arbitrarily restrict certain game types, limiting the flexibility of the dispute system and potentially preventing the deployment of new Game Implementations.
Function Specification
constructor
Initializes the contract in a disabled state to prevent implementation contract initialization.
Behavior:
- MUST disable initializers to prevent the implementation contract from being initialized
- MUST set the initial reinitializer version to 1
initialize
Initializes the proxy contract with an owner address.
Parameters:
_owner: The address that will own the contract and have permission to configure game types
Behavior:
- MUST revert if not called by ProxyAdmin or ProxyAdmin owner
- MUST initialize the Ownable functionality
- MUST transfer ownership to
_owner - MUST only be callable once per reinitializer version
gameCount
Returns the total number of dispute games created by this factory.
Behavior:
- MUST return the total number of games created
- MUST be a view function with no state changes
games
Queries for a dispute game by its parameters.
Parameters:
_gameType: The type of the dispute game_rootClaim: The root claim of the dispute game_extraData: Any extra data provided to the dispute game
Behavior:
- MUST compute the Game UUID from the provided parameters
- MUST return the game proxy address and creation timestamp if a game exists for the given parameters
- MUST return
address(0)and timestamp 0 if no game exists for the given parameters - MUST be a view function with no state changes
gameAtIndex
Returns the dispute game at a specific index in the creation order.
Parameters:
_index: The index of the dispute game in the creation list
Behavior:
- MUST revert if
_indexis greater than or equal to the total game count - MUST return the game type, creation timestamp, and proxy address for the game at the specified index
- MUST be a view function with no state changes
create
Creates a new dispute game proxy contract.
Parameters:
_gameType: The type of the dispute game to create_rootClaim: The root claim of the dispute game_extraData: Any extra data to provide to the created dispute game
Behavior:
- MUST revert if no implementation is registered for
_gameType - MUST revert if
msg.valuedoes not exactly equal the Initialization Bond for_gameType - MUST revert if a game with the same Game UUID already exists
- MUST clone the implementation contract using CWIA with immutable arguments: creator address, root claim, parent block hash, and extra data
- MUST include game type and implementation args in the clone if implementation args are configured for the game type
- MUST call initialize on the created clone, forwarding the sent ETH
- MUST make the game queryable by both its parameters and its creation index
- MUST increment the total game count
- MUST emit DisputeGameCreated event with the proxy address, game type, and root claim
- MUST return the address of the created game proxy
getGameUUID
Computes the unique identifier for a set of dispute game parameters.
Parameters:
_gameType: The type of the dispute game_rootClaim: The root claim of the dispute game_extraData: Any extra data for the dispute game
Behavior:
- MUST return
keccak256(abi.encode(_gameType, _rootClaim, _extraData)) - MUST be a pure function with no state access
findLatestGames
Searches for the most recent games of a specific type.
Parameters:
_gameType: The type of game to search for_start: The index to start the reverse search from_n: The maximum number of games to return
Behavior:
- MUST return an empty array if
_startis greater than or equal to the total game count - MUST return an empty array if
_nis zero - MUST perform a reverse linear search from
_starttowards index 0 - MUST include only games matching
_gameType - MUST return at most
_ngames - MUST return games in reverse chronological order (newest first)
- MUST include the index, metadata (GameId), timestamp, root claim, and extra data for each game
- MUST query the game proxy for root claim and extra data
- MUST be a view function with no state changes
setImplementation (without args)
Sets the implementation contract for a specific game type without implementation args.
Parameters:
_gameType: The type of the dispute game_impl: The implementation contract address
Behavior:
- MUST revert if not called by the owner
- MUST store
_implas the implementation for_gameType - MUST emit ImplementationSet event with the implementation address and game type
setImplementation (with args)
Sets the implementation contract and configuration args for a specific game type.
Parameters:
_gameType: The type of the dispute game_impl: The implementation contract address_args: The configuration arguments to pass during clone creation
Behavior:
- MUST revert if not called by the owner
- MUST store
_implas the implementation for_gameType - MUST store
_argsas the implementation args for_gameType - MUST emit ImplementationSet event with the implementation address and game type
- MUST emit ImplementationArgsSet event with the game type and args
setInitBond
Sets the Initialization Bond for a specific game type.
Parameters:
_gameType: The type of the dispute game_initBond: The bond amount in wei
Behavior:
- MUST revert if not called by the owner
- MUST store
_initBondas the Initialization Bond for_gameType - MUST emit InitBondUpdated event with the game type and new bond amount