Overview
A dispute game is played between multiple parties when contesting the truthiness of a claim. In the context of an optimistic rollup, claims are made about the state of the layer two network to enable withdrawals to the layer one. A proposer makes a claim about the layer two state such that they can withdraw and a challenger can dispute the validity of the claim. The security of the layer two comes from the ability of fraudulent withdrawals being able to be disputed. A dispute game interface is defined to allow for multiple implementations of dispute games to exist. If multiple dispute games run in production, it gives a similar security model as having multiple protocol clients, as a bug in a single dispute game will not result in the bug becoming consensus.Types
For added context, we define a few types that are used in the following snippets.DisputeGameFactory Interface
The dispute game factory is responsible for creating new DisputeGame contracts
given a GameType and a root Claim. Challenger agents listen to the DisputeGameCreated events in order to
keep up with on-going disputes in the protocol and participate accordingly.
A clones-with-immutable-args factory
(originally by @wighawag, but forked and improved by @Vectorized) is used to create Clones. Each GameType has
a corresponding implementation within the factory, and when a new game is created, the factory creates a
clone of the GameType’s pre-deployed implementation contract.
The rootClaim of created dispute games can either be a claim that the creator agrees or disagrees with.
This is an implementation detail that is left up to the IDisputeGame to handle within its resolve function.
When the DisputeGameFactory creates a new DisputeGame contract, it calls initialize() on the clone to
set up the game. The factory passes immutable arguments to the clone using the CWIA (Clone With Immutable Args)
pattern. There are two CWIA layouts depending on whether the game type has implementation args configured:
Standard CWIA Layout (when gameArgs[_gameType] is empty):
| Bytes | Description |
|---|---|
| [0, 20) | Game creator address |
| [20, 52) | Root claim |
| [52, 84) | Parent block hash at creation time |
| [84, 84 + n) | Extra data (opaque) |
gameArgs[_gameType] is non-empty):
| Bytes | Description |
|---|---|
| [0, 20) | Game creator address |
| [20, 52) | Root claim |
| [52, 84) | Parent block hash at creation time |
| [84, 88) | Game type |
| [88, 88 + n) | Extra data (opaque) |
| [88 + n, 88 + n + m) | Implementation args (opaque) |
DisputeGame Interface
The dispute game interface defines a generic, black-box dispute. It exposes stateful information such as the status of
the dispute, when it was created, as well as the bootstrap data and dispute type. This interface exposes one state
mutating function, resolve, which when implemented should deterministically yield an opinion about the rootClaim
and reflect the opinion by updating the status to CHALLENGER_WINS or DEFENDER_WINS.
Clones of the IDisputeGame’s initialize functions will be called by the DisputeGameFactory atomically upon
creation.