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: standard l2 genesis #97

Merged
merged 20 commits into from
Nov 6, 2024
Merged
Changes from 8 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
91 changes: 79 additions & 12 deletions protocol/standard-l2-genesis.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,24 +95,36 @@ block matches the expected value.

#### SuperchainConfig "Upgrader" Role

This new role is to allow for operational flexibility going into the future. If its not desired to add this role,
we could make the `guardian` able to faciliate the upgrade transactions. In practice, we may end up setting both
the `guardian` and the `upgrader` to the same account for the Superchain.

Open to removing this from the spec and just using the `guardian` if preferred, but the possible operational
flexibility seems useful.

The `upgrader` role can call the `OptimismPortal.upgrade(bytes memory data, uint32 gasLimit)` function
and it emits a deposit tx from the `DEPOSITOR_ACCOUNT` that calls the `L2ProxyAdmin`. Sourcing the auth
from the `SuperchainConfig` allows for simple management of this very important role, given that it impacts
stage 1 status. This is meant to simplify operations, ie remove the concept of the aliased L1 `ProxyAdmin` owner
stage 1 status. This is meant to simplify operations by removing the aliased L1 `ProxyAdmin` owner
being set as the L2 `ProxyAdmin`.

Since the the L1 and L2 `ProxyAdmin` contracts are intended to have the same owner,
an additional improvement (which may be excluded to limit scope creep), would be to remove the
`Ownable` dependency on the L1 `ProxyAdmin` contract, and instead have it read the
`SuperchainConfig.upgrader()` role to authorize upgrades.
maurelian marked this conversation as resolved.
Show resolved Hide resolved

The `data` and `gasLimit` are allowed to be specified since we don't fully know what sorts of calls we may have to do.
We may only need to do simple `upgradeTo` calls, but we may also need to do `upgradeToAndCall`. To support the
[liquidity migration](https://github.com/ethereum-optimism/design-docs/blob/4b62eb12eceb8e4867ac101134730102c0f5a989/protocol/superchainerc20/liquidity-migration.md), we need to backport storage slots into the `OptimismMintableERC20Factory`
contract. We may need to introduce multicall support into the `L2ProxyAdmin` as part of this.

#### FeeAdmin role

The entity which authorized to modify the various `FeeVault` configs must be able to vary from chain
maurelian marked this conversation as resolved.
Show resolved Hide resolved
to chain. Therefore a new `feeAdmin` role will be added to the `SystemConfig` contract. This role
can call a new `SystemConfig.setFeeConfig()` function which forwards config updates to
maurelian marked this conversation as resolved.
Show resolved Hide resolved
`OptimismPortal.setConfig()` with the appropriate `ConfigType`.

This role will be set in `SystemConfig.initialize()`, meaning that it can only be updated by an upgrade.

In summary:
maurelian marked this conversation as resolved.
Show resolved Hide resolved

1. The `FeeAdmin` can update the `FeeConfig`.
2. The Upgrade Controller (aka [L1 ProxyAdmin Owner](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/stage-1.md#configuration-of-safes)) Safe cand update the `FeeAdmin`.

#### L2ProxyAdmin

A new contract exists called the `L2ProxyAdmin`, it simply inherits from the `ProxyAdmin` and overrides the
Expand All @@ -123,7 +135,27 @@ that is considered a bonus when we do get around to it.

#### SystemConfig

The `SystemConfig`
The `SystemConfig`'s `initialize()` function will be updated to:

- Accept a new `Roles` struct, composed of the existing `owner` address, and the new
`feeAdmin` role.
- Makes multiple calls to the OptimismPortal's `setConfig()` function to set the config values.

> [!IMPORTANT]
> We should consider if there is a risk associated with 'resetting' these values. Similar to the OptimismPortal's
> `DEFAULT_L2_SENDER` [reinit issue](https://github.com/ethereum-optimism/optimism/pull/8864).
> I do not believe so as they are only modifiable in the `initializer` and so cannot be
> changed in normal operation. However the current design will require that all
> `SystemConfig` upgrades do not unintentionally modify the existing values.

The `SystemConfig` will also get the following new external methods which are only callable by the
`feeAdmin`:

```solidity
function setBaseFeeVaultConfig(address _recipient, uint256 _min, Types.WithdrawalNetwork _network) external;
function setL1FeeVaultConfig(address _recipient, uint256 _min, Types.WithdrawalNetwork _network) external;
function setSequencerFeeVaultConfig(address _recipient, uint256 _min, Types.WithdrawalNetwork _network) external;
```

#### Initializable Predeploys Removed

Expand Down Expand Up @@ -153,8 +185,33 @@ The additional deposit gas is the only additional resource usage and its covered
at the bottom of this document.

This approach expands the ABI of the `L1Block` contract, meaning that automatically generated solidity dispatcher
will binary search over the possible function selectors, consuming a bit more gas. This is something that we could
avoid by writing a custom dispatcher in a fallback function or by grinding for names of functions.
will binary search over the possible function selectors, consuming a bit more gas.

## Implications for the Predeploy Releases Process

### L2Genesis Generation

When a new predeploy release is created, the bytcode from each predeploy should be placed into a
an new autogenerated library which resembles the following:

```solidity
library HolocenePredeploys {
bytes constant L1Block = hex"...";
...
}
```

The `L2Genesis.s.sol` solidity script, will have additional functionality so that it can
maurelian marked this conversation as resolved.
Show resolved Hide resolved
optionally generate the L2 state from the current commit as it currently does using
`vm.getDeployedCode()`, or retrieve the code from the specified library.

### Upgrade Process

Note that this design modifies how L2 upgrade auth is managed (moving that management into a single
storage slot on L1), but does not change how upgrades to predeploy contracts are performed.
Predeploy upgrades can still be done either via a `TransactionDeposited()` event, or a [network
upgrade automation
transaction](https://github.com/ethereum-optimism/specs/blob/9f7226be064be0c87f90cbc6be6b0a4b4f58656a/specs/protocol/derivation.md#network-upgrade-automation-transactions).
maurelian marked this conversation as resolved.
Show resolved Hide resolved

# Alternatives Considered

Expand All @@ -173,14 +230,24 @@ to source this config, it would likely need to be hardcoded in the binary and th
<!-- An overview of what could go wrong.
Also any open questions that need more work to resolve. -->

## Sequenced transactions on a fresh chain

There is a concern that the sequencer can include transactions before these values are set on L2.
If we define the `SystemConfig.startBlock` as the [first block to start derivation in](https://github.com/ethereum-optimism/optimism/blob/d05fb505809717282d5cee7264a09d26002a4ddd/op-node/cmd/genesis/cmd.go#L174C30-L174C40),
which is set on `SystemConfig.initialize` and also the deposit transactions that set these values are
sent in the same block, then we should have the guarantee that no user transactions are included before
the deposit transactions.

## Max Resource Limit on Deposit Transactions

There is a concern around the max deposit gas limit being too small so that the `SystemConfig` cannot
deposit all of these values, we should have logic that reverts if the deposit gas limit is too small
maurelian marked this conversation as resolved.
Show resolved Hide resolved
in the `ResourceConfig` sanity check function. Since the `ResourceConfig` can be modified during
in the `setResourceConfig()` function's [sanity checks](https://github.com/ethereum-optimism/optimism/blob/feat/holocene-contracts/packages/contracts-bedrock/src/L1/SystemConfig.sol#L538-L556). Since the `ResourceConfig` can be modified during
`initialize`, its not that big of a deal and chain operators will see that they need to increase that
value.

A related concern is that the `useGas()`
[function](https://github.com/ethereum-optimism/optimism/blob/f99424ded3917ddc0c4ef14355d61e50a38d4d0d/packages/contracts-bedrock/src/L1/ResourceMetering.sol#L156)
which is called in the `upgrade()` and `setConfig()` functions does not check that the max resource limit is not exceeded by
the additional `prevBoughtGas`. This is in contrast with
[`_metered()`](https://github.com/ethereum-optimism/optimism/blob/f99424ded3917ddc0c4ef14355d61e50a38d4d0d/packages/contracts-bedrock/src/L1/ResourceMetering.sol#L128C1-L132C10) which does check `prevBoughtGas`. This requires investigation.
maurelian marked this conversation as resolved.
Show resolved Hide resolved