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: add shared lockbox spec #465

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
4 changes: 4 additions & 0 deletions specs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
- [SuperchainWETH](./interop/superchain-weth.md)
- [Derivation](./interop/derivation.md)
- [Transaction Pool](./interop/tx-pool.md)
- [OptimismPortal](./interop/optimism-portal.md)
- [SuperchainConfig](./interop/superchain-config.md)
- [Shared Lockbox](./interop/shared-lockbox.md)
- [Shared Lockbox Upgrade](./interop/shared-lockbox-upgrade.md)
- [OP Contracts Manager](./experimental/op-contracts-manager.md)
- [Governance Token](./experimental/gov-token.md)
- [Multithreaded Cannon FPVM](./experimental/cannon-fault-proof-vm-mt.md)
Expand Down
16 changes: 16 additions & 0 deletions specs/interop/dependency-set.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- [Chain ID](#chain-id)
- [Updating the Dependency Set](#updating-the-dependency-set)
- [The CLUSTER_MANAGER Role](#the-cluster_manager-role)
- [Future Considerations](#future-considerations)
- [Layer 1 as Part of the Dependency Set](#layer-1-as-part-of-the-dependency-set)
- [Security Considerations](#security-considerations)
Expand Down Expand Up @@ -47,6 +48,21 @@ It is a known issue that not all software in the Ethereum ecosystem can handle 3
The dependency set is managed in the client software. Adding a chain to the dependency set is
considered an upgrade to the network. It is not possible to remove chains from the dependency set.

The dependency set is managed by the L1 `SuperchainConfig` contract. It:

- Maintains the L1-side dependency set
- Manages authorized `OptimismPortal`s
- Handles ETH liquidity migration to `SharedLockbox` when adding new dependencies
- Can only be updated by the `CLUSTER_MANAGER` role

More details can be found on the [Superchain Config interop specification](./superchain-config.md#Overview).

### The CLUSTER_MANAGER Role

The `CLUSTER_MANAGER` role is a privileged role in the `SuperchainConfig` contract that has the authority
to directly add chains to the dependency set. This role can add chains by calling `addDependency` and must
provide valid chain ID and `SystemConfig` contract addresses when doing so.

## Future Considerations

### Layer 1 as Part of the Dependency Set
Expand Down
119 changes: 119 additions & 0 deletions specs/interop/optimism-portal-interop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# OptimismPortal Interop

<!-- 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**

- [Overview](#overview)
- [Integrating `SharedLockbox`](#integrating-sharedlockbox)
- [Interface and properties](#interface-and-properties)
- [ETH Management](#eth-management)
- [`migrateLiquidity`](#migrateliquidity)
- [Internal ETH Functions](#internal-eth-functions)
- [`_lockETH`](#_locketh)
- [`_unlockETH`](#_unlocketh)
- [Events](#events)
- [`ETHMigrated`](#ethmigrated)
- [Invariants](#invariants)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Overview
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be clear that its possible to upgrade to this hardfork and not be part of a cluster. The requirement would be that a chain has its own lockbox


The `OptimismPortal` contract is extended to integrate with the `SharedLockbox`
for managing unified ETH liquidity.
This liquidity consists of every ETH balance migrated from each `OptimismPortal` when joining
the op-governed dependency set.

It is possible to upgrade to this version without being part of the op-governed dependency set. In this case,
the corresponding chain would need to deploy and manage its own `SharedLockbox` and `SuperchainConfig`.

### Integrating `SharedLockbox`

The integration with the `SharedLockbox` involves locking ETH when executing deposit transactions and unlocking ETH
when finalizing withdrawal transactions, without altering other aspects of the current `OptimismPortal` implementation.

## Interface and properties

### ETH Management

#### `migrateLiquidity`

Migrates the ETH liquidity to the SharedLockbox. This function will only be called once by the
SuperchainConfig when adding this chain to the dependency set.

```solidity
function migrateLiquidity() external;
```

- MUST only be callable by the `SuperchainConfig` contract
- MUST set the migrated flag to true
- MUST transfer all ETH balance to the `SharedLockbox`
- MUST emit an `ETHMigrated` event with the amount transferred

### Internal ETH Functions

The contract overrides two internal functions from `OptimismPortal2` to handle ETH management with the `SharedLockbox`:

#### `_lockETH`

Called during deposit transactions to handle ETH locking.

```solidity
function _lockETH() internal virtual override;
```

- MUST be called during `depositTransaction` when there is ETH value
- If not migrated, function is a no-op
- If migrated:
- MUST lock any ETH value in the `SharedLockbox`
- MUST NOT revert on zero value

#### `_unlockETH`

Called during withdrawal finalization to handle ETH unlocking.

```solidity
function _unlockETH(Types.WithdrawalTransaction memory _tx) internal virtual override;
```

- MUST be called during withdrawal finalization when there is ETH value
- If not migrated, function is a no-op
- If migrated:
- MUST unlock the withdrawal value from the `SharedLockbox`
- MUST NOT revert on zero value
- MUST revert if withdrawal target is the `SharedLockbox`

## Events

### `ETHMigrated`

MUST be triggered when the ETH liquidity is migrated to the SharedLockbox.

```solidity
event ETHMigrated(uint256 amount);
```

## Invariants

- Before migration:

- Deposits MUST keep the ETH in the portal

- Withdrawals MUST use the portal's own ETH balance

- After migration:

- Deposits MUST lock the ETH in the `SharedLockbox`

- Withdrawals MUST unlock the ETH from the `SharedLockbox` and forward it to the withdrawal target

- The contract MUST NOT hold any ETH balance from deposits or withdrawals

- General invariants:

- The contract MUST be able to handle zero ETH value operations

- The contract MUST NOT allow withdrawals to target the `SharedLockbox` address

- The contract MUST only migrate liquidity once
14 changes: 7 additions & 7 deletions specs/interop/predeploys.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ Emits the `ExecutingMessage` event to signal the transaction has a cross chain m

The following fields are required for validating a cross chain message:

| Name | Type | Description |
| -------- | ---------- | -------------------------------------------------------------------------- |
| `_id` | Identifier | A [`Identifier`] pointing to the initiating message. |
| `_msgHash` | `bytes32` | The keccak256 hash of the message payload matching the initiating message. |
| Name | Type | Description |
| ---------- | ---------- | -------------------------------------------------------------------------- |
| `_id` | Identifier | A [`Identifier`] pointing to the initiating message. |
| `_msgHash` | `bytes32` | The keccak256 hash of the message payload matching the initiating message. |

```solidity
function validateMessage(Identifier calldata _id, bytes32 _msgHash)
Expand Down Expand Up @@ -768,9 +768,9 @@ sequenceDiagram
L2SBA->>SuperERC20_A: crosschainBurn(from, amount)
SuperERC20_A-->SuperERC20_A: emit CrosschainBurn(from, amount)
L2SBA->>Messenger_A: sendMessage(chainId, message)
Messenger_A->>L2SBA: return msgHash_
Messenger_A->>L2SBA: return msgHash_
L2SBA-->L2SBA: emit SentERC20(tokenAddr, from, to, amount, destination)
L2SBA->>from: return msgHash_
L2SBA->>from: return msgHash_
Inbox->>Messenger_B: relayMessage()
Messenger_B->>L2SBB: relayERC20(tokenAddr, from, to, amount)
L2SBB->>SuperERC20_B: crosschainMint(to, amount)
Expand Down Expand Up @@ -801,7 +801,7 @@ The bridging of `SuperchainERC20` using the `SuperchainTokenBridge` will require
to the same address on the target chain.
Similarly, the `relayERC20()` function should only process messages originating from the same address.
- Note: The [`Create2Deployer` preinstall](../protocol/preinstalls.md#create2deployer)
and the custom Factory will ensure same address deployment.
and the custom Factory will ensure same address deployment.
- Locally initiated: The bridging action should be initialized
from the chain where funds are located only.
- This is because the same address might correspond to different users cross-chain.
Expand Down
87 changes: 87 additions & 0 deletions specs/interop/shared-lockbox-upgrade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Shared Lockbox - Upgrade and migration process

<!-- 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**

- [Overview](#overview)
- [Upgrade Process](#upgrade-process)
- [ETH Migration](#eth-migration)
- [Diagram](#diagram)
- [Future Considerations / Additional Notes](#future-considerations--additional-notes)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Overview

When a new chain joins the op-governed dependency set, it must integrate with the `SharedLockbox`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should distinguish what op-governed means here, and realistically just say "Superchain" unless we want to mention other interop dependency sets

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm I believe this should be common for every cluster so maybe finding a more general definition could be better

to participate in unified ETH liquidity management. This process is initiated by the `CLUSTER_MANAGER` role.

## Upgrade Process

1. The `CLUSTER_MANAGER` role calls `addDependency` on the `SuperchainConfig`
contract with the new chain ID and it's system config address

2. The `SuperchainConfig` processes the addition by:

- Validating the request came from the cluster manager
- Verifying the chain ID isn't already in the dependency set
- Adding the chain ID to the dependency set
- Getting the chain's portal address from its `SystemConfig`

3. The portal is authorized in the `SharedLockbox`:

- Verifying the portal uses the correct `SuperchainConfig`
- Checking the portal isn't already authorized
- Adding the portal to the authorized portals mapping
- Triggering ETH migration via `migrateLiquidity()`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be very explicit here that this is the step where the eth actually changes hands

- In this step the `OptimismPortal`'s ETH balance is transferred to the `SharedLockbox`

4. The `OptimismPortal` migrates its ETH:
- Sets migrated flag to true

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would include the second order effect of why this matters

- This is necessary to start using the `SharedLockbox` for ETH operations,
if not set the `OptimismPortal` will continue using it's own ETH balance.
- Transfers entire ETH balance to `SharedLockbox` via `lockETH()`
- `SharedLockbox` emits `ETHLocked` event
- Portal emits `ETHMigrated` event

### ETH Migration

After authorization, the `OptimismPortal`'s ETH liquidity is migrated to the `SharedLockbox`:

1. The `OptimismPortal`'s ETH balance is transferred to the `SharedLockbox`
2. The `OptimismPortal` is configured to use the `SharedLockbox` for all future ETH operations

After migration:

- All deposits lock ETH in the `SharedLockbox`
- All withdrawals unlock ETH from the `SharedLockbox`
- The `OptimismPortal` no longer holds ETH directly

## Diagram

```mermaid
sequenceDiagram
participant ClusterManager
participant Config as SuperchainConfig
participant Portal as OptimismPortal
participant Lockbox as SharedLockbox

ClusterManager->>Config: addDependency(chainId, systemConfig)
Config->>Config: validate & add to set
Config->>Config: authorize portal
Config->>Portal: migrateLiquidity()
Portal->>Lockbox: lockETH(balance)
Lockbox->>Config: authorizedPortals(portal)
Lockbox-->>Lockbox: emits ETHLocked
Portal-->>Portal: emits ETHMigrated
Config-->>Config: emits DependencyAdded
```

## Future Considerations / Additional Notes

- Before calling `addDependency`, it MUST be ensured that the `chainId` and `systemConfig` match.
This means that the `systemConfig` address is the correct one for the chain ID. There is no on-chain source of truth
for this information, so it is the responsibility of the `CLUSTER_MANAGER` to ensure the correct parameters are used.

- The `OptimismPortal` MUST be updated before initiating the migration
Loading