Skip to content

Commit

Permalink
interop: added superc20 interface for bridge interaction (#398)
Browse files Browse the repository at this point in the history
* feat: added interface to SuperchainERC20 standard in token-bridging.md

* feat: added references to the SuperchainERC20 interface in predeploys.md

* feat: changed interface function names from mint(burn)FromBridge to __superchainMint(Burn)

* feat: added SuperchainMint and SuperchainBurn events to the SuperchainERC20 interface
  • Loading branch information
0xParticle authored Oct 1, 2024
1 parent fb1fb8e commit 40a6a50
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 9 deletions.
16 changes: 14 additions & 2 deletions specs/interop/predeploys.md
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,11 @@ It SHOULD burn `_amount` tokens with address `_tokenAddress` and initialize a me
`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.

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).

```solidity
sendERC20(address _tokenAddress, address _to, uint256 _amount, uint256 _chainId)
```
Expand All @@ -867,6 +872,11 @@ It SHOULD mint `_amount` of tokens with address `_tokenAddress` to address `_to`
and emit an event including the `_tokenAddress`, the `_from` and chain id from the
`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).

```solidity
relayERC20(address _tokenAddress, address _from, address _to, uint256 _amount)
```
Expand Down Expand Up @@ -905,12 +915,14 @@ sequenceDiagram
participant SuperERC20_B as SuperchainERC20 (Chain B)
from->>L2SBA: sendERC20To(tokenAddr, to, amount, chainID)
L2SBA->>SuperERC20_A: burn(from, amount)
L2SBA->>SuperERC20_A: __superchainBurn(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: mint(to, amount)
L2SBB->>SuperERC20_B: __superchainMint(to, amount)
SuperERC20_B-->SuperERC20_B: emit SuperchainMint(to, amount)
L2SBB-->L2SBB: emit RelayedERC20(tokenAddr, from, to, amount, source)
```

Expand Down
62 changes: 55 additions & 7 deletions specs/interop/token-bridging.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

- [Overview](#overview)
- [`SuperchainERC20` standard](#superchainerc20-standard)
- [Properties](#properties)
- [Interface](#interface)
- [`__superchainMint`](#__superchainmint)
- [`__superchainBurn`](#__superchainburn)
- [`SuperchainMint`](#superchainmint)
- [`SuperchainBurn`](#superchainburn)
- [`SuperchainERC20Bridge`](#superchainerc20bridge)
- [Diagram](#diagram)
- [Implementation](#implementation)
Expand All @@ -18,12 +24,14 @@
## Overview

Without a standardized security model, bridged assets may not be fungible with each other.
The `SuperchainERC20` standard is a set of properties allowing ERC20 to be fungible across the
The `SuperchainERC20` standard is a set of properties and an interface allowing ERC20 to be fungible across the
Superchain using the official `SuperchainERC20Bridge`.
The `SuperchainERC20Bridge` is a predeploy that builds on the messaging protocol as the most trust-minimized bridging solution.

## `SuperchainERC20` standard

### Properties

The standard will build on top of ERC20 and include the following properties:

1. Give `mint` and `burn` rights to the `SuperchainERC20Bridge`.
Expand All @@ -48,6 +56,42 @@ 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

Implementations of the `SuperchainERC20` standard will need to implement the following two public functions:

#### `__superchainMint`

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

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

#### `__superchainBurn`

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

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

#### `SuperchainMint`

MUST trigger when `__superchainMint` is called

```solidity
event SuperchainMint(address indexed _to, uint256 _amount)
```

#### `SuperchainBurn`

MUST trigger when `__superchainBurn` is called

```solidity
event SuperchainBurn(address indexed _from, uint256 _amount)
```

## `SuperchainERC20Bridge`

The `SuperchainERC20Bridge` is a predeploy that works as an abstraction
Expand Down Expand Up @@ -84,12 +128,14 @@ sequenceDiagram
participant SuperERC20_B as SuperchainERC20 (Chain B)
from->>L2SBA: sendERC20To(tokenAddr, to, amount, chainID)
L2SBA->>SuperERC20_A: burn(from, amount)
L2SBA->>SuperERC20_A: __superchainBurn(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: mint(to, amount)
L2SBB->>SuperERC20_B: __superchainMint(to, amount)
SuperERC20_B-->SuperERC20_B: emit SuperchainMint(to, amount)
L2SBB-->L2SBB: emit RelayedERC20(tokenAddr, from, to, amount, source)
```

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

```solidity
function sendERC20(SuperchainERC20 _token, address _to, uint256 _amount, uint256 _chainId) public {
_token.burn(msg.sender, _amount);
_token.__superchainBurn(msg.sender, _amount);
bytes memory _message = abi.encodeCall(this.relayERC20, (_token, msg.sender, _to, _amount));
L2ToL2CrossDomainMessenger.sendMessage(_chainId, address(this), _message);
Expand All @@ -113,7 +159,7 @@ function relayERC20(SuperchainERC20 _token, address _from, address _to, uint256
uint256 _source = L2ToL2CrossChainMessenger.crossDomainMessageSource();
_token.mint(_to, _amount);
_token.__superchainMint(_to, _amount);
emit RelayERC20(address(_token), _from, _to, _amount, _source);
}
Expand Down Expand Up @@ -176,13 +222,15 @@ sequenceDiagram
from->>Intermediate_A: sendWithData(data)
Intermediate_A->>L2SBA: sendERC20To(tokenAddr, to, amount, chainID)
L2SBA->>SuperERC20_A: burn(from, amount)
L2SBA->>SuperERC20_A: __superchainBurn(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)
Intermediate_A->>Messenger_A: sendMessage(chainId, to, data)
Inbox->>Messenger_B: relayMessage()
Messenger_B->>L2SBB: relayERC20(tokenAddr, from, to, amount)
L2SBB->>SuperERC20_B: mint(to, amount)
L2SBB->>SuperERC20_B: __superchainMint(to, amount)
SuperERC20_B-->SuperERC20_B: emit SuperchainMint(to, amount)
Inbox->>Messenger_B: relayMessage(): call
L2SBB-->L2SBB: emit RelayedERC20(tokenAddr, from, to, amount, source)
Messenger_B->>to: call(data)
Expand Down

0 comments on commit 40a6a50

Please sign in to comment.