-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Proofs: AnchorStateRegistry, OptimismPortal incident response improvements #472
base: main
Are you sure you want to change the base?
Changes from all commits
e896799
5841241
13d66ab
42d3d5d
14e2aab
af03cb3
dd3b97c
624f4f2
c2b80ea
65e1987
7422c6f
d9502c9
85724f4
8d87959
22510a0
dd375de
315f39e
00eccf1
11b3b54
236036d
b6df996
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,398 @@ | ||
# Anchor State Registry | ||
|
||
<!-- START doctoc generated TOC please keep comment here to allow auto update --> | ||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
|
||
**Table of Contents** | ||
|
||
- [Anchor State Registry](#anchor-state-registry) | ||
- [Overview](#overview) | ||
- [Perspective](#perspective) | ||
- [Definitions](#definitions) | ||
- [Dispute game](#dispute-game) | ||
- [Maybe valid game](#maybe-valid-game) | ||
- [Dispute game finality delay](#dispute-game-finality-delay) | ||
- [Valid game](#valid-game) | ||
- [Blacklisted game](#blacklisted-game) | ||
- [Invalid game](#invalid-game) | ||
- [Retired game](#retired-game) | ||
- [Game retirement timestamp](#game-retirement-timestamp) | ||
- [Anchor state](#anchor-state) | ||
- [Anchor game](#anchor-game) | ||
- [Withdrawal](#withdrawal) | ||
- [Authorized input](#authorized-input) | ||
- [Assumptions](#assumptions) | ||
- [aFDG-001: Fault dispute games correctly report certain properties](#afdg-001-fault-dispute-games-correctly-report-certain-properties) | ||
- [Mitigations](#mitigations) | ||
- [aFDG-002: Fault dispute games with correct claims resolve correctly at some regular rate](#afdg-002-fault-dispute-games-with-correct-claims-resolve-correctly-at-some-regular-rate) | ||
- [Mitigations](#mitigations-1) | ||
- [aFDG-003: Fault dispute games are properly incentivized to resolve correctly](#afdg-003-fault-dispute-games-are-properly-incentivized-to-resolve-correctly) | ||
- [Mitigations](#mitigations-2) | ||
- [aDGF-001: Dispute game factory correctly identifies the games it created](#adgf-001-dispute-game-factory-correctly-identifies-the-games-it-created) | ||
- [Mitigations](#mitigations-3) | ||
- [aDGF-002: Games created by the DisputeGameFactory will be monitored](#adgf-002-games-created-by-the-disputegamefactory-will-be-monitored) | ||
- [Mitigations](#mitigations-4) | ||
- [aASR-001: Incorrectly resolving games will be invalidated within the dispute game finality delay period](#aasr-001-incorrectly-resolving-games-will-be-invalidated-within-the-dispute-game-finality-delay-period) | ||
- [Mitigations](#mitigations-5) | ||
- [aASR-002: The AnchorStateRegistry will be correctly initialized at deployment](#aasr-002-the-anchorstateregistry-will-be-correctly-initialized-at-deployment) | ||
- [Mitigations](#mitigations-6) | ||
- [aSC-001: SuperchainConfig correctly reports its guardian address](#asc-001-superchainconfig-correctly-reports-its-guardian-address) | ||
- [Mitigations](#mitigations-7) | ||
- [Component Invariants](#component-invariants) | ||
- [iASR-001: Only "truly" **valid games** will be represented as **valid games**](#iasr-001-only-truly-valid-games-will-be-represented-as-valid-games) | ||
- [Impact](#impact) | ||
- [Dependencies](#dependencies) | ||
- [iASR-002: The anchor state is recent, within some bounded time period](#iasr-002-the-anchor-state-is-recent-within-some-bounded-time-period) | ||
- [Impact](#impact-1) | ||
- [Dependencies](#dependencies-1) | ||
- [iASR-003: The anchor state is a correct L2 state root](#iasr-003-the-anchor-state-is-a-correct-l2-state-root) | ||
- [Impact](#impact-2) | ||
- [Dependencies](#dependencies-2) | ||
- [Function-Level Invariants](#function-level-invariants) | ||
- [Implementation Spec](#implementation-spec) | ||
- [`constructor`](#constructor) | ||
- [`initialize`](#initialize) | ||
- [`getRecentValidState`](#getrecentvalidstate) | ||
- [`updateAnchorState`](#updateanchorstate) | ||
- [~~`getAnchorState`~~ / `anchors`](#getanchorstate--anchors) | ||
- [`registerAnchorGameCandidate`](#registeranchorgamecandidate) | ||
- [`tryUpdateAnchorState`](#tryupdateanchorstate) | ||
- [`isGameBlacklisted`](#isgameblacklisted) | ||
- [`isGameRetired`](#isgameretired) | ||
- [`isGameMaybeValid`](#isgamemaybevalid) | ||
- [`isGameValid`](#isgamevalid) | ||
- [`setRespectedGameType`](#setrespectedgametype) | ||
- [`retireAllExistingGames`](#retireallexistinggames) | ||
- [`setGameBlacklisted`](#setgameblacklisted) | ||
- [`getGameFinalityDelay`](#getgamefinalitydelay) | ||
|
||
<!-- END doctoc generated TOC please keep comment here to allow auto update --> | ||
|
||
## Overview | ||
|
||
### Perspective | ||
|
||
The whole point of the fault proof system is to create correctly resolving games whose claims we can depend on to | ||
finalize withdrawals (or other L2-to-L1 dependents). Indeed, everything about the system, from the contract mechanics to | ||
bond incentives, is engineered to provide complete confidence that the outcome of a resolved game is correct. Yet, there | ||
are corner cases where the resolved game rebukes its platonic, game-theoretic ideal, resolving incorrectly. The anchor | ||
state registry appreciates this and affords games and their dependents probabalistic validity by enforcing a game | ||
finality delay, and adding additional dependencies like blacklisting and game retirement. These concessions improve the | ||
confidence in resolved games, and calcify the assumptions upon which withdrawals and other dependents rest. | ||
|
||
## Definitions | ||
|
||
### Dispute game | ||
|
||
> See [Fault Dispute Game](fault-dispute-game.md) | ||
|
||
A dispute game is a contract that resolves an L2 state claim. | ||
wildmolasses marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Maybe valid game | ||
|
||
A **maybe valid game** is a dispute game whose validity is questionable. However, the game does meet certain properties | ||
that make it a candidate for eventual **valid game** status, and can be useful to dependents in its limited state. A | ||
maybe valid game meets the following conditions: | ||
|
||
- Game was created by the dispute game factory. | ||
- Game is not **blacklisted**. | ||
- Game was created while it was the respected game type. | ||
- Game status is not `CHALLENGER_WINS`. | ||
wildmolasses marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Game `createdAt` timestamp is less than the **game retirement timestamp**. | ||
|
||
### Dispute game finality delay | ||
|
||
> Also known as "air gap." | ||
|
||
The dispute game finality delay is the period of time between a dispute game resolving and a dispute game becoming | ||
finalized. It's set via **authorized input**. | ||
|
||
### Valid game | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would just relist everything |
||
|
||
A game is a **valid game** if it, among other qualifications, has resolved in favor of the defender and has also matured | ||
past the finality delay. It meets the following conditions: | ||
|
||
- Game `resolvedAt` timestamp is not zero. | ||
- Game `resolvedAt` timestamp is more than `dispute game finality delay` seconds ago. | ||
- Game was created by the dispute game factory. | ||
- Game is not **blacklisted**. | ||
- Game was created while it was the respected game type. | ||
- Game status is not `CHALLENGER_WINS`. | ||
- Game `createdAt` timestamp is less than the **game retirement timestamp**. | ||
|
||
### Blacklisted game | ||
|
||
A **blacklisted game** is a game that has been set as blacklisted via **authorized action**. It must not be considered | ||
valid, and must not be used for finalizing withdrawals or any other dependent L2-to-L1 action. | ||
|
||
### Invalid game | ||
|
||
An **invalid game** is a game whose claim was false, or does not meet some other **maybe valid game** condition. | ||
|
||
### Retired game | ||
|
||
A **retired game** is a game whose `createdAt` timestamp is older than the **game retirement timestamp**. A game that | ||
gets retired is no longer considered valid. | ||
|
||
### Game retirement timestamp | ||
|
||
The game retirement timestamp determines **retired games** and can only be adjusted via **authorized input**. | ||
|
||
### Anchor state | ||
|
||
> See [Fault Dispute Game -> Anchor State](fault-dispute-game.md#anchor-state). | ||
|
||
An anchor state is the state root from a correct L2 claim that is used as a starting point for new dispute games. | ||
|
||
### Anchor game | ||
|
||
A game can be marked as the **"anchor game"** if that game is currently a **valid game** and corresponds to a claim | ||
about an L2 block number greater than the L2 block number of the current **anchor game**. A game remains the anchor game | ||
until replaced by another anchor game. An anchor game that becomes blacklisted is no longer considered a usable anchor | ||
game. An anchor game that becomes retired is still considered a usable anchor game. | ||
|
||
### Withdrawal | ||
|
||
> See [Withdrawals](../../protocol/withdrawals.md). | ||
|
||
A withdrawal is a cross-chain transaction initiated on L2, and finalized on L1. | ||
|
||
### Authorized input | ||
|
||
An authorized input is an input for which there is social consensus, i.e. coming from governance. | ||
|
||
## Assumptions | ||
|
||
> **NOTE:** Assumptions are utilized by specific invariants and do not apply globally. Invariants typically only rely on | ||
> a subset of the following assumptions. Different invariants may rely on different assumptions. Refer to individual | ||
> invariants for their dependencies. | ||
|
||
### aFDG-001: Fault dispute games correctly report certain properties | ||
|
||
We assume that a fault dispute game will correctly report the following properties: | ||
|
||
- its game type. | ||
- whether its game type was the respected game type when created (also assumes this is set once and never changes). | ||
- the l2BlockNumber of its root claim. | ||
- its `createdAt` timestamp. | ||
- its `resolvedAt` timestamp. | ||
|
||
#### Mitigations | ||
|
||
- Existing audit on `FaultDisputeGame`. Note: Existing audit does not yet cover the second property above (that a game | ||
correctly reports whether its game type was the respected game type when created). | ||
- Integration testing. | ||
wildmolasses marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### aFDG-002: Fault dispute games with correct claims resolve correctly at some regular rate | ||
wildmolasses marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
We assume that fault dispute games will regularly correctly resolve in favor of the defender. While the system can | ||
handle games that resolve in favor of the challenger, as well as incorrect resolutions, there must be other games that | ||
resolve correctly to maintain the system's integrity. | ||
|
||
#### Mitigations | ||
|
||
- Existing incentives in fault proof system design. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very open to suggestions on how to phrase these mitigations! |
||
|
||
### aFDG-003: Fault dispute games are properly incentivized to resolve correctly | ||
|
||
We assume that fault dispute games are properly incentivized to resolve correctly, implying that participants are | ||
incentivized to play the game correctly to its correct conclusion. | ||
|
||
#### Mitigations | ||
|
||
- Existing incentives in fault proof system design. | ||
|
||
### aDGF-001: Dispute game factory correctly identifies the games it created | ||
|
||
We assume that `DisputeGameFactory` will correctly identify whether it created a game (i.e. whether the game is | ||
"factory-registered"). | ||
|
||
#### Mitigations | ||
|
||
- Existing audit on the `DisputeGameFactory`. | ||
- Integration testing. | ||
|
||
### aDGF-002: Games created by the DisputeGameFactory will be monitored | ||
wildmolasses marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
We assume that games created by the `DisputeGameFactory` will be monitored for incorrect resolution. | ||
|
||
#### Mitigations | ||
|
||
- Stakeholder incentives. | ||
|
||
### aASR-001: Incorrectly resolving games will be invalidated within the dispute game finality delay period | ||
|
||
We assume that games that resolve incorrectly will be blacklisted or retired via **authorized action** within the | ||
dispute game finality delay period. This further depends on | ||
[aDGF-002](#adgf-002-games-created-by-the-disputegamefactory-will-be-monitored). | ||
|
||
#### Mitigations | ||
|
||
- Stakeholder incentives / processes. | ||
- Incident response plan. | ||
|
||
### aASR-002: The AnchorStateRegistry will be correctly initialized at deployment | ||
|
||
We assume that the AnchorStateRegistry will be correctly initialized at deployment, including: | ||
|
||
- Address of initial anchor game. | ||
- Address of `DisputeGameFactory`. | ||
- An appropriate `DISPUTE_GAME_FINALITY_DELAY`. | ||
- Address of `SuperchainConfig`. | ||
|
||
#### Mitigations | ||
|
||
- Verify the configured values in the deployment script. | ||
|
||
### aSC-001: SuperchainConfig correctly reports its guardian address | ||
|
||
We assume the SuperchainConfig contract correctly returns its guardian address. | ||
|
||
#### Mitigations | ||
|
||
- Existing audit on the `SuperchainConfig`. | ||
- Integration testing. | ||
|
||
## Component Invariants | ||
|
||
### iASR-001: Only "truly" **valid games** will be represented as **valid games** | ||
|
||
When asked for a **valid game** by its dependents, the AnchorStateRegistry will only serve **valid games** representing | ||
correct L2 state claims. | ||
|
||
#### Impact | ||
|
||
**Severity: Critical** | ||
|
||
If this invariant is broken, the L1 will have an inaccurate view of L2 state. The `OptimismPortal` can be tricked into | ||
finalizing withdrawals based on incorrect state roots, causing loss of funds. Other dependents will also be affected. | ||
|
||
#### Dependencies | ||
smartcontracts marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- [aFDG-001](#afdg-001-fault-dispute-games-correctly-report-certain-properties) | ||
- [aDGF-002](#adgf-002-games-created-by-the-disputegamefactory-will-be-monitored) | ||
- [aASR-001](#aasr-001-incorrectly-resolving-games-will-be-invalidated-within-the-dispute-game-finality-delay-period) | ||
- [aASR-002](#aasr-002-the-anchorstateregistry-will-be-correctly-initialized-at-deployment) | ||
- [aSC-001](#asc-001-superchainconfig-correctly-reports-its-guardian-address) | ||
|
||
### iASR-002: The anchor state is recent, within some bounded time period | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note to self: understand how long this period is |
||
|
||
When asked for the **anchor state** by fault dispute games, the contract will only serve an **anchor state** whose L2 | ||
block timestamp is recent, within some bounded period of time. | ||
|
||
#### Impact | ||
|
||
**Severity: High** | ||
|
||
If this invariant is broken, proposer software can break (run out of memory), leading to dispute game liveness issues | ||
and incorrect game resolution. | ||
|
||
#### Dependencies | ||
|
||
- [aASR-002](#aasr-002-the-anchorstateregistry-will-be-correctly-initialized-at-deployment) | ||
- [aFDG-002](#afdg-002-fault-dispute-games-with-correct-claims-resolve-correctly-at-some-regular-rate) | ||
|
||
### iASR-003: The anchor state is a correct L2 state root | ||
|
||
When asked for the **anchor state** by fault dispute games, the contract will serve an **anchor state** that's correct, | ||
i.e. in agreement with a flawless L2 state oracle. | ||
|
||
#### Impact | ||
|
||
**Severity: High** | ||
|
||
If this invariant is broken, dispute games can be created with incorrect starting points, leading to games that can be | ||
used to prove false claims. This would lead to an operational failure, requiring incident response. If incident response | ||
doesn't occur, this could lead to loss of funds. | ||
|
||
#### Dependencies | ||
|
||
- TODO | ||
|
||
## Function-Level Invariants | ||
|
||
## Implementation Spec | ||
|
||
### `constructor` | ||
|
||
The constructor must disable the initializer on the implementation contract. | ||
|
||
### `initialize` | ||
|
||
- Initial anchor state must be an **authorized input**. | ||
- Dispute game factory must be an **authorized input**. | ||
- `dispute game finality delay` must be an **authorized input**. | ||
- Superchain config must be an **authorized input**. | ||
|
||
### `getRecentValidState` | ||
|
||
Returns the state of the **anchor game**. Reverts if the **anchor game** has been **retired**. | ||
|
||
### `updateAnchorState` | ||
|
||
- Game must be a **valid game**. | ||
- Game's block number must be higher than current **anchor state**'s block number. | ||
- This function is the ONLY way to update the **anchor state** (after initialization). | ||
|
||
### ~~`getAnchorState`~~ / `anchors` | ||
|
||
Returns the **anchor state** of the **anchor game**. | ||
|
||
- Must revert if the **anchor game** is a **blacklisted game**. | ||
- Must maintain the property that the timestamp of the game is not too old. | ||
- TODO: How old is too old? | ||
|
||
### `registerAnchorGameCandidate` | ||
|
||
Register a **maybe valid game** as a candidate for **anchor game**. | ||
|
||
- Callable only by a **maybe valid game**. | ||
- Calling game must only register itself (and not some other game). | ||
- TODO: determine any invariants around registry ordering. | ||
|
||
### `tryUpdateAnchorState` | ||
|
||
Try to update the **anchor state** using registry of **maybe valid games**. | ||
|
||
- Callable by anyone. | ||
- Find the most recent (comparing on l2BlockNumber) valid game you can find in the register within a fixed amount of | ||
gas. | ||
- Fixed gas amount ensures that this function does not get more expensive to call as time goes on. | ||
- Use this as input to `updateAnchorGame`. | ||
|
||
### `isGameBlacklisted` | ||
|
||
Returns whether the game is a **blacklisted game**. | ||
|
||
### `isGameRetired` | ||
|
||
Returns whether the game is a **retired game**. | ||
|
||
### `isGameMaybeValid` | ||
|
||
Returns whether the game is a **maybe valid game**. | ||
|
||
### `isGameValid` | ||
|
||
Returns whether the game is a **valid game**. | ||
|
||
### `setRespectedGameType` | ||
|
||
- Must be **authorized** by guardian role. | ||
|
||
### `retireAllExistingGames` | ||
|
||
Retires all currently deployed games. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there's an implication in the scenario here that i'd like to double check on:
are we ok with an anchor game being days old? in the above scenario, if games get retired a second time before another game became valid, the anchor state could be up to |
||
|
||
- Must set the **game retirement timestamp** to the current block timestamp. | ||
- Must be **authorized** by guardian role. | ||
|
||
### `setGameBlacklisted` | ||
|
||
Blacklists a game. | ||
|
||
- Must be **authorized** by guardian role. | ||
|
||
### `getGameFinalityDelay` | ||
|
||
Returns **authorized** finality delay duration in seconds. No external dependents; public getter for convenience. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this section articulate the motivations correctly? is it missing anything?