Skip to content

Commit

Permalink
Merge branch 'main' into vd/h-l2-withdrawals-root
Browse files Browse the repository at this point in the history
  • Loading branch information
vdamle authored Sep 27, 2024
2 parents 7eadd5d + 8163c9d commit 8d6e224
Show file tree
Hide file tree
Showing 8 changed files with 621 additions and 206 deletions.
2 changes: 1 addition & 1 deletion specs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,6 @@
- [SuperchainWETH](./interop/superchain-weth.md)
- [Derivation](./interop/derivation.md)
- [Transaction Pool](./interop/tx-pool.md)
- [OP Stack Manager](./experimental/op-stack-manager.md)
- [OP Contracts Manager](./experimental/op-contracts-manager.md)
- [Governance Token](./experimental/gov-token.md)
- [Glossary](./glossary.md)
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# OP Stack Manager
# OP Contracts Manager

[`op-contracts/v1.4.0`]: https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.4.0
[`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
[superchain registry]: https://github.com/ethereum-optimism/superchain-registry
[ethereum-lists/chains]: https://github.com/ethereum-lists/chains
[Batch Inbox]: ../protocol/configurability.md#consensus-parameters

The OP Stack Manager is a contract that deploys the L1 contracts for an OP Stack chain in a single
The OP Contracts Manager is a contract that deploys the L1 contracts for an OP Stack chain in a single
transaction. It provides a minimal set of user-configurable parameters to ensure that the resulting
chain meets the [standard configuration] requirements.

Expand Down Expand Up @@ -40,22 +40,22 @@ of governance approved [contract releases] can be found on the

## Deployment

The OP Stack Manager is a proxied contract deployed at `0xTODO`. It can be deployed as follows:
The OP Contracts Manager is a proxied contract deployed at `0xTODO`. It can be deployed as follows:

TODO.

## Interface

Version 1.0.0 of the OP Stack Manager deploys the [`op-contracts/v1.4.0`]
Version 1.0.0 of the OP Contracts Manager deploys the [`op-contracts/v1.6.0`]
contracts release.

### `Proxy.sol`

The OP Stack Manager is a proxied contract using the standard `Proxy.sol` contract that lives in
the Optimism monorepo. Therefore the OP Stack Manager will have the same interface as the
The OP Contracts Manager is a proxied contract using the standard `Proxy.sol` contract that lives in
the Optimism monorepo. Therefore the OP Contracts Manager will have the same interface as the
`Proxy.sol`, in addition to other methods defined in this specification.

The privileged methods of the OP Stack Manager will be held by the L1 ProxyAdmin owner, as
The privileged methods of the OP Contracts Manager will be held by the L1 ProxyAdmin owner, as
specified by the [standard configuration].

### `deploy`
Expand Down Expand Up @@ -85,11 +85,11 @@ function deploy(
The `l2ChainId` has the following restrictions:

- It must not be equal to 0.
- It must not be equal to the chain ID of the chain the OP Stack Manager is
- It must not be equal to the chain ID of the chain the OP Contracts Manager is
deployed on.
- It must not be equal to a chain ID that is already present in the
[ethereum-lists/chains] repository. This is not enforced onchain, but may matter
for future versions of OP Stack Manager that handle upgrades.
for future versions of OP Contracts Manager that handle upgrades.

On success, the following event is emitted:

Expand Down Expand Up @@ -139,7 +139,7 @@ the batch inbox addresses.

### Contract Deployments

All contracts deployed by the OP Stack Manager are deployed with CREATE2, with a
All contracts deployed by the OP Contracts Manager are deployed with CREATE2, with a
salt equal to either:

- The L2 chain ID, or
Expand All @@ -157,29 +157,29 @@ This provides the following benefits:
will result in attempting to deploy to the same address, which is prohibited by
the EVM.
- This property is contingent on the proxy and `AddressManager` code not
changing when OP Stack Manager is upgraded. Both of these are not planned to
changing when OP Contracts Manager is upgraded. Both of these are not planned to
change.
- The OP Stack Manager is not responsible for enforcing chain ID uniqueness, so it is acceptable
if this property is not preserved in future versions of the OP Stack Manager.
- The OP Contracts Manager is not responsible for enforcing chain ID uniqueness, so it is acceptable
if this property is not preserved in future versions of the OP Contracts Manager.

## Security Considerations

### Chain ID Source of Truth

One of the implicit restrictions on chain ID is that `deploy` can only be called
once per chain ID, because contract addresses are a function of chain ID. However,
future versions of OP Stack Manager may:
future versions of OP Contracts Manager may:

- Change the Proxy code used, which would allow a duplicate chain ID to be deployed
if there is only the implicit check.
- Manage upgrades, which will require "registering" existing pre-OP Stack Manager
chains in the OP Stack Manager. Registration will be a privileged action, and the [superchain registry] will be
- Manage upgrades, which will require "registering" existing pre-OP Contracts Manager
chains in the OP Contracts Manager. Registration will be a privileged action, and the [superchain registry] will be
used as the source of truth for registrations.

This means, for example, if deploying a chain with a chain ID of 10—which is OP
Mainnet's chain ID—deployment will execute successfully, but the entry in OP
Stack Manager may be overwritten in a future upgrade. Therefore, chain ID
uniqueness is not enforced by the OP Stack Manager, and it is strongly
uniqueness is not enforced by the OP Contracts Manager, and it is strongly
recommended to only use chain IDs that are not already present in the
[ethereum-lists/chains] repository.

Expand All @@ -193,13 +193,13 @@ transactions can be frontrun.

### Chain ID Value

While not specific to OP Stack Manager, when choosing a chain ID is important
While not specific to OP Contracts Manager, when choosing a chain ID is important
to consider that not all chain IDs are well supported by tools. For example,
MetaMask [only supports](https://gist.github.com/rekmarks/a47bd5f2525936c4b8eee31a16345553)
chain IDs up to `4503599627370476`, well below the max allowable 256-bit value.

OP Stack Manager does not consider factors such as these. The EVM supports
256-bit chain IDs, so OP Stack Manager sticks with the full 256-bit range to
OP Contracts Manager does not consider factors such as these. The EVM supports
256-bit chain IDs, so OP Contracts Manager sticks with the full 256-bit range to
maximize compatibility.

### Proxy Admin Owner
Expand Down
136 changes: 133 additions & 3 deletions specs/interop/predeploys.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@
- [`Converted`](#converted)
- [Invariants](#invariants)
- [Conversion Flow](#conversion-flow)
- [SuperchainERC20Bridge](#superchainerc20bridge)
- [Overview](#overview-2)
- [Functions](#functions-2)
- [`sendERC20`](#senderc20)
- [`relayERC20`](#relayerc20)
- [Events](#events-2)
- [`SentERC20`](#senterc20)
- [`RelayedERC20`](#relayederc20)
- [Diagram](#diagram)
- [Invariants](#invariants-1)
- [Security Considerations](#security-considerations)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand Down Expand Up @@ -421,8 +431,9 @@ function relayExpire(bytes32 _expiredHash, uint256 _messageSource) external {

### OptimismSuperchainERC20

The `OptimismSuperchainERC20Factory` creates ERC20 contracts that implement to the `SuperchainERC20` [standard](token-bridging.md)
and grant mint-burn rights to the `L2StandardBridge` (`OptimismSuperchainERC20`).
The `OptimismSuperchainERC20Factory` creates ERC20 contracts that implements the `SuperchainERC20` [standard](token-bridging.md),
grants mint-burn rights to the `L2StandardBridge` (`OptimismSuperchainERC20`)
and include a `remoteToken` variable.
These ERC20s are called `OptimismSuperchainERC20` and can be converted back and forth with `OptimismMintableERC20` tokens.
The goal of the `OptimismSuperchainERC20` is to extend functionalities
of the `OptimismMintableERC20` so that they are interop compatible.
Expand Down Expand Up @@ -763,7 +774,7 @@ The `convert` function conserves the following invariants:
remote token addresses.
- Freedom of conversion for valid and paired tokens:
anyone can convert between allowed legacy representations and
valid `OptimismSuperchainERC20s` corresponding to the same remote token.
valid `OptimismSuperchainERC20` corresponding to the same remote token.

### Conversion Flow

Expand All @@ -785,6 +796,125 @@ sequenceDiagram
L2StandardBridge-->L2StandardBridge: emit Converted(from, to, Alice, amount)
```

## SuperchainERC20Bridge

| Constant | Value |
| -------- | -------------------------------------------- |
| Address | `0x4200000000000000000000000000000000000028` |

### Overview

The `SuperchainERC20Bridge` is an abstraction on top of the `L2toL2CrossDomainMessenger`
that facilitates token bridging using interop.
It has mint and burn rights over `SuperchainERC20` tokens
as described in the [token bridging spec](./token-bridging.md).

### Functions

#### `sendERC20`

Initializes a transfer of `_amount` amount of tokens with address `_tokenAddress` to target address `_to` in chain `_chainId`.

It SHOULD burn `_amount` tokens with address `_tokenAddress` and initialize a message to the
`L2ToL2CrossChainMessenger` to mint the `_amount` of the same token
in the target address `_to` at `_chainId` and emit the `SentERC20` event including the `msg.sender` as parameter.

```solidity
sendERC20(address _tokenAddress, address _to, uint256 _amount, uint256 _chainId)
```

#### `relayERC20`

Process incoming messages IF AND ONLY IF initiated
by the same contract (bridge) address on a different chain
and relayed from the `L2ToL2CrossChainMessenger` in the local chain.
It SHOULD mint `_amount` of tokens with address `_tokenAddress` to address `_to`, as defined in `sendERC20`
and emit an event including the `_tokenAddress`, the `_from` and chain id from the
`source` chain, where `_from` is the `msg.sender` of `sendERC20`.

```solidity
relayERC20(address _tokenAddress, address _from, address _to, uint256 _amount)
```

### Events

#### `SentERC20`

MUST trigger when a cross-chain transfer is initiated using `sendERC20`.

```solidity
event SentERC20(address indexed tokenAddress, address indexed from, address indexed to, uint256 amount, uint256 destination)
```

#### `RelayedERC20`

MUST trigger when a cross-chain transfer is finalized using `relayERC20`.

```solidity
event RelayedERC20(address indexed tokenAddress, address indexed from, address indexed to, uint256 amount, uint256 source);
```

### Diagram

The following diagram depicts a cross-chain transfer.

```mermaid
sequenceDiagram
participant from
participant L2SBA as SuperchainERC20Bridge (Chain A)
participant SuperERC20_A as SuperchainERC20 (Chain A)
participant Messenger_A as L2ToL2CrossDomainMessenger (Chain A)
participant Inbox as CrossL2Inbox
participant Messenger_B as L2ToL2CrossDomainMessenger (Chain B)
participant L2SBB as SuperchainERC20Bridge (Chain B)
participant SuperERC20_B as SuperchainERC20 (Chain B)
from->>L2SBA: sendERC20To(tokenAddr, to, amount, chainID)
L2SBA->>SuperERC20_A: burn(from, amount)
L2SBA->>Messenger_A: sendMessage(chainId, message)
L2SBA-->L2SBA: emit SentERC20(tokenAddr, from, to, amount, destination)
Inbox->>Messenger_B: relayMessage()
Messenger_B->>L2SBB: relayERC20(tokenAddr, from, to, amount)
L2SBB->>SuperERC20_B: mint(to, amount)
L2SBB-->L2SBB: emit RelayedERC20(tokenAddr, from, to, amount, source)
```

### Invariants

The bridging of `SuperchainERC20` using the `SuperchainERC20Bridge` will require the following invariants:

- Conservation of bridged `amount`: The minted `amount` in `relayERC20()` should match the `amount`
that was burnt in `sendERC20()`, as long as target chain has the initiating chain in the dependency set.
- Corollary 1: Finalized cross-chain transactions will conserve the sum of `totalSupply`
and each user's balance for each chain in the Superchain.
- Corollary 2: Each initiated but not finalized message (included in initiating chain but not yet in target chain)
will decrease the `totalSupply` and the initiating user balance precisely by the burnt `amount`.
- Corollary 3: `SuperchainERC20s` should not charge a token fee or increase the balance when moving cross-chain.
- Note: if the target chain is not in the initiating chain dependency set,
funds will be locked, similar to sending funds to the wrong address.
If the target chain includes it later, these could be unlocked.
- Freedom of movement: Users should be able to send and receive tokens in any target
chain with the initiating chain in its dependency set
using `sendERC20()` and `relayERC20()`, respectively.
- Unique Messenger: The `sendERC20()` function must exclusively use the `L2toL2CrossDomainMessenger` for messaging.
Similarly, the `relayERC20()` function should only process messages originating from the `L2toL2CrossDomainMessenger`.
- Unique Address: The `sendERC20()` function must exclusively send a message
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.
- 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.
For example, two SAFEs with the same address in two chains might have different owners.
With the prospects of a smart wallet future, it is impossible to assume
there will be a way to distinguish EOAs from smart wallets.
- A way to allow for remotely initiated bridging is to include remote approval,
i.e. approve a certain address in a certain chainId to spend local funds.
- Bridge Events:
- `sendERC20()` should emit a `SentERC20` event. `
- `relayERC20()` should emit a `RelayedERC20` event.

## Security Considerations

TODO
Loading

0 comments on commit 8d6e224

Please sign in to comment.