Skip to content
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

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
398 changes: 398 additions & 0 deletions specs/fault-proof/stage-one/anchor-state-registry.md
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.
Copy link
Collaborator Author

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?


## 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
Copy link
Contributor

Choose a reason for hiding this comment

The 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.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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
Copy link
Contributor

Choose a reason for hiding this comment

The 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.
Copy link
Collaborator Author

@wildmolasses wildmolasses Dec 12, 2024

Choose a reason for hiding this comment

The 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:

  • all games are retired
  • getAnchorGame returns a game that's retired.
  • all games will be using the retired anchor game for their root until another game resolves and waits the finality duration
  • that means the anchor game won't update for at least min(game resolution time) + finality duration delay

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 2 * (min(game resolution time) + finality duration delay) seconds old. when does this become a problem?


- 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.
Loading