Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Callout, Steps } from 'nextra/components'
# Bridging Your Custom ERC-20 Token Using the Standard Bridge

<Callout type="info">
**This tutorial is for developers who want to bridge a new ERC-20 token to an OP Stack chain.**
**This tutorial is for developers who want to bridge a new ERC-20 token to an OP Stack chain. This is not related to the "Custom Gas Token" feature for new OP Stack chains**
If you want to bridge existing tokens, you can skip to the tutorial on [Bridging ERC-20 tokens with the Optimism SDK](./cross-dom-bridge-erc20).
</Callout>

Expand Down
1 change: 1 addition & 0 deletions pages/builders/chain-operators/management/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"configuration": "Configuration",
"blobs": "Using Blobs",
"snap-sync": "Using Snap Sync",
"custom-gas-token": "Run a Custom Gas Token Chain",
"operations": "Node Operations",
"key-management": "Key Management",
"troubleshooting": "Troubleshooting"
Expand Down
157 changes: 157 additions & 0 deletions pages/builders/chain-operators/management/custom-gas-token.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
---
title: How to Run a Custom Gas Token Chain
lang: en-US
description: Learn how to run a custom gas token chain.
---

import { Callout, Steps } from 'nextra/components'

# How to Run a Custom Gas Token Chain

<Callout type="warning">
The Custom Gas Token feature is a Beta feature of the MIT licensed OP Stack. While it has received initial review from core contributors, it is still undergoing testing, and may have bugs or other issues.
</Callout>

This guide provides a walkthrough for chain operators who want to run a custom gas token chain. See the [Custom Gas Token Explainer](/stack/protocol/features/custom-gas-token) for a general overview of this OP Stack feature.
An OP Stack chain that uses the custom gas token feature enables an end user to deposit an L1 native ERC20 token into L2 where that asset is minted as the native L2 asset and can be used to pay for gas on L2.
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a comma for correct punctuation.

- an L1 native ERC20 token into L2 where
+ an L1 native ERC20 token into L2, where

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
An OP Stack chain that uses the custom gas token feature enables an end user to deposit an L1 native ERC20 token into L2 where that asset is minted as the native L2 asset and can be used to pay for gas on L2.
An OP Stack chain that uses the custom gas token feature enables an end user to deposit an L1 native ERC20 token into L2, where that asset is minted as the native L2 asset and can be used to pay for gas on L2.


<Steps>
### Deploying Your Contracts

* Checkout the [`v2.0.0-beta.1` of the contracts](https://github.com/ethereum-optimism/optimism/tree/op-contracts/v2.0.0-beta.1) and use the commit to deploy.
Copy link
Contributor

Choose a reason for hiding this comment

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

Clarify the sentence structure.

- Checkout the [`v2.0.0-beta.1` of the contracts](https://github.com/ethereum-optimism/optimism/tree/op-contracts/v2.0.0-beta.1) and use the commit to deploy.
+ Check out the [`v2.0.0-beta.1` of the contracts](https://github.com/ethereum-optimism/optimism/tree/op-contracts/v2.0.0-beta.1) and use the commit to deploy.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
* Checkout the [`v2.0.0-beta.1` of the contracts](https://github.com/ethereum-optimism/optimism/tree/op-contracts/v2.0.0-beta.1) and use the commit to deploy.
* Check out the [`v2.0.0-beta.1` of the contracts](https://github.com/ethereum-optimism/optimism/tree/op-contracts/v2.0.0-beta.1) and use the commit to deploy.


<Callout type="error">
Be sure to check out this tag or you will not deploy a chain that uses custom gas token!
</Callout>

* Update the deploy config in `contracts-bedrock/deploy-config` with new fields: `useCustomGasToken` and `customGasTokenAddress`
Copy link
Contributor

Choose a reason for hiding this comment

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

Clarify the term usage.

- Update the deploy config
+ Update the deployment config

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
* Update the deploy config in `contracts-bedrock/deploy-config` with new fields: `useCustomGasToken` and `customGasTokenAddress`
* Update the deployment config in `contracts-bedrock/deploy-config` with new fields: `useCustomGasToken` and `customGasTokenAddress`


* Set `useCustomGasToken` to `true`. If you set `useCustomGasToken` to `false` (it defaults this way), then it will use ETH as the gas paying token.

* Set `customGasTokenAddress` to the contract address of an L1 ERC20 token you wish to use as the gas token on your L2. The ERC20 should already be deployed before trying to spin up the custom gas token chain.

The custom gas token being set must meet the following criteria:

* must be a valid ERC-20 token
* the number of decimals on the token MUST be exactly 18
* the name of the token MUST be less than or equal to 32 bytes
* symbol MUST be less than or equal to 32 bytes.
* must not be yield-bearing
* cannot be rebasing or have a transfer fee
* must be transferrable only via a call to the token address itself
* must only be able to set allowance via a call to the token address itself
* must not have a callback on transfer, and more generally a user must not be able to make a transfer to themselves revert
* a user must not be able to make a transfer have unexpected side effects

<Callout type="warning">
You will NOT be able to change the address of the custom gas token after it is set during deployment.
</Callout>

* Deploy the L1 contracts from `contracts-bedrock` using the following command:

```bash
DEPLOYMENT_OUTFILE=deployments/artifact.json \
DEPLOY_CONFIG_PATH=<PATH_TO_MY_DEPLOY_CONFIG> \
forge script scripts/Deploy.s.sol:Deploy \
--broadcast --private-key $PRIVATE_KEY \
--rpc-url $ETH_RPC_URL
```

* `DEPLOYMENT_OUTFILE` is the path to the file at which the L1 contract deployment artifacts are written to after deployment. Foundry has filesystem restrictions for security, so make this file a child of the `deployments` directory. This file will contain key/value pairs of the names and addresses of the deployed contracts.
* `DEPLOY_CONFIG_PATH` is the path to the file for the deploy config used to deploy
Copy link
Contributor

Choose a reason for hiding this comment

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

Clarify the term usage.

- the deploy config used to deploy
+ the deployment config used to deploy

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
* `DEPLOY_CONFIG_PATH` is the path to the file for the deploy config used to deploy
* `DEPLOY_CONFIG_PATH` is the path to the file for the deployment config used to deploy


### Generating L2 Allocs

<Callout type="info">
Be sure to use the same tag that you used to deploy the L1 contracts.
</Callout>

A forge script is used to generate the L2 genesis. It is a requirement that the L1 contracts have been deployed before generating the L2 genesis, since some L1 contract addresses are embedded into the L2 genesis.

```bash
CONTRACT_ADDRESSES_PATH=deployments/artifact.json \
DEPLOY_CONFIG_PATH=<PATH_TO_MY_DEPLOY_CONFIG> \
STATE_DUMP_PATH=<PATH_TO_WRITE_L2_ALLOCS> \
forge script scripts/L2Genesis.s.sol:L2Genesis \
--sig 'runWithStateDump()' --chain-id $L2_CHAIN_ID
```

To generate L2 Allocs, it is assumed that:

* You have the L1 contracts artifact, specified with `DEPLOYMENT_OUTFILE`
* `CONTRACT_ADDRESSES_PATH` is the path to the deployment artifact from deploying the L1 contracts in the first step, aka `DEPLOYMENT_OUTFILE`
* `DEPLOY_CONFIG_PATH` is the path to the file for the deploy config used to deploy
Copy link
Contributor

Choose a reason for hiding this comment

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

Clarify the term usage.

- the deploy config used to deploy
+ the deployment config used to deploy

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
* `DEPLOY_CONFIG_PATH` is the path to the file for the deploy config used to deploy
* `DEPLOY_CONFIG_PATH` is the path to the file for the deployment config used to deploy

* `STATE_DUMP_PATH` is a path to the generated L2 allocs file, this is the genesis state and is required for the next step.

### Generating L2 Genesis

The `op-node` is used to generate the final L2 genesis file. It takes the allocs created by the forge script as input for the `--l2-allocs` flag.

```bash
op-node genesis l2 \
--l1-rpc $ETH_RPC_URL \
--deploy-config <PATH_TO_MY_DEPLOY_CONFIG> \
--l2-allocs <PATH_TO_L2_ALLOCS> \
--l1-deployments <PATH_TO_L1_DEPLOY_ARTIFACT> \
--outfile.l2 <PATH_TO_WRITE_L2_GENESIS> \
--outfile.rollup <PATH_TO_WRITE_OP_NODE_CONFIG>
```

### Spinning Up Your Infrastructure

Ensure that the end to end system is running.

### Validating your deployment

This calls the `WETH` predeploy which should be considered wrapped native asset in the context of custom gas token. It should return the name of the token prefixed by `"Wrapped "`

```bash
cast call --rpc-url $L2_ETH_RPC_URL 0x4200000000000000000000000000000000000006 'name()(string)'
```

This calls the `L1Block` predeploy should return `true`.

```bash
cast call --rpc-url $L2_ETH_RPC_URL 0x4200000000000000000000000000000000000015 'isCustomGasToken()(bool)
```

This calls the L1 `SystemConfig` contract and should return `true`.

```bash
cast call --rpc-url $L1_ETH_RPC_URL <SYSTEM_CONFIG_ADDRESS> 'isCustomGasToken()(bool)
```

### Depositing Custom Gas Token into the Chain

* To deposit the custom gas token into the chain, users must use the **`OptimismPortalProxy.depositERC20Transaction`** method
* Users MUST first `approve()` the `OptimismPortal` before they can deposit tokens using `depositERC20Transaction`.

```
function depositERC20Transaction(
address _to,
uint256 _mint,
uint256 _value,
uint64 _gasLimit,
bool _isCreation,
bytes memory _data
) public;
```

### Withdrawing Custom Gas Tokens out of the Chain

* To withdraw your native custom gas token from the chain, users must use the **`L2ToL1MessagePasser.initiateWithdrawal`** method. Proving and finalizing withdrawals is identical to the process on chains that use ETH as the native gas token.

```
function initiateWithdrawal(
address _target,
uint256 _gasLimit,
bytes memory _data
) public payable;
```
</Steps>

## Next Steps

* Additional questions? See the FAQ section in the [Custom Gas Token Explainer](/stack/protocol/features/custom-gas-token#faqs).
* For more detailed info on custom gas tokens, see the [specs](https://specs.optimism.io/protocol/granite/custom-gas-token.html).
* If you experience any problems, please reach out to [developer support](https://github.com/ethereum-optimism/developers/discussions).
1 change: 1 addition & 0 deletions pages/stack/protocol/_meta.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"rollup": "Rollup",
"fault-proofs": "Fault Proofs",
"features": "Features",
"outages": "Sequencer Outages"
}
3 changes: 3 additions & 0 deletions pages/stack/protocol/features/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"custom-gas-token": "Custom Gas Token"
}
93 changes: 93 additions & 0 deletions pages/stack/protocol/features/custom-gas-token.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title: Custom Gas Token Explainer
lang: en-US
description: Learn the basic process, benefits, and considerations for running a custom gas token chain.
---

import { Callout } from 'nextra/components'

# Custom Gas Token Explainer

The Custom Gas Token configuration lets OP Stack chain operators deploy their chain allowing a specific ERC-20 token to be deposited in as the native token to pay for gas fees. Chain operators can now customize their gas token to:

* provide utility for their project's token
* make it easier to subsidize gas costs for their users directly via their token treasury
* facilitate in-game economies, allowing players to pay for gas with their in-game currency
* build alignment with the community of any token.

## Native Gas Tokens

By default, L2 OP Stack chains allow users to deposit ETH from L1 into the L2 chain as native L2 token that can then be used to pay for gas fees.
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider adding an article for clarity.

- as native L2 token
+ as the native L2 token

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
By default, L2 OP Stack chains allow users to deposit ETH from L1 into the L2 chain as native L2 token that can then be used to pay for gas fees.
By default, L2 OP Stack chains allow users to deposit ETH from L1 into the L2 chain as the native L2 token that can then be used to pay for gas fees.

Chain operators wanted to configure the stack to use a custom token to pay for gas, other than ETH.

With custom gas tokens, chain operators can now set an L1 ERC-20 token address at the time of deploying the contracts of their L2 chain.
When deposited, this L1 ERC-20 token will become the native gas token on the L2 and can be used to pay for gas fees.

<Callout type="warning">
**Caveats chain operators should be aware of:**

* You cannot switch from your custom gas token to another token after the chain is launched.
* Existing chains cannot switch to use a custom gas token. A custom token must be configured at the time of chain deployment.
* You will need to manually modify your fee configuration values to properly charge fees for users.
* Understand the [constraints required for your chain to be able to join the Superchain](#considerations) when setting the custom gas token for your chain.
</Callout>

## How It Works

This is the general flow of how custom gas tokens work on the OP Stack:

* On deployment of an L2 chain, set the address of an L1 token to be used as the gas token.
* When depositing the custom gas token to L2, it mints the native L2 token.
* Withdrawing the native L2 token results in the unlocking of the custom token on L1.
* The native L2 token is used by default to pay for gas fees.

## Benefits

Chain operators get the following benefits by using custom gas tokens:

* can use an L1 ERC-20 token as the custom gas token for L2 OP Stack chain deployment
* can use an ERC-20 token on an existing L2 OP Stack chain as as the custom gas token for an L3 OP Stack chain deployment
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove duplicate word for correct grammar.

- as as the custom gas token
+ as the custom gas token

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
* can use an ERC-20 token on an existing L2 OP Stack chain as as the custom gas token for an L3 OP Stack chain deployment
* can use an ERC-20 token on an existing L2 OP Stack chain as the custom gas token for an L3 OP Stack chain deployment

* can use custom gas tokens with other configurations of the OP Stack, including Plasma Mode.

## Considerations

The custom token being used must adhere to the following constraints to be able to join the Superchain:

* must be a valid ERC-20 token
* the number of decimals on the token MUST be exactly 18
* the name of the token MUST be less than or equal to 32 bytes
* symbol MUST be less than or equal to 32 bytes.
* must not be yield-bearing
* cannot be rebasing or have a transfer fee
* must be transferrable only via a call to the token address itself
* must only be able to set allowance via a call to the token address itself
* must not have a callback on transfer, and more generally a user must not be able to make a transfer to themselves revert
* a user must not be able to make a transfer have unexpected side effects



## Next Steps

* Ready to get started? Read our guide on how to [deploy your custom gas token chain](/builders/chain-operators/management/custom-gas-token).
* For more info about how the custom gas token feature works under the hood, [check out the specs](https://specs.optimism.io/protocol/granite/custom-gas-token.html).

## FAQs

### What is the Wrapped (ERC-20) Gas Token?

* The `WETH` predeploy at `0x4200000000000000000000000000000000000006` represents the wrapped custom gas token. If you wish to transact with your native gas token as an ERC-20, you can `deposit` and `withdraw` from this contract to wrap and unwrap your token.
* What this means is the asset at the `WETH` predeploy is not `ether` but instead is the wrapped version of your custom gas token. Its an ERC20 token, the `name()` will be `"Wrapped ..."` (whatever the name of your token is).

### How do I charge fees as the chain operator?

The initial release of custom gas token does not have special logic for taking into account the exchange rate between the custom gas token and ether. Currently, the protocol charges fees for users with scalars on the L1 blob fee and L1 base fee in ETH. Chain operator will be taking user fees in the custom gas token and spending in ether.

For the initial release of custom gas token, the chain operator will need to manage this either out of band or by manually tuning the fee scalar values to capture the exchange rate between ETH and the custom gas token to ensure profitability. A future release may include [L1 Fee Abstraction](https://github.com/ethereum-optimism/specs/issues/73) where the L1 fee is calculated in a smart contract instead of native code. This would enable an on chain oracle to take into account the exchange rate of the custom gas token.

### Can I migrate my chain into being custom gas token?

If you are already live using `ether` to pay for gas, you cannot become a custom gas token chain. This would likely require a risky, high lift state migration that we would not recommend.

### Do node operators need to do anything?

There are no core changes to `op-geth` or `op-node` so the infrastructure that node operators run is exactly the same as any other OP Stack based chain. The differences are encapsulated in the smart contracts, so only the L1 contract deployments and L2 genesis generation need to be done in a particular way.
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a hyphen for correct spelling.

- OP Stack based chain
+ OP Stack-based chain

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
There are no core changes to `op-geth` or `op-node` so the infrastructure that node operators run is exactly the same as any other OP Stack based chain. The differences are encapsulated in the smart contracts, so only the L1 contract deployments and L2 genesis generation need to be done in a particular way.
There are no core changes to `op-geth` or `op-node` so the infrastructure that node operators run is exactly the same as any other OP Stack-based chain. The differences are encapsulated in the smart contracts, so only the L1 contract deployments and L2 genesis generation need to be done in a particular way.

4 changes: 3 additions & 1 deletion words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ accountslots
ADDI
ADDIU
ADDU
Allocs
allocs
ANDI
Apeworx
Expand Down Expand Up @@ -134,7 +135,6 @@ journalremotes
JSPATH
jspath
jwtsecret
leadup
leveldb
lightkdf
logfile
Expand Down Expand Up @@ -299,9 +299,11 @@ tility
timeseries
trustlessly
trustrpc
TWAP
txfeecap
TXPOOL
txpool
undercollateralized
Unprotect
unsubmitted
UPNP
Expand Down