diff --git a/specs/SUMMARY.md b/specs/SUMMARY.md
index fff23e9b2..b8547733b 100644
--- a/specs/SUMMARY.md
+++ b/specs/SUMMARY.md
@@ -54,7 +54,7 @@
- [Derivation](./protocol/holocene/derivation.md)
- [Execution Engine](./protocol/holocene/exec-engine.md)
- [Predeploys](./protocol/holocene/predeploys.md)
- - [Configurability](./protocol/holocene/configurability.md)
+ - [System Config](./protocol/holocene/system-config.md)
- [Governance]()
- [Governance Token](./governance/gov-token.md)
- [Experimental]()
diff --git a/specs/experimental/op-contracts-manager.md b/specs/experimental/op-contracts-manager.md
index fa80e67ba..405eebb8d 100644
--- a/specs/experimental/op-contracts-manager.md
+++ b/specs/experimental/op-contracts-manager.md
@@ -45,7 +45,7 @@ TODO.
## Interface
-Version 1.0.0 of the OP Contracts Manager deploys the [`op-contracts/v1.6.0`]
+Version 1.0.0 of the OP Contracts Manager deploys the `op-contracts/v1.6.0`
contracts release.
### `Proxy.sol`
diff --git a/specs/protocol/configurability.md b/specs/protocol/configurability.md
index 4101c2174..4754c956d 100644
--- a/specs/protocol/configurability.md
+++ b/specs/protocol/configurability.md
@@ -130,7 +130,7 @@ to finalize withdrawals.
**Requirement:** [`CANNON` (
`0`)](https://github.com/ethereum-optimism/optimism/blob/op-contracts/v1.5.0/packages/contracts-bedrock/src/dispute/lib/Types.sol#L28)
**Notes:** The game type may be changed to [`PERMISSIONED_CANNON` (
-`1`)](https://github.com/ethereum-optimism/optimism/blob/op-contracts/v1.5.0/packages/contracts-bedrock/src/dispute/lib/Types.sol#L31)
+`1`)]()
as a fallback to permissioned proposals, in the event of a failure in the Fault Proof system.
### Fault Game Max Depth
diff --git a/specs/protocol/holocene/exec-engine.md b/specs/protocol/holocene/exec-engine.md
index c745deb65..df7a4eb9b 100644
--- a/specs/protocol/holocene/exec-engine.md
+++ b/specs/protocol/holocene/exec-engine.md
@@ -4,82 +4,33 @@
**Table of Contents**
+- [Overview](#overview)
- [Timestamp Activation](#timestamp-activation)
-- [`L2ToL1MessagePasser` Storage Root in Header](#l2tol1messagepasser-storage-root-in-header)
- - [Header Validity Rules](#header-validity-rules)
- - [Header Withdrawals Root](#header-withdrawals-root)
- - [Rationale](#rationale)
- - [Forwards Compatibility Considerations](#forwards-compatibility-considerations)
- - [Client Implementation Considerations](#client-implementation-considerations)
-- [Extended `PayloadAttributesV3`](#extended-payloadattributesv3)
- - [`eip1559Params` encoding](#eip1559params-encoding)
+- [Dynamic EIP-1559 Parameters](#dynamic-eip-1559-parameters)
+ - [Extended `PayloadAttributesV3`](#extended-payloadattributesv3)
+ - [`eip1559Params` encoding](#eip1559params-encoding)
- [Execution](#execution)
- - [Rationale](#rationale-1)
-- [`eip1559Params` in Header](#eip1559params-in-header)
- - [Header Validity Rules](#header-validity-rules-1)
- - [Encoding](#encoding)
- - [Rationale](#rationale-2)
+ - [Rationale](#rationale)
+ - [`eip1559Params` in Header](#eip1559params-in-header)
+ - [Header Validity Rules](#header-validity-rules)
+ - [Encoding](#encoding)
+ - [Rationale](#rationale-1)
+## Overview
+
+The EIP-1559 parameters are encoded in the block header's `nonce` field and can be
+configured dynamically through the `SystemConfig`.
+
## Timestamp Activation
Holocene, like other network upgrades, is activated at a timestamp.
Changes to the L2 Block execution rules are applied when the `L2 Timestamp >= activation time`.
-## `L2ToL1MessagePasser` Storage Root in Header
-
-After Holocene's activation, the L2 block header's `withdrawalsRoot` field will consist of the 32-byte
-[`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root _after_ the block has been executed, and _after_ the
-insertions and deletions have been applied to the trie. In other words, the storage root should be the same root
-that is returned by `eth_getProof` at the given block number.
-
-### Header Validity Rules
-
-Prior to holocene activation, the L2 block header's `withdrawalsRoot` field must be:
-
-- `nil` if Canyon has not been activated.
-- `keccak256(rlp(empty_string_code))` if Canyon has been activated.
+## Dynamic EIP-1559 Parameters
-After Holocene activation, an L2 block header's `withdrawalsRoot` field is valid iff:
-
-1. It is exactly 32 bytes in length.
-1. The [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root, as committed to in the `storageRoot` within the block
- header, is equal to the header's `withdrawalsRoot` field.
-
-### Header Withdrawals Root
-
-| Byte offset | Description |
-| ----------- | --------------------------------------------------------- |
-| `[0, 32)` | [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root |
-
-#### Rationale
-
-Currently, to generate [L2 output roots][output-root] for historical blocks, an archival node is required. This directly
-places a burden on users of the system in a post-fault-proofs world, where:
-
-1. A proposer must have an archive node to propose an output root at the safe head.
-1. A user that is proving their withdrawal must have an archive node to verify that the output root they are proving
- their withdrawal against is indeed valid and included within the safe chain.
-
-Placing the [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root in the `withdrawalsRoot` field alleviates this burden
-for users and protocol participants alike, allowing them to propose and verify other proposals with lower operating costs.
-
-#### Forwards Compatibility Considerations
-
-As it stands, the `withdrawalsRoot` field is unused within the OP Stack's header consensus format, and will never be
-used for other reasons that are currently planned. Setting this value to the account storage root of the withdrawal
-directly fits with the OP Stack, and makes use of the existing field in the L1 header consensus format.
-
-#### Client Implementation Considerations
-
-Varous EL clients store historical state of accounts differently. If, as a contrived case, an OP Stack chain did not have
-an outbound withdrawal for a long period of time, the node may not have access to the account storage root of the
-[`L2ToL1MessagePasser`][l2-to-l1-mp]. In this case, the client would be unable to keep consensus. However, most modern
-clients are able to at the very least reconstruct the account storage root at a given block on the fly if it does not
-directly store this information.
-
-## Extended `PayloadAttributesV3`
+### Extended `PayloadAttributesV3`
The [`PayloadAttributesV3`](https://github.com/ethereum/execution-apis/blob/cea7eeb642052f4c2e03449dc48296def4aafc24/src/engine/cancun.md#payloadattributesv3)
type is extended to:
@@ -98,7 +49,7 @@ PayloadAttributesV3: {
}
```
-### `eip1559Params` encoding
+#### `eip1559Params` encoding
| Name | Type | Byte Offset |
| ------------- | ------------------ | ----------- |
@@ -124,21 +75,21 @@ parameters of the chain. As described in the [derivation - AttributesBuilder](./
section, the derivation pipeline must populate this field from the `SystemConfig` during payload building, similar to
how it must reference the `SystemConfig` for the `gasLimit` field.
-## `eip1559Params` in Header
+### `eip1559Params` in Header
Upon Holocene activation, the L2 block header's `nonce` field will consist of the 8-byte `eip1559Params` value.
-### Header Validity Rules
+#### Header Validity Rules
Prior to Holocene activation, the L2 block header's `nonce` field is valid iff it is equal to `u64(0)`.
After Holocene activation, The L2 block header's `nonce` field is valid iff it is non-zero.
-### Encoding
+#### Encoding
The encoding of the `eip1559Params` value is described in [`eip1559Params` encoding](#eip1559params-encoding).
-### Rationale
+#### Rationale
By chosing to put the `eip1559Params` in the `PayloadAttributes` rather than in the L1 block info transaction,
the EIP-1559 parameters for the chain are not available within history. This would place a burden on performing
diff --git a/specs/protocol/holocene/overview.md b/specs/protocol/holocene/overview.md
index 095b2a1db..b29019e67 100644
--- a/specs/protocol/holocene/overview.md
+++ b/specs/protocol/holocene/overview.md
@@ -10,11 +10,9 @@
-This document is not finalized and should be considered experimental.
-
## Execution Layer
-- [L2ToL1MessagePasser Storage Root in Header](./exec-engine.md##l2tol1messagepasser-storage-root-in-header)
+- [Dynamic EIP-1559 Parameters](./exec-engine.md#dynamic-eip-1559-parameters)
## Consensus Layer
@@ -22,5 +20,4 @@ This document is not finalized and should be considered experimental.
## Smart Contracts
-- [Predeploys](./predeploys.md)
-- [Configurability](./configurability.md)
+- [System Config](./system-config.md)
diff --git a/specs/protocol/holocene/system-config.md b/specs/protocol/holocene/system-config.md
new file mode 100644
index 000000000..c94105621
--- /dev/null
+++ b/specs/protocol/holocene/system-config.md
@@ -0,0 +1,80 @@
+# System Config
+
+
+
+**Table of Contents**
+
+- [Overview](#overview)
+ - [`ConfigUpdate`](#configupdate)
+ - [Initialization](#initialization)
+ - [Modifying EIP-1559 Parameters](#modifying-eip-1559-parameters)
+ - [Interface](#interface)
+ - [EIP-1559 Params](#eip-1559-params)
+ - [`setEIP1559Params`](#seteip1559params)
+ - [`eip1559Elasticity`](#eip1559elasticity)
+ - [`eip1559Denominator`](#eip1559denominator)
+
+
+
+## Overview
+
+The `SystemConfig` is updated to allow for dynamic EIP-1559 parameters.
+
+### `ConfigUpdate`
+
+The following `ConfigUpdate` event is defined where the `CONFIG_VERSION` is `uint256(0)`:
+
+| Name | Value | Definition | Usage |
+| ---- | ----- | --- | -- |
+| `BATCHER` | `uint8(0)` | `abi.encode(address)` | Modifies the account that is authorized to progress the safe chain |
+| `FEE_SCALARS` | `uint8(1)` | `(uint256(0x01) << 248) \| (uint256(_blobbasefeeScalar) << 32) \| _basefeeScalar` | Modifies the fee scalars |
+| `GAS_LIMIT` | `uint8(2)` | `abi.encode(uint64 _gasLimit)` | Modifies the L2 gas limit |
+| `UNSAFE_BLOCK_SIGNER` | `uint8(3)` | `abi.encode(address)` | Modifies the account that is authorized to progress the unsafe chain |
+| `EIP_1559_PARAMS` | `uint8(4)` | `uint256(uint64(uint32(_denominator))) << 32 \| uint64(uint32(_elasticity))` | Modifies the EIP-1559 denominator and elasticity |
+
+### Initialization
+
+The following actions should happen during the initialization of the `SystemConfig`:
+
+- `emit ConfigUpdate.BATCHER`
+- `emit ConfigUpdate.FEE_SCALARS`
+- `emit ConfigUpdate.GAS_LIMIT`
+- `emit ConfigUpdate.UNSAFE_BLOCK_SIGNER`
+- `emit ConfigUpdate.EIP_1559_PARAMS`
+
+### Modifying EIP-1559 Parameters
+
+A new `SystemConfig` `UpdateType` is introduced that enables the modification of
+[EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) parameters. This allows for the chain
+operator to modify the `BASE_FEE_MAX_CHANGE_DENOMINATOR` and the `ELASTICITY_MULTIPLIER`.
+
+### Interface
+
+#### EIP-1559 Params
+
+##### `setEIP1559Params`
+
+This function MUST only be callable by the chain governor.
+
+```solidity
+function setEIP1559Params(uint32 _denominator, uint32 _elasticity)
+```
+
+The `_denominator` and `_elasticity` MUST be set to values greater to than 0.
+It is possible for the chain operator to set EIP-1559 parameters that result in poor user experience.
+
+##### `eip1559Elasticity`
+
+This function returns the currently configured EIP-1559 elasticity.
+
+```solidity
+function eip1559Elasticity()(uint64)
+```
+
+##### `eip1559Denominator`
+
+This function returns the currently configured EIP-1559 denominator.
+
+```solidity
+function eip1559Denominator()(uint64)
+```
diff --git a/specs/protocol/holocene/configurability.md b/specs/protocol/isthmus/configurability.md
similarity index 80%
rename from specs/protocol/holocene/configurability.md
rename to specs/protocol/isthmus/configurability.md
index 3f42ccbe2..7c2792e58 100644
--- a/specs/protocol/holocene/configurability.md
+++ b/specs/protocol/isthmus/configurability.md
@@ -10,12 +10,7 @@
- [`SystemConfig`](#systemconfig)
- [`ConfigUpdate`](#configupdate)
- [Initialization](#initialization)
- - [Modifying EIP-1559 Parameters](#modifying-eip-1559-parameters)
- [Interface](#interface)
- - [EIP-1559 Params](#eip-1559-params)
- - [`setEIP1559Params`](#seteip1559params)
- - [`eip1559Elasticity`](#eip1559elasticity)
- - [`eip1559Denominator`](#eip1559denominator)
- [Fee Vault Config](#fee-vault-config)
- [`setBaseFeeVaultConfig`](#setbasefeevaultconfig)
- [`setL1FeeVaultConfig`](#setl1feevaultconfig)
@@ -23,6 +18,7 @@
- [`OptimismPortal`](#optimismportal)
- [Interface](#interface-1)
- [`setConfig`](#setconfig)
+ - [`upgrade`](#upgrade)
@@ -82,43 +78,8 @@ The following actions should happen during the initialization of the `SystemConf
These actions MAY only be triggered if there is a diff to the value.
-### Modifying EIP-1559 Parameters
-
-A new `SystemConfig` `UpdateType` is introduced that enables the modification of
-[EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) parameters. This allows for the chain
-operator to modify the `BASE_FEE_MAX_CHANGE_DENOMINATOR` and the `ELASTICITY_MULTIPLIER`.
-
### Interface
-#### EIP-1559 Params
-
-##### `setEIP1559Params`
-
-This function MUST only be callable by the chain governor.
-
-```solidity
-function setEIP1559Params(uint32 _denominator, uint32 _elasticity)
-```
-
-The `_denominator` and `_elasticity` MUST be set to values greater to than 0.
-It is possible for the chain operator to set EIP-1559 parameters that result in poor user experience.
-
-##### `eip1559Elasticity`
-
-This function returns the currently configured EIP-1559 elasticity.
-
-```solidity
-function eip1559Elasticity()(uint64)
-```
-
-##### `eip1559Denominator`
-
-This function returns the currently configured EIP-1559 denominator.
-
-```solidity
-function eip1559Denominator()(uint64)
-```
-
#### Fee Vault Config
For each `FeeVault`, there is a setter for its config. The arguments to the setter include
@@ -173,3 +134,26 @@ The following fields are included:
- `version` is `uint256(0)`
- `opaqueData` is the tightly packed transaction data where `mint` is `0`, `value` is `0`, the `gasLimit`
is `200_000`, `isCreation` is `false` and the `data` is `abi.encodeCall(L1Block.setConfig, (_type, _value))`
+
+#### `upgrade`
+
+The `upgrade` function MUST only be callable by the `UPGRADER` role as defined
+in the [`SuperchainConfig`](./superchain-config.md).
+
+```solidity
+function upgrade(bytes memory _data) external
+```
+
+This function emits a `TransactionDeposited` event.
+
+```solidity
+event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData);
+```
+
+The following fields are included:
+
+- `from` is the `DEPOSITOR_ACCOUNT`
+- `to` is `Predeploys.ProxyAdmin`
+- `version` is `uint256(0)`
+- `opaqueData` is the tightly packed transaction data where `mint` is `0`, `value` is `0`, the `gasLimit`
+ is `200_000`, `isCreation` is `false` and the `data` is the data passed into `upgrade`.
diff --git a/specs/protocol/isthmus/exec-engine.md b/specs/protocol/isthmus/exec-engine.md
new file mode 100644
index 000000000..dc4df4752
--- /dev/null
+++ b/specs/protocol/isthmus/exec-engine.md
@@ -0,0 +1,78 @@
+# L2 Execution Engine
+
+
+
+**Table of Contents**
+
+- [Overview](#overview)
+- [Timestamp Activation](#timestamp-activation)
+- [`L2ToL1MessagePasser` Storage Root in Header](#l2tol1messagepasser-storage-root-in-header)
+ - [Header Validity Rules](#header-validity-rules)
+ - [Header Withdrawals Root](#header-withdrawals-root)
+ - [Rationale](#rationale)
+ - [Forwards Compatibility Considerations](#forwards-compatibility-considerations)
+ - [Client Implementation Considerations](#client-implementation-considerations)
+
+
+
+## Overview
+
+The storage root of the `L2ToL1MessagePasser` is included in the block header's
+`withdrawalRoot` field.
+
+## Timestamp Activation
+
+Isthmus, like other network upgrades, is activated at a timestamp.
+Changes to the L2 Block execution rules are applied when the `L2 Timestamp >= activation time`.
+
+## `L2ToL1MessagePasser` Storage Root in Header
+
+After Holocene's activation, the L2 block header's `withdrawalsRoot` field will consist of the 32-byte
+[`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root _after_ the block has been executed, and _after_ the
+insertions and deletions have been applied to the trie. In other words, the storage root should be the same root
+that is returned by `eth_getProof` at the given block number.
+
+### Header Validity Rules
+
+Prior to holocene activation, the L2 block header's `withdrawalsRoot` field must be:
+
+- `nil` if Canyon has not been activated.
+- `keccak256(rlp(empty_string_code))` if Canyon has been activated.
+
+After Holocene activation, an L2 block header's `withdrawalsRoot` field is valid iff:
+
+1. It is exactly 32 bytes in length.
+1. The [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root, as committed to in the `storageRoot` within the block
+ header, is equal to the header's `withdrawalsRoot` field.
+
+### Header Withdrawals Root
+
+| Byte offset | Description |
+| ----------- | --------------------------------------------------------- |
+| `[0, 32)` | [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root |
+
+#### Rationale
+
+Currently, to generate [L2 output roots][output-root] for historical blocks, an archival node is required. This directly
+places a burden on users of the system in a post-fault-proofs world, where:
+
+1. A proposer must have an archive node to propose an output root at the safe head.
+1. A user that is proving their withdrawal must have an archive node to verify that the output root they are proving
+ their withdrawal against is indeed valid and included within the safe chain.
+
+Placing the [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root in the `withdrawalsRoot` field alleviates this burden
+for users and protocol participants alike, allowing them to propose and verify other proposals with lower operating costs.
+
+#### Forwards Compatibility Considerations
+
+As it stands, the `withdrawalsRoot` field is unused within the OP Stack's header consensus format, and will never be
+used for other reasons that are currently planned. Setting this value to the account storage root of the withdrawal
+directly fits with the OP Stack, and makes use of the existing field in the L1 header consensus format.
+
+#### Client Implementation Considerations
+
+Varous EL clients store historical state of accounts differently. If, as a contrived case, an OP Stack chain did not have
+an outbound withdrawal for a long period of time, the node may not have access to the account storage root of the
+[`L2ToL1MessagePasser`][l2-to-l1-mp]. In this case, the client would be unable to keep consensus. However, most modern
+clients are able to at the very least reconstruct the account storage root at a given block on the fly if it does not
+directly store this information.
diff --git a/specs/protocol/isthmus/overview.md b/specs/protocol/isthmus/overview.md
index ec7bf0827..90c286eb2 100644
--- a/specs/protocol/isthmus/overview.md
+++ b/specs/protocol/isthmus/overview.md
@@ -6,6 +6,7 @@
- [Execution Layer](#execution-layer)
- [Consensus Layer](#consensus-layer)
+- [Smart Contracts](#smart-contracts)
@@ -13,6 +14,10 @@ This document is not finalized and should be considered experimental.
## Execution Layer
+- [L2ToL1MessagePasser Storage Root in Header](./exec-engine.md##l2tol1messagepasser-storage-root-in-header)
+
## Consensus Layer
-- [Interop](../../interop/overview.md)
+## Smart Contracts
+
+- [SuperchainConfig](./superchain-config.md)
diff --git a/specs/protocol/holocene/predeploys.md b/specs/protocol/isthmus/predeploys.md
similarity index 91%
rename from specs/protocol/holocene/predeploys.md
rename to specs/protocol/isthmus/predeploys.md
index 9b874510f..a6e50868f 100644
--- a/specs/protocol/holocene/predeploys.md
+++ b/specs/protocol/isthmus/predeploys.md
@@ -6,10 +6,12 @@
- [Constants](#constants)
- [Predeploys](#predeploys)
+ - [ProxyAdmin](#proxyadmin)
+ - [Rationale](#rationale)
- [L1Block](#l1block)
- [Storage](#storage)
- [Interface](#interface)
- - [`setHolocene`](#setholocene)
+ - [`setIsthmus`](#setisthmus)
- [`setConfig`](#setconfig)
- [`baseFeeVaultConfig`](#basefeevaultconfig)
- [`sequencerFeeVaultConfig`](#sequencerfeevaultconfig)
@@ -79,6 +81,20 @@ graph LR
OptimismPortal -- "setConfig(uint8,bytes)" --> L1Block
```
+### ProxyAdmin
+
+The `ProxyAdmin` is updated to have its `owner` be the `DEPOSITOR_ACCOUNT`.
+This means that it can be deterministically called by network upgrade transactions
+or by special deposit transactions emitted by the `OptimismPortal` that assume
+the identity of the `DEPOSITOR_ACCOUNT`.
+
+#### Rationale
+
+It is much easier to manage the overall roles of the full system under this model.
+The owner of the `ProxyAdmin` can upgrade any of the predeploys, meaning it can
+write storage slots that correspond to withdrawals. This ensures that only the
+system or a chain governor can issue upgrades to the predeploys.
+
### L1Block
#### Storage
@@ -98,7 +114,7 @@ via a deposit transaction from the `DEPOSITOR_ACCOUNT`.
#### Interface
-##### `setHolocene`
+##### `setIsthmus`
This function is meant to be called once on the activation block of the holocene network upgrade.
It MUST only be callable by the `DEPOSITOR_ACCOUNT` once. When it is called, it MUST call
diff --git a/specs/protocol/isthmus/superchain-config.md b/specs/protocol/isthmus/superchain-config.md
new file mode 100644
index 000000000..355614c6a
--- /dev/null
+++ b/specs/protocol/isthmus/superchain-config.md
@@ -0,0 +1,34 @@
+# SuperchainConfig
+
+
+
+**Table of Contents**
+
+- [Overview](#overview)
+- [Constants](#constants)
+- [Interface](#interface)
+- [Initialization](#initialization)
+
+
+
+## Overview
+
+The `SuperchainConfig` contract is updated with a new role that has the ability
+to issue deposit transactions from the identity of the `DEPOSITOR_ACCOUNT`
+that call the L2 `ProxyAdmin`.
+
+## Constants
+
+| Name | Value | Definition |
+| --------- | ------------------------- | -- |
+| `UPGRADER_SLOT` | `bytes32(uint256(keccak256("superchainConfig.upgrader")) - 1)` | Account that can call the L2 `ProxyAdmin` |
+
+## Interface
+
+```solidity
+function upgrader() public view returns (address)
+```
+
+## Initialization
+
+The `upgrader` can only be set during initialization.