diff --git a/specs/SUMMARY.md b/specs/SUMMARY.md
index f0b72b517..5f147d008 100644
--- a/specs/SUMMARY.md
+++ b/specs/SUMMARY.md
@@ -56,6 +56,8 @@
- [Predeploys](./protocol/holocene/predeploys.md)
- [L1 Block Attributes](./protocol/holocene/l1-attributes.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 70196652a..fa80e67ba 100644
--- a/specs/experimental/op-contracts-manager.md
+++ b/specs/experimental/op-contracts-manager.md
@@ -1,6 +1,5 @@
# OP Contracts Manager
-[`op-contracts/v1.4.0`]: https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.6.0
[Optimism Monorepo releases]: https://github.com/ethereum-optimism/optimism/releases
[contract releases]: https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/VERSIONING.md
[standard configuration]: ../protocol/configurability.md
diff --git a/specs/protocol/configurability.md b/specs/protocol/configurability.md
index 6e6ba8792..4101c2174 100644
--- a/specs/protocol/configurability.md
+++ b/specs/protocol/configurability.md
@@ -408,8 +408,8 @@ existing [permissioned dispute games](../fault-proof/stage-one/bridge-integratio
[^of-gnosis-safe-l1]
**Notes:** Optimism Foundation (OF) multisig
leveraging [battle-tested software](https://github.com/safe-global/safe-smart-account). This role is only active when
-the `OptimismPortal` respected game type is [
-`PERMISSIONED_CANNON`](https://github.com/ethereum-optimism/optimism/blob/op-contracts/v1.5.0/packages/contracts-bedrock/src/dispute/lib/Types.sol#L31).
+the `OptimismPortal` respected game type is [`PERMISSIONED_CANNON`]
+().
### [Guardian address](https://github.com/ethereum-optimism/optimism/blob/c927ed9e8af501fd330349607a2b09a876a9a1fb/packages/contracts-bedrock/src/L1/SuperchainConfig.sol#L50)
@@ -429,8 +429,8 @@ with [permissioned dispute games](../fault-proof/stage-one/bridge-integration.md
L1.
**Administrator:** [L1 Proxy Admin](#admin-roles)
**Requirement:** No requirement
-**Notes:** This role is only active when the `OptimismPortal` respected game type is [
-`PERMISSIONED_CANNON`](https://github.com/ethereum-optimism/optimism/blob/op-contracts/v1.5.0/packages/contracts-bedrock/src/dispute/lib/Types.sol#L31).
+**Notes:** This role is only active when the `OptimismPortal` respected game type is [`PERMISSIONED_CANNON`]
+().
The `L1ProxyAdmin` sets the implementation of the `PERMISSIONED_CANNON` game type. Thus, it determines the proposer
configuration of the permissioned dispute game.
diff --git a/specs/protocol/holocene/configurability.md b/specs/protocol/holocene/configurability.md
index b1300be0c..490beb0d4 100644
--- a/specs/protocol/holocene/configurability.md
+++ b/specs/protocol/holocene/configurability.md
@@ -55,7 +55,7 @@ The following `ConfigUpdate` enum is defined where the `CONFIG_VERSION` is `uint
| 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 |
+| `FEE_SCALARS` | `uint8(1)` | `(uint256(0x01) << 248) \| (uint256(_operatorFeeScalar) << 108 \| (uint256(_operatorFeeConstant) << 96 \| (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(_denominator)) << 32 \| uint64(_elasticity)` | Modifies the EIP-1559 denominator and elasticity |
diff --git a/specs/protocol/holocene/derivation.md b/specs/protocol/holocene/derivation.md
index cd51a1b13..949c2a9db 100644
--- a/specs/protocol/holocene/derivation.md
+++ b/specs/protocol/holocene/derivation.md
@@ -341,5 +341,7 @@ The Holocene hardfork activation block contains the following transactions, in t
- L1Block deployment
- Update L1Block Proxy ERC-1967 Implementation
- L1Block Enable Holocene
+ - GasPriceOracle deployment
+ - Update GasPriceOracle Proxy ERC-1967 Implementation
- OptimismMintableERC20Factory deployment
- Update OptimismMintableERC20Factory Proxy ERC-1967 Implementation
diff --git a/specs/protocol/holocene/exec-engine.md b/specs/protocol/holocene/exec-engine.md
index 42d3bd891..0a1a0e371 100644
--- a/specs/protocol/holocene/exec-engine.md
+++ b/specs/protocol/holocene/exec-engine.md
@@ -11,6 +11,9 @@
- [Rationale](#rationale)
- [Forwards Compatibility Considerations](#forwards-compatibility-considerations)
- [Client Implementation Considerations](#client-implementation-considerations)
+- [Fees](#fees)
+ - [Operator fees](#operator-fees)
+ - [Configuring scalars](#configuring-scalars)
@@ -75,3 +78,37 @@ directly store this information.
[l2-to-l1-mp]: ../../protocol/predeploys.md#L2ToL1MessagePasser
[output-root]: ../../glossary.md#l2-output-root
+
+## Fees
+
+New OP stack variants have different resource consumption patterns, and thus require a more flexible
+pricing model. To enable more customizable fee structures, Holocene adds a new component to the fee
+calculation: the `operatorFee`, which is parameterized by two scalars: the `operatorFeeScalar`
+and the `operatorFeeConstant`.
+
+### Operator fees
+
+The operator fee, in wei, is set as follows:
+
+`operatorFee = (gasUsed * operatorFeeScalar / 1e6) + operatorFeeConstant`
+
+Where:
+
+- `gasUsed` is amount of gas used by the transaction.
+- `operatorFeeScalar` is a `uint32` scalar set by the chain operator, scaled by `1e6`.
+- `operatorFeeConstant` is a `uint64` scalar set by the chain operator.
+
+These collected fees are sent to the `SequencerFeeVault`.
+
+#### Configuring scalars
+
+`operatorFeeScalar` and `operatorFeeConstant` are loaded in a similar way to the `baseFeeScalar` and
+`blobBaseFeeScalar` used in the [`L1Fee`](../../protocol/exec-engine.md#ecotone-l1-cost-fee-changes-eip-4844-da).
+calculation. In more detail, these scalars can be accessed in two interchangable ways.
+
+- read from the deposited L1 attributes (`operatorFeeScalar` and `operatorFeeConstant`) of the current L2 block
+- read from the L1 Block Info contract (`0x4200000000000000000000000000000000000015`)
+ - using the respective solidity getter functions (`operatorFeeScalar`, `operatorFeeConstant`)
+ - using direct storage-reads:
+ - Operator fee scalar as big-endian `uint32` in slot `3` at offset `20`.
+ - Operator fee constant as big-endian `uint64` in slot `3` at offset `16`.
diff --git a/specs/protocol/holocene/l1-attributes.md b/specs/protocol/holocene/l1-attributes.md
index a21d841b7..aa4a1fcff 100644
--- a/specs/protocol/holocene/l1-attributes.md
+++ b/specs/protocol/holocene/l1-attributes.md
@@ -26,3 +26,14 @@ The L1 block attributes transaction is updated to include the EIP-1559 parameter
| batcherHash | bytes32 | 132-163 | 5 |
| eip1559Denominator | uint64 | 164-171 | 6 |
| eip1559Elasticity | uint64 | 172-179 | |
+| operatorFeeScalar | uint32 | 180-183 | |
+| operatorFeeConstant | uint64 | 184-191 | |
+
+In the first L2 block after the Holocene activation block, the Holocene L1 attributes are first used.
+
+The pre-Holocene values are migrated over 1:1.
+Blocks after the Holocene activation block contain all pre-Holocene values 1:1,
+and also set the following new attributes:
+
+- The `operatorFeeScalar` is set to `0`.
+- The `operatorFeeConstant` is set to `0`.
diff --git a/specs/protocol/holocene/overview.md b/specs/protocol/holocene/overview.md
index c57ce2d85..fcf77a7eb 100644
--- a/specs/protocol/holocene/overview.md
+++ b/specs/protocol/holocene/overview.md
@@ -26,3 +26,4 @@ This document is not finalized and should be considered experimental.
- [Predeploys](./predeploys.md)
- [L1 Block Attributes](./l1-attributes.md)
- [Configurability](./configurability.md)
+- [System Config](./system-config.md)
diff --git a/specs/protocol/holocene/predeploys.md b/specs/protocol/holocene/predeploys.md
index 99002982d..af16199e3 100644
--- a/specs/protocol/holocene/predeploys.md
+++ b/specs/protocol/holocene/predeploys.md
@@ -30,6 +30,9 @@
- [Interface](#interface-3)
- [L2StandardBridge](#l2standardbridge)
- [Interface](#interface-4)
+ - [GasPriceOracle](#gaspriceoracle)
+ - [Interface](#interface-5)
+ - [`getOperatorFee`](#getoperatorfee)
- [OptimismMintableERC721Factory](#optimismmintableerc721factory)
- [Security Considerations](#security-considerations)
- [GovernanceToken](#governancetoken)
@@ -255,6 +258,21 @@ The following functions are updated to read from the `L1Block` contract by calli
- `otherBridge()(address)`
- `OTHER_BRIDGE()(address)`
+### GasPriceOracle
+
+In order to maintain accurate offchain fee estimation, the `GasPriceOracle` must be updated to allow users
+to estimate the operator fee.
+
+#### Interface
+
+##### `getOperatorFee`
+
+This function calculates the operator fee based on the expected amount of gas used for a certain transaction.
+
+```function
+function getOperatorFee(uint256 gasUsed)(uint256)
+```
+
### OptimismMintableERC721Factory
The chain id is no longer read from storage but instead is read from the `L1Block` contract by calling
diff --git a/specs/protocol/holocene/system-config.md b/specs/protocol/holocene/system-config.md
new file mode 100644
index 000000000..670e37011
--- /dev/null
+++ b/specs/protocol/holocene/system-config.md
@@ -0,0 +1,39 @@
+# System Config
+
+
+
+**Table of Contents**
+
+- [System config contents (version 0)](#system-config-contents-version-0)
+ - [Scalars](#scalars)
+ - [Holocene `scalar`, `overhead` (`uint256,uint256`) change](#holocene-scalar-overhead-uint256uint256-change)
+
+
+
+## System config contents (version 0)
+
+### Scalars
+
+In order to allow rollup operators to adjust the new `operatorFeeScalar` and `operatorFeeConstant`, a change to
+the `scalar` and `overhead` encoding is necessary.
+
+#### Holocene `scalar`, `overhead` (`uint256,uint256`) change
+
+After Holocene activation:
+
+- A new version to the `scalar` encoding is added. It is described as follows.
+
+\*Byte ranges are indicated with `[` (inclusive) and `)` (exclusive).
+
+- `0`: scalar-version byte
+- `[1, 32)`: depending scalar-version:
+ - Scalar-version `2`:
+ - `[1, 8)`: padding, must be zero.
+ - `[12, 16)`: big-endian `uint32`, encoding the `operatorFeeScalar`
+ - `[16, 24)`: big-endian `uint64`, encoding the `operatorFeeConstant`
+ - `[24, 28)`: big-endian `uint32`, encoding the `blobBaseFeeScalar`
+ - `[28, 32)`: big-endian `uint32`, encoding the `baseFeeScalar`
+ - This version adds the `operatorFeeScalar` and the `operatorFeeConstant`.
+
+The `operatorFeeScalar` and `operatorFeeConstant` are incorporated into the L2 through the
+[Holocene L1 attributes deposit transaction calldata](l1-attributes.md).