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

interop: change SuperchainERC20 function naming to be Superchain neutral #413

Merged
merged 5 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
18 changes: 10 additions & 8 deletions specs/interop/predeploys.md
Original file line number Diff line number Diff line change
Expand Up @@ -855,9 +855,10 @@ It SHOULD burn `_amount` tokens with address `_tokenAddress` and initialize a me
in the target address `_to` at `_chainId` and emit the `SentERC20` event including the `msg.sender` as parameter.

To burn the token, the `sendERC20` function
calls `__superchainBurn` in the token contract,
which is included as part of the the `SuperchainERC20`
[standard](./token-bridging.md#__superchainburn).
calls `__crosschainBurn` in the token contract,
which is included as part of the the `ICrosschainERC20`
[interface](./token-bridging.md#__crosschainburn)
implemented by the `SuperchainERC20` standard.

```solidity
sendERC20(address _tokenAddress, address _to, uint256 _amount, uint256 _chainId)
Expand All @@ -873,9 +874,10 @@ and emit an event including the `_tokenAddress`, the `_from` and chain id from t
`source` chain, where `_from` is the `msg.sender` of `sendERC20`.

To mint the token, the `relayERC20` function
calls `__superchainMint` in the token contract,
which is included as part of the the `SuperchainERC20`
[standard](./token-bridging.md#__superchainmint).
calls `__crosschainMint` in the token contract,
which is included as part of the the `ICrosschainERC20`
[interface](./token-bridging.md#__crosschainmint)
implemented by the `SuperchainERC20` standard.

```solidity
relayERC20(address _tokenAddress, address _from, address _to, uint256 _amount)
Expand Down Expand Up @@ -915,13 +917,13 @@ sequenceDiagram
participant SuperERC20_B as SuperchainERC20 (Chain B)

from->>L2SBA: sendERC20To(tokenAddr, to, amount, chainID)
L2SBA->>SuperERC20_A: __superchainBurn(from, amount)
L2SBA->>SuperERC20_A: __crosschainBurn(from, amount)
SuperERC20_A-->SuperERC20_A: emit SuperchainBurn(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: __superchainMint(to, amount)
L2SBB->>SuperERC20_B: __crosschainMint(to, amount)
SuperERC20_B-->SuperERC20_B: emit SuperchainMinted(to, amount)
L2SBB-->L2SBB: emit RelayedERC20(tokenAddr, from, to, amount, source)
```
Expand Down
65 changes: 34 additions & 31 deletions specs/interop/token-bridging.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
- [Overview](#overview)
- [`SuperchainERC20` standard](#superchainerc20-standard)
- [Properties](#properties)
- [Interface](#interface)
- [`__superchainMint`](#__superchainmint)
- [`__superchainBurn`](#__superchainburn)
- [`SuperchainMinted`](#superchainminted)
- [`SuperchainBurnt`](#superchainburnt)
- [`ICrosschainERC20`](#icrosschainerc20)
- [`__crosschainMint`](#__crosschainmint)
- [`__crosschainBurn`](#__crosschainburn)
- [`CrosschainMinted`](#crosschainminted)
- [`CrosschainBurnt`](#crosschainburnt)
- [`SuperchainERC20Bridge`](#superchainerc20bridge)
- [Diagram](#diagram)
- [Implementation](#implementation)
Expand All @@ -32,9 +32,11 @@ The `SuperchainERC20Bridge` is a predeploy that builds on the messaging protocol

### Properties

The standard will build on top of ERC20 and include the following properties:
The standard will build on top of ERC20, implement the [`ICrosschainERC20`](#icrosschainerc20)
interface and include the following properties:

1. Give `mint` and `burn` rights to the `SuperchainERC20Bridge`.
1. Only allow `SuperchainERC20Bridge` to call
[`__crosschainMint`](#__crosschainmint) and [`__crosschainBurn`](#__crosschainburn).
2. Be deployed at the same address on every chain in the Superchain.

The first property will allow the `SuperchainERC20Bridge` to have a liquidity guarantee,
Expand All @@ -56,40 +58,41 @@ Notice that ERC20s that do not implement the standard can still be fungible
using interop message passing
using a custom bridge or implementing `sendERC20` and `relayERC20` on their own contracts.

### Interface
### `ICrosschainERC20`

Implementations of the `SuperchainERC20` standard will need to implement two external functions and two events:
Implementations of the `SuperchainERC20` standard will need to implement the `ICrosschainERC20`
token standard, that includes two external functions and two events:

#### `__superchainMint`
#### `__crosschainMint`

Mints `_amount` of token to address `_account`. It should only be callable by the `SuperchainERC20Bridge`
Mints `_amount` of token to address `_account`.

```solidity
__superchainMint(address _account, uint256 _amount)
__crosschainMint(address _account, uint256 _amount)
```

#### `__superchainBurn`
#### `__crosschainBurn`

Burns `_amount` of token from address `_account`. It should only be callable by the `SuperchainERC20Bridge`
Burns `_amount` of token from address `_account`.

```solidity
__superchainBurn(address _account, uint256 _amount)
__crosschainBurn(address _account, uint256 _amount)
```

#### `SuperchainMinted`
#### `CrosschainMinted`

MUST trigger when `__superchainMint` is called
MUST trigger when `__crosschainMint` is called

```solidity
event SuperchainMinted(address indexed _to, uint256 _amount)
event CrosschainMinted(address indexed _to, uint256 _amount)

Choose a reason for hiding this comment

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

This doesn't really matter but just want to note that the main optimism repository doesn't prefix event parameters with underscores.

e.g. in this implementation

https://github.com/defi-wonderland/optimism/blob/a5aca61f43f0141e2f986f478c7cab5b48216b56/packages/contracts-bedrock/src/L2/interfaces/ICrosschainERC20.sol

```

#### `SuperchainBurnt`
#### `CrosschainBurnt`

MUST trigger when `__superchainBurn` is called
MUST trigger when `__crosschainBurn` is called

```solidity
event SuperchainBurnt(address indexed _from, uint256 _amount)
event CrosschainBurnt(address indexed _from, uint256 _amount)
```

## `SuperchainERC20Bridge`
Expand Down Expand Up @@ -128,14 +131,14 @@ sequenceDiagram
participant SuperERC20_B as SuperchainERC20 (Chain B)

from->>L2SBA: sendERC20To(tokenAddr, to, amount, chainID)
L2SBA->>SuperERC20_A: __superchainBurn(from, amount)
SuperERC20_A-->SuperERC20_A: emit SuperchainBurnt(from, amount)
L2SBA->>SuperERC20_A: __crosschainBurn(from, amount)
SuperERC20_A-->SuperERC20_A: emit CrosschainBurnt(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: __superchainMint(to, amount)
SuperERC20_B-->SuperERC20_B: emit SuperchainMinted(to, amount)
L2SBB->>SuperERC20_B: __crosschainMint(to, amount)
SuperERC20_B-->SuperERC20_B: emit CrosschainMinted(to, amount)
L2SBB-->L2SBB: emit RelayedERC20(tokenAddr, from, to, amount, source)
```

Expand All @@ -145,7 +148,7 @@ An example implementation for the `sendERC20` and `relayERC20` functions is prov

```solidity
function sendERC20(SuperchainERC20 _token, address _to, uint256 _amount, uint256 _chainId) external {
_token.__superchainBurn(msg.sender, _amount);
_token.__crosschainBurn(msg.sender, _amount);

bytes memory _message = abi.encodeCall(this.relayERC20, (_token, msg.sender, _to, _amount));
L2ToL2CrossDomainMessenger.sendMessage(_chainId, address(this), _message);
Expand All @@ -159,7 +162,7 @@ function relayERC20(SuperchainERC20 _token, address _from, address _to, uint256

uint256 _source = L2ToL2CrossChainMessenger.crossDomainMessageSource();

_token.__superchainMint(_to, _amount);
_token.__crosschainMint(_to, _amount);

emit RelayERC20(address(_token), _from, _to, _amount, _source);
}
Expand Down Expand Up @@ -222,15 +225,15 @@ sequenceDiagram

from->>Intermediate_A: sendWithData(data)
Intermediate_A->>L2SBA: sendERC20To(tokenAddr, to, amount, chainID)
L2SBA->>SuperERC20_A: __superchainBurn(from, amount)
SuperERC20_A-->SuperERC20_A: emit SuperchainBurnt(from, amount)
L2SBA->>SuperERC20_A: __crosschainBurn(from, amount)
SuperERC20_A-->SuperERC20_A: emit CrosschainBurnt(from, amount)
L2SBA->>Messenger_A: sendMessage(chainId, message)
L2SBA-->L2SBA: emit SentERC20(tokenAddr, from, to, amount, destination)
Intermediate_A->>Messenger_A: sendMessage(chainId, to, data)
Inbox->>Messenger_B: relayMessage()
Messenger_B->>L2SBB: relayERC20(tokenAddr, from, to, amount)
L2SBB->>SuperERC20_B: __superchainMint(to, amount)
SuperERC20_B-->SuperERC20_B: emit SuperchainMinted(to, amount)
L2SBB->>SuperERC20_B: __crosschainMint(to, amount)
SuperERC20_B-->SuperERC20_B: emit CrosschainMinted(to, amount)
Inbox->>Messenger_B: relayMessage(): call
L2SBB-->L2SBB: emit RelayedERC20(tokenAddr, from, to, amount, source)
Messenger_B->>to: call(data)
Expand Down