diff --git a/specs/fault-proof/stage-one/anchor-state-registry.md b/specs/fault-proof/stage-one/anchor-state-registry.md new file mode 100644 index 000000000..25e1106f5 --- /dev/null +++ b/specs/fault-proof/stage-one/anchor-state-registry.md @@ -0,0 +1,134 @@ +# Anchor State Registry + +## Overview (What this contract is actually supposed to do) + +This contract manages and communicates properties of dispute game validity to other contracts in order to facilitate withdrawals and future dispute games. + +- This contract is the source of truth for the validity of an **anchor state**. + - [FaultDisputeGame](fault-dispute-game.md) and PermissionedDisputeGame depend on this contract for a valid **anchor state** against which to resolve a claim. These contracts assume the state is valid. + - The valid anchor state needs to be recent enough so that the game doesn't break (run out of memory) in op-challenger. +- This contract is the source of truth for the validity of a particular fault dispute game result. + - This property is used by the [OptimismPortal](optimism-portal.md). The Portal asks two things of the Registry: + - Can this dispute game can be used to prove a withdrawal? + - Can this dispute game can be used to finalize a withdrawal? + +## Definitions + +- **Anchor state** + - See [Fault Dispute Game -> Anchor State](fault-dispute-game.md#anchor-state). +- **Authorized input** + - An input for which there is social consensus, i.e. coming from governance. +- **Invalid game** + - A dispute game is invalid if any of the following are true: + - Game was not created by the dispute game factory. + - Game was not created while it was the respected game type. + - Game is blacklisted. + - Game was created before the validity timestamp. + - Game status is `CHALLENGER_WINS`. +- **Finalized game** + - A dispute game is finalized if all of the following are true: + - Game status is `CHALLENGER_WINS` or `DEFENDER_WINS`. + - Game `resolvedAt` timestamp is not zero. + - Game `resolvedAt` timestamp is more than `dispute game finality seconds` seconds ago. +- **Valid game** + - A game is a **Valid game** if it is not an **Invalid game**, and is a **Finalized game**. +- **Latest valid game** + - The latest valid game is a **valid game** whose anchor state will be used to initialize new FaultDisputeGames and PermissionedDisputeGames. It represents the most recent valid representation of L2 state. + +## Top-Level Invariants + +- The Validity timestamp starts at zero. + +## Function-Level Invariants + +### `initialize` + +Initialize the thing somehow. + +- Initial anchor state is **authorized**. +- Need an **authorized** reference to the dispute game factory. +- Need **authorized** input for `dispute game finality seconds`. +- Need **authorized** reference to superchain config. + +### `getLatestValidGame` + +Get latest **valid game**. + +- Throws an error if the game is not valid. + - Depends on the condition that `update latest valid game` is the only method to update the “latest valid game” state variable and that it will only update the state variable with a **valid game**. Still, it is possible for the once valid game to become invalid. + +### Update latest **valid game** + +- Game must be **valid** +- Block number for latest valid game must be higher than current latest valid game +- This function is the ONLY way to update the latest valid game (after initialization) + +### Get latest valid root claim + +- Returns the root claim of the result of `get latest valid game` or an **authorized** anchor state if no such game exists + +### Get anchor state + +- Returns the root claim of the result of `get latest valid game` or an **authorized** anchor state if no such game exists +- Must maintain the property that the timestamp of the game is not too old + +### Register game result + +- Callable only by a game itself +- Game must not be invalid +- If game is not invalid, stores the address of the game in some array + +### Try update latest valid game based on previous game results + +- Callable by anyone +- Find the latest (comparing on l2BlockNumber) valid game you can find in the register within a fixed amount of gas +- Use this as input to `update latest valid game` +- Make sure this doesn’t get more expensive as time goes on + +### Is this game invalid? + +### Is this game finalized? + +### Is this game valid? + +- `return !isGameInvalid(game) && isGameFinalized(game)` +- Definition of **valid** is this condition passing + +### Set respected game type + +- Can only be set by + +### Update validity timestamp + +- Can only be set by +- Must be greater than previous validity timestamp +- Cannot be greater than current block timestamp + +### Blacklist game + +- Can only be set by + +--- + +- Definition of valid is NOT invalid AND finalized +- Airgap is a condition of finalization +- Therefore airgap is a condition of validity +- Games can be blacklisted after they are valid + +--- + +- Change respected game type +- Observe that change to respected game type is finalized +- Then change the validation timestamp +- Or just do both but make sure that respected game type change doesn’t get reorged to be after the timestamp change + +### Get dispute game finality delay + +- Returns **authorized** finality delay duration. + +# FaultDisputeGame + +- Only sets that special boolean if it actually is the respected game type +- And the boolean never changes after it’s been set +- Reports its game type correctly +- Reports its l2BlockNumber correctly diff --git a/specs/fault-proof/stage-one/bond-incentives.md b/specs/fault-proof/stage-one/bond-incentives.md index bb2a3f204..802bc1aae 100644 --- a/specs/fault-proof/stage-one/bond-incentives.md +++ b/specs/fault-proof/stage-one/bond-incentives.md @@ -2,22 +2,24 @@ + **Table of Contents** -- [Overview](#overview) -- [Moves](#moves) -- [Subgame Resolution](#subgame-resolution) - - [Leftmost Claim Incentives](#leftmost-claim-incentives) -- [Fault Proof Mainnet Incentives](#fault-proof-mainnet-incentives) - - [Authenticated Roles](#authenticated-roles) - - [Base Fee Assumption](#base-fee-assumption) - - [Bond Scaling](#bond-scaling) - - [Required Bond Formula](#required-bond-formula) - - [Other Incentives](#other-incentives) - - [DelayedWETH](#delayedweth) - - [Sub-Account Model](#sub-account-model) - - [Delay Period](#delay-period) - - [Integration](#integration) +- [Bond Incentives](#bond-incentives) + - [Overview](#overview) + - [Moves](#moves) + - [Subgame Resolution](#subgame-resolution) + - [Leftmost Claim Incentives](#leftmost-claim-incentives) + - [Fault Proof Mainnet Incentives](#fault-proof-mainnet-incentives) + - [Authenticated Roles](#authenticated-roles) + - [Base Fee Assumption](#base-fee-assumption) + - [Bond Scaling](#bond-scaling) + - [Required Bond Formula](#required-bond-formula) + - [Other Incentives](#other-incentives) + - [DelayedWETH](#delayedweth) + - [Sub-Account Model](#sub-account-model) + - [Delay Period](#delay-period) + - [Integration](#integration) @@ -76,9 +78,9 @@ proof system. ### Authenticated Roles -| Name | Description | -| ---- | ----------- | -| Guardian | Role responsible for blacklisting dispute game contracts and changing the respected dispute game type | +| Name | Description | +| ------------ | ----------------------------------------------------------------------------------------------------- | +| Guardian | Role responsible for blacklisting dispute game contracts and changing the respected dispute game type | | System Owner | Role that owns the `ProxyAdmin` contract that in turn owns most `Proxy` contracts within the OP Stack | ### Base Fee Assumption @@ -139,19 +141,18 @@ incorrectly distribute bonds. - `DelayedWETH` has an `owner()` address. We typically expect this to be set to the `System Owner` address. - `DelayedWETH` has a `delay()` function that returns a period of time that withdrawals will be delayed. - `DelayedWETH` has an `unlock(guy,wad)` function that modifies a mapping called `withdrawals` keyed as -`withdrawals[msg.sender][guy] => WithdrawalRequest` where `WithdrawalRequest` is -`struct Withdrawal Request { uint256 amount, uint256 timestamp }`. When `unlock` is called, the timestamp for -`withdrawals[msg.sender][guy]` is set to the current timestamp and the amount is increased by the given amount. -- `DelayedWETH` modifies the `WETH.withdraw` function such that an address *must* provide a "sub-account" to withdraw -from. The function signature becomes `withdraw(guy,wad)`. The function retrieves `withdrawals[msg.sender][guy]` and -checks that the current `block.timestamp` is greater than the timestamp on the withdrawal request plus the `delay()` -seconds and reverts if not. It also confirms that the amount being withdrawn is less than the amount in the withdrawal -request. Before completing the withdrawal, it reduces the amount contained within the withdrawal request. The original -`withdraw(wad)` function becomes an alias for `withdraw(msg.sender, wad)`. -`withdraw(guy,wad)` will not be callable when `SuperchainConfig.paused()` is `true`. + `withdrawals[msg.sender][guy] => WithdrawalRequest` where `WithdrawalRequest` is + `struct Withdrawal Request { uint256 amount, uint256 timestamp }`. When `unlock` is called, the timestamp for + `withdrawals[msg.sender][guy]` is set to the current timestamp and the amount is increased by the given amount. +- `DelayedWETH` modifies the `WETH.withdraw` function such that an address _must_ provide a "sub-account" to withdraw + from. The function signature becomes `withdraw(guy,wad)`. The function retrieves `withdrawals[msg.sender][guy]` and + checks that the current `block.timestamp` is greater than the timestamp on the withdrawal request plus the `delay()` + seconds and reverts if not. It also confirms that the amount being withdrawn is less than the amount in the withdrawal + request. Before completing the withdrawal, it reduces the amount contained within the withdrawal request. The original + `withdraw(wad)` function becomes an alias for `withdraw(msg.sender, wad)`. + `withdraw(guy,wad)` will not be callable when `SuperchainConfig.paused()` is `true`. - `DelayedWETH` has a `hold()` function that allows the `owner()` address to give itself an allowance from any address. -- `DelayedWETH` has a `recover()` function that allows the `owner()` address to recover any amount of ETH from the -contract. +- `DelayedWETH` has a `recover()` function that allows the `owner()` address to recover any amount of ETH from the contract. #### Sub-Account Model diff --git a/specs/fault-proof/stage-one/optimism-portal.md b/specs/fault-proof/stage-one/optimism-portal.md new file mode 100644 index 000000000..eeb2a38c2 --- /dev/null +++ b/specs/fault-proof/stage-one/optimism-portal.md @@ -0,0 +1,9 @@ +# Optimism Portal + +## Overview (What this contract is actually supposed to do) + +## Definitions + +## Top-Level Invariants + +## Function-Level Invariants