|
| 1 | +--- |
| 2 | +title: Creating custom SuperchainERC20 tokens |
| 3 | +lang: en-US |
| 4 | +description: Create SuperchainERC20 tokens with custom behaviors |
| 5 | +--- |
| 6 | + |
| 7 | +import { Callout } from 'nextra/components' |
| 8 | +import { Steps } from 'nextra/components' |
| 9 | + |
| 10 | +<Callout> |
| 11 | + The SuperchainERC20 standard is ready for production deployments. |
| 12 | + Please note that the OP Stack interoperability upgrade, required for crosschain messaging, is currently still in active development. |
| 13 | +</Callout> |
| 14 | + |
| 15 | +# Custom SuperchainERC20 tokens |
| 16 | + |
| 17 | +## Overview |
| 18 | + |
| 19 | +This guide explains how to modify the behavior of [`SuperchainERC20`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainERC20.sol) contracts to create custom tokens that can then be bridged quickly and safely using the [`SuperchainTokenBridge`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol) contract (once interop is operational). |
| 20 | +For more information on how it works, [see the explainer](/stack/interop/superchain-erc20). |
| 21 | + |
| 22 | +To ensure fungibility across chains, `SuperchainERC20` assets *must* have the same contract address on all chains. |
| 23 | +This requirement abstracts away the complexity of cross-chain validation. |
| 24 | +Achieving this requires deterministic deployment methods. There are [many ways to do this](https://github.com/Arachnid/deterministic-deployment-proxy). |
| 25 | +Here we will use the [SuperchainERC20 Starter Kit](/app-developers/starter-kit). |
| 26 | + |
| 27 | +### What you'll do |
| 28 | + |
| 29 | +* Use the [SuperchainERC20 Starter Kit](/app-developers/starter-kit) to deploy tokens with your custom code. |
| 30 | + |
| 31 | +### What you'll learn |
| 32 | + |
| 33 | +* How to deploy custom ERC-20 tokens on different chains at the same address so that they can be bridged with the [`SuperchainTokenBridge`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol) contract. |
| 34 | + |
| 35 | +## Prerequisites |
| 36 | + |
| 37 | +Before starting this tutorial, ensure your development environment meets the following requirements: |
| 38 | + |
| 39 | +### Technical knowledge |
| 40 | + |
| 41 | +* Understanding of smart contract development |
| 42 | +* Familiarity with blockchain concepts |
| 43 | +* Familiarity with [standard SuperchainERC20 deployments](./deploy-superchain-erc20). |
| 44 | + |
| 45 | +### Development environment |
| 46 | + |
| 47 | +* Unix-like operating system (Linux, macOS, or WSL for Windows) |
| 48 | +* Git for version control |
| 49 | + |
| 50 | +### Required tools |
| 51 | + |
| 52 | +The tutorial uses these primary tools: |
| 53 | + |
| 54 | +* Foundry: For sending transactions to blockchains. |
| 55 | + |
| 56 | +## Step by step explanation |
| 57 | + |
| 58 | +<Steps> |
| 59 | + ### Prepare for deployment |
| 60 | + |
| 61 | + 1. Follow the setup steps in the [SuperchainERC20 Starter Kit](/app-developers/starter-kit#setup). |
| 62 | + Don't start the development environment (step 5). |
| 63 | + |
| 64 | + 2. Follow [the deployment preparations steps](./deploy-superchain-erc20#prepare-for-deployment) in the issuing new assets page. |
| 65 | + Don't deploy the contracts yet. |
| 66 | + |
| 67 | + **Note:** Make sure to specify a previously unused value for the salt, for example your address and a timestamp. |
| 68 | + This is necessary because if the same constructor code is used with the same salt when using the deployment script, it gets the same address, which is a problem if you want a fresh deployment. |
| 69 | + |
| 70 | + ### Create the custom contract |
| 71 | + |
| 72 | + The easiest way to do this is to copy and modify the `L2NativeSuperchainERC20.sol` contract. |
| 73 | + Use this code, for example, as `packages/contracts/src/CustomSuperchainToken.sol`. |
| 74 | + |
| 75 | + ```solidity file=<rootDir>/public/tutorials/CustomSuperchainToken.sol hash=4ad95b9203ce523351eba0501f8b972d |
| 76 | + ``` |
| 77 | + |
| 78 | + <details> |
| 79 | + <summary>Explanation</summary> |
| 80 | + |
| 81 | + ```solidity file=<rootDir>/public/tutorials/CustomSuperchainToken.sol#L36-L38 hash=4e402ea88c9cd796500425172a6de16d |
| 82 | + ``` |
| 83 | + |
| 84 | + This function lets users get tokens for themselves. |
| 85 | + This token is for testing purposes, so it is useful for users to get their own tokens to run tests. |
| 86 | + </details> |
| 87 | + |
| 88 | + ### Deploy the new token |
| 89 | + |
| 90 | + 1. Edit `packages/contracts/scripts/SuperchainERC20Deployer.s.sol`: |
| 91 | + |
| 92 | + * Change line 6 to import the new token. |
| 93 | + |
| 94 | + ```solidity |
| 95 | + import {CustomSuperchainToken} from "../src/CustomSuperchainToken.sol"; |
| 96 | + ``` |
| 97 | + |
| 98 | + * Update lines 52-54 to get the `CustomSuperchainToken` initialization code. |
| 99 | + |
| 100 | + ```solidity |
| 101 | + bytes memory initCode = abi.encodePacked( |
| 102 | + type(CustomSuperchainToken).creationCode, abi.encode(ownerAddr_, name, symbol, uint8(decimals)) |
| 103 | + ); |
| 104 | + ``` |
| 105 | + |
| 106 | + * Modify line 62 to deploy a `CustomSuperchainToken` contract. |
| 107 | + |
| 108 | + ```solidity |
| 109 | + addr_ = address(new CustomSuperchainToken{salt: _implSalt()}(ownerAddr_, name, symbol, uint8(decimals))); |
| 110 | + ``` |
| 111 | + |
| 112 | + 2. Deploy the token contract. |
| 113 | + |
| 114 | + ```sh |
| 115 | + pnpm contracts:deploy:token |
| 116 | + ``` |
| 117 | + |
| 118 | + <details> |
| 119 | + <summary>Sanity check</summary> |
| 120 | + |
| 121 | + 1. Set `TOKEN_ADDRESS` to the address where the token is deployed. |
| 122 | + You can also play with the token I created, which is at address [`0xF3Ce0794cB4Ef75A902e07e5D2b75E4D71495ee8`](https://sid.testnet.routescan.io/address/0xF3Ce0794cB4Ef75A902e07e5D2b75E4D71495ee8). |
| 123 | + |
| 124 | + ```sh |
| 125 | + TOKEN_ADDRESS=0xF3Ce0794cB4Ef75A902e07e5D2b75E4D71495ee8 |
| 126 | + ``` |
| 127 | + |
| 128 | + 2. Source the `.env` file to get the private key and the address to which it corresponds. |
| 129 | + |
| 130 | + ```sh |
| 131 | + . packages/contracts/.env |
| 132 | + MY_ADDRESS=`cast wallet address $DEPLOYER_PRIVATE_KEY` |
| 133 | + ``` |
| 134 | + |
| 135 | + 3. Set variables for the RPC URLs. |
| 136 | + |
| 137 | + ```sh |
| 138 | + RPC_DEV0=https://interop-alpha-0.optimism.io |
| 139 | + RPC_DEV1=https://interop-alpha-1.optimism.io |
| 140 | + ``` |
| 141 | + |
| 142 | + 4. Get your current balance (it should be zero). |
| 143 | + |
| 144 | + ```sh |
| 145 | + cast call --rpc-url $RPC_DEV0 $TOKEN_ADDRESS "balanceOf(address)" $MY_ADDRESS | cast --from-wei |
| 146 | + ``` |
| 147 | + |
| 148 | + 5. Call the faucet to get a token and check the balance again. |
| 149 | + |
| 150 | + ```sh |
| 151 | + cast send --private-key $DEPLOYER_PRIVATE_KEY --rpc-url $RPC_DEV0 $TOKEN_ADDRESS "faucet()" |
| 152 | + cast call --rpc-url $RPC_DEV0 $TOKEN_ADDRESS "balanceOf(address)" $MY_ADDRESS | cast --from-wei |
| 153 | + ``` |
| 154 | + </details> |
| 155 | +</Steps> |
| 156 | + |
| 157 | +## How does this work? |
| 158 | + |
| 159 | +To allow for superchain interoperability, an ERC-20 token has to implement [ERC-7802](https://specs.optimism.io/interop/token-bridging.html#ierc7802). |
| 160 | +You can either use [the `SuperchainERC20` implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainERC20.sol#L26-L46), or write your own. |
| 161 | + |
| 162 | +For more details [see the explainer](../superchain-erc20). |
| 163 | + |
| 164 | +## Next steps |
| 165 | + |
| 166 | +* Use the [SuperchainERC20 Starter Kit](/app-developers/starter-kit) to deploy your token across the Superchain. |
| 167 | +* Explore the [SuperchainERC20 specifications](https://specs.optimism.io/interop/token-bridging.html) for in-depth implementation details. |
| 168 | +* Review the [Superchain Interop Explainer](../explainer) for answers to common questions about interoperability. |
0 commit comments