forked from ethereum-optimism/optimism
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add superchain erc20 bridge (#61)
* feat: add superchain erc20 bridge * fix: interfaces and versions
- Loading branch information
Showing
14 changed files
with
317 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
155 changes: 155 additions & 0 deletions
155
packages/contracts-bedrock/snapshots/abi/SuperchainERC20Bridge.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
[ | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "address", | ||
"name": "_token", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "address", | ||
"name": "_from", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "address", | ||
"name": "_to", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_amount", | ||
"type": "uint256" | ||
} | ||
], | ||
"name": "relayERC20", | ||
"outputs": [], | ||
"stateMutability": "nonpayable", | ||
"type": "function" | ||
}, | ||
{ | ||
"inputs": [ | ||
{ | ||
"internalType": "address", | ||
"name": "_token", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "address", | ||
"name": "_to", | ||
"type": "address" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_amount", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"internalType": "uint256", | ||
"name": "_chainId", | ||
"type": "uint256" | ||
} | ||
], | ||
"name": "sendERC20", | ||
"outputs": [], | ||
"stateMutability": "nonpayable", | ||
"type": "function" | ||
}, | ||
{ | ||
"inputs": [], | ||
"name": "version", | ||
"outputs": [ | ||
{ | ||
"internalType": "string", | ||
"name": "", | ||
"type": "string" | ||
} | ||
], | ||
"stateMutability": "view", | ||
"type": "function" | ||
}, | ||
{ | ||
"anonymous": false, | ||
"inputs": [ | ||
{ | ||
"indexed": true, | ||
"internalType": "address", | ||
"name": "token", | ||
"type": "address" | ||
}, | ||
{ | ||
"indexed": true, | ||
"internalType": "address", | ||
"name": "from", | ||
"type": "address" | ||
}, | ||
{ | ||
"indexed": true, | ||
"internalType": "address", | ||
"name": "to", | ||
"type": "address" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "amount", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "source", | ||
"type": "uint256" | ||
} | ||
], | ||
"name": "RelayERC20", | ||
"type": "event" | ||
}, | ||
{ | ||
"anonymous": false, | ||
"inputs": [ | ||
{ | ||
"indexed": true, | ||
"internalType": "address", | ||
"name": "token", | ||
"type": "address" | ||
}, | ||
{ | ||
"indexed": true, | ||
"internalType": "address", | ||
"name": "from", | ||
"type": "address" | ||
}, | ||
{ | ||
"indexed": true, | ||
"internalType": "address", | ||
"name": "to", | ||
"type": "address" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "amount", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "destination", | ||
"type": "uint256" | ||
} | ||
], | ||
"name": "SendERC20", | ||
"type": "event" | ||
}, | ||
{ | ||
"inputs": [], | ||
"name": "CallerNotL2ToL2CrossDomainMessenger", | ||
"type": "error" | ||
}, | ||
{ | ||
"inputs": [], | ||
"name": "InvalidCrossDomainSender", | ||
"type": "error" | ||
} | ||
] |
1 change: 1 addition & 0 deletions
1
packages/contracts-bedrock/snapshots/storageLayout/SuperchainERC20Bridge.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
packages/contracts-bedrock/src/L2/SuperchainERC20Bridge.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.25; | ||
|
||
// Libraries | ||
import { Predeploys } from "src/libraries/Predeploys.sol"; | ||
|
||
// Interfaces | ||
import { ISuperchainERC20Bridge } from "src/L2/interfaces/ISuperchainERC20Bridge.sol"; | ||
import { IMintableAndBurnableERC20 } from "src/L2/interfaces/IMintableAndBurnableERC20.sol"; | ||
import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; | ||
|
||
/// @custom:proxied true | ||
/// @custom:predeploy 0x4200000000000000000000000000000000000028 | ||
/// @title SuperchainERC20Bridge | ||
/// @notice The SuperchainERC20Bridge allows for the bridging of ERC20 tokens to make them fungible across the | ||
/// Superchain. It builds on top of the L2ToL2CrossDomainMessenger for both replay protection and domain | ||
/// binding. | ||
contract SuperchainERC20Bridge is ISuperchainERC20Bridge { | ||
/// @notice Address of the L2ToL2CrossDomainMessenger Predeploy. | ||
address internal constant MESSENGER = Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER; | ||
|
||
/// @notice Semantic version. | ||
/// @custom:semver 1.0.0-beta.1 | ||
string public constant version = "1.0.0-beta.1"; | ||
|
||
/// @notice Sends tokens to some target address on another chain. | ||
/// @param _token Token to send. | ||
/// @param _to Address to send tokens to. | ||
/// @param _amount Amount of tokens to send. | ||
/// @param _chainId Chain ID of the destination chain. | ||
function sendERC20(address _token, address _to, uint256 _amount, uint256 _chainId) external { | ||
IMintableAndBurnableERC20(_token).burn(msg.sender, _amount); | ||
|
||
bytes memory message = abi.encodeCall(this.relayERC20, (_token, msg.sender, _to, _amount)); | ||
IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), message); | ||
|
||
emit SendERC20(_token, msg.sender, _to, _amount, _chainId); | ||
} | ||
|
||
/// @notice Relays tokens received from another chain. | ||
/// @param _token Token to relay. | ||
/// @param _from Address of the msg.sender of sendERC20 on the source chain. | ||
/// @param _to Address to relay tokens to. | ||
/// @param _amount Amount of tokens to relay. | ||
function relayERC20(address _token, address _from, address _to, uint256 _amount) external { | ||
if (msg.sender != MESSENGER) revert CallerNotL2ToL2CrossDomainMessenger(); | ||
|
||
if (IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSender() != address(this)) { | ||
revert InvalidCrossDomainSender(); | ||
} | ||
|
||
uint256 source = IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSource(); | ||
|
||
IMintableAndBurnableERC20(_token).mint(_to, _amount); | ||
|
||
emit RelayERC20(_token, _from, _to, _amount, source); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
packages/contracts-bedrock/src/L2/interfaces/IMintableAndBurnableERC20.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
|
||
/// @title IMintableAndBurnableERC20 | ||
/// @notice Interface for mintable and burnable ERC20 tokens. | ||
interface IMintableAndBurnableERC20 is IERC20 { | ||
/// @notice Mints `_amount` of tokens to `_to`. | ||
/// @param _to Address to mint tokens to. | ||
/// @param _amount Amount of tokens to mint. | ||
function mint(address _to, uint256 _amount) external; | ||
|
||
/// @notice Burns `_amount` of tokens from `_from`. | ||
/// @param _from Address to burn tokens from. | ||
/// @param _amount Amount of tokens to burn. | ||
function burn(address _from, uint256 _amount) external; | ||
} |
Oops, something went wrong.