SuperchainERC20
is an implementation of ERC-7802 designed to enable asset interoperability in the Superchain.
SuperchainERC20
tokens are fungible across the Superchain by giving the SuperchainERC20Bridge
permission to mint and burn the token during cross-chain transfers. For more information on SuperchainERC20 please visit the docs.
Note: ERC20 tokens that do not utilize the SuperchainERC20Bridge
for cross-chain transfers can still achieve fungibility across the Superchain through interop message passing with a custom bridge solution. For these custom tokens, implementing ERC-7802 is strongly recommended, as it unifies cross-chain mint and burn interfaces, enabling tokens to benefit from a standardized approach to cross-chain transfers.
To achieve cross-chain functionality, the SuperchainERC20
standard incorporates the IERC7802
interface, defining essential functions and events:
crosschainMint
: Mints tokens on the destination chain as part of a cross-chain transfer.crosschainBurn
: Burns tokens on the source chain to facilitate the transfer.- Events (
CrosschainMint
andCrosschainBurn
): Emit when tokens are minted or burned, enabling transparent tracking of cross-chain transactions.
supersim
requires anvil
to be installed.
Follow this guide to install Foundry.
git clone [email protected]:ethereum-optimism/superchainerc20-starter.git
cd superchainerc20-starter
pnpm i
pnpm init:env
This command will:
- Start the
supersim
local development environment - Deploy the smart contracts to the test networks
- Launch the example frontend application
pnpm dev
This repository includes a script to automatically fetch the public RPC URLs for each chain listed in the Superchain Registry and add them to the [rpc_endpoints]
configuration section of foundry.toml
.
The script ensures that only new RPC URLs are appended, preserving any URLs already present in foundry.toml
. To execute this script, run:
pnpm contracts:update:rpcs
The deployment configuration for token deployments is managed through the deploy-config.toml
file. Below is a detailed breakdown of each configuration section:
This section defines parameters for deploying token contracts.
salt
: A unique identifier used for deploying token contracts via [Create2
]. This value along with the contract bytecode ensures that contract deployments are deterministic.- example:
salt = "ethers phoenix"
- example:
chains
: Lists the chains where the token will be deployed. Each chain must correspond to an entry in the[rpc_endpoints]
section offoundry.toml
.- example:
chains = ["op_chain_a","op_chain_b"]
- example:
Deployment configuration for the token that will be deployed.
owner_address
: the address designated as the owner of the token.- The
L2NativeSuperchainERC20.sol
contract included in this repo extends theOwnable
contract - example:
owner_address = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
- The
name
: the token's name.- example:
name = "TestSuperchainERC20"
- example:
symbol
: the token's symbol.- example:
symbol = "TSU"
- example:
decimals
: the number of decimal places the token supports.- example:
decimals = 18
- example:
Before proceeding with this section, ensure that your deploy-config.toml
file is fully configured (see the Deployment config section for more details on setup). Additionally, confirm that the [rpc_endpoints]
section in foundry.toml
is properly set up by following the instructions in Configuring RPC urls.
Deployments are executed through the SuperchainERC20Deployer.s.sol
script. This script deploys tokens across each specified chain in the deployment configuration using Create2
, ensuring deterministic contract addresses for each deployment. The script targets the L2NativeSuperchainERC20.sol
contract by default. If you need to modify the token being deployed, either update this file directly or point the script to a custom token contract of your choice.
To execute a token deployment run:
pnpm contracts:deploy:token
Create2
ensures that the address is deterministically determined by the bytecode of the contract and the provided salt. This is crucial because in order for cross-chain transfers of SuperchainERC20
s to work with interop, the tokens must be deployed at the same address across all chains.
For best security practices SuperchainERC20Bridge
should be the only contract with permission to call crosschainMint
and crosschainBurn
. These permissions are set up by default when using the SuperchainERC20
contract.
The packages/e2e-test
directory contains simple end-to-end integration tests using vitest
that run against supersim
Before running the tests, ensure you have:
- Completed all steps in the Getting Started section
- Initialized your environment variables (
pnpm init:env
)
pnpm e2e-test
The tests will run against your local supersim instance.
Note: Interop is currently in active development and not yet ready for production use. This example uses supersim in order to demonstrate how cross-chain transfers will work once interop is live.
Note: this example uses a pre-funded test account provided by anvil for all transactions and as the owner of the L2NativeSuperchainERC20
. The address of this account is 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
and private key is 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
1. Follow the steps in the Getting started section.
After completing these steps, you will have the following set up:
supersim
running in autorelay mode with two L2 chains- The
L2NativeSuperchainERC20
token deployed on both chains
2. Find the address and owner of the L2NativeSuperchainERC20 token that was deployed.
The address that the token in step 1 was deployed to and the address of the owner of the token can be found in the deployment.json file under the "deployedAddress"
and "ownerAddress"
fields. The deployedAddress
address will be used for any token interactions in the next steps and the private key of the ownerAddress
will need to be used for step 3 since minting requires owner privileges. In this example deployment.json
file the token in step 1 was deployed at 0x5BCf71Ca0CE963373d917031aAFDd6D98B80B159
and the owner address is 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
:
# example
{
"deployedAddress": "0x5BCf71Ca0CE963373d917031aAFDd6D98B80B159",
"ownerAddress": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
}
3. Mint tokens to transfer on chain 901
The following command creates a transaction using cast
to mint 1000 L2NativeSuperchainERC20
tokens. Replace <deployed-token-address>
with the deployedAddress
from deployment.json, replace <recipient-address>
with the address you would like to send the tokens to, and replace <owner-address-private-key>
with the private key of the ownerAddress
from step deployment.json.
cast send <deployed-token-address> "mintTo(address _to, uint256 _amount)" <recipient-address> 1000 --rpc-url http://127.0.0.1:9545 --private-key <owner-address-private-key>
4. Initiate the send transaction on chain 901
Send the tokens from Chain 901 to Chain 902 by calling SendERC20
on the SuperchainTokenBridge
. The SuperchainTokenBridge
is an OP Stack predeploy and can be located at address 0x4200000000000000000000000000000000000028
. Replace <deployed-token-address>
with the deployedAddress
from deployment.json, replace <recipient-address>
with the address you would like to send the tokens to, and replace <token-sender-private-key>
with the private key of the recipient address from step 3.
cast send 0x4200000000000000000000000000000000000028 "sendERC20(address _token, address _to, uint256 _amount, uint256 _chainId)" <deployed-token-address> <recipient-address> 1000 902 --rpc-url http://127.0.0.1:9545 --private-key <token-sender-private-key>
5. Wait for the relayed message to appear on chain 902
In a few seconds, you should see the RelayedMessage on chain 902:
# example
INFO [11-01|16:02:25.089] SuperchainTokenBridge#RelayERC20 token=0x5BCf71Ca0CE963373d917031aAFDd6D98B80B159 from=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 to=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 amount=1000 source=901
6. Check the balance on chain 902
Verify that the balance for the recipient of the L2NativeSuperchainERC20
on chain 902 has increased:
cast balance --erc20 <deployed-token-address> <recipient-address> --rpc-url http://127.0.0.1:9546
Contributions are encouraged, but please open an issue before making any major changes to ensure your changes will be accepted.
Files are licensed under the MIT license.