-
Notifications
You must be signed in to change notification settings - Fork 267
custom-gas-token #665
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
custom-gas-token #665
Changes from all commits
de63455
1e1c67f
ce6f702
d2f0f77
29d7fc5
b828112
872a566
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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. | ||||||
|
||||||
<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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
|
||||||
|
||||||
<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` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
|
||||||
|
||||||
* 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 | ||||||
K-Ho marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
* 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 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
|
||||||
|
||||||
### 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 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
|
||||||
* `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> | ||||||
|
||||||
K-Ho marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
## 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). |
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" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"custom-gas-token": "Custom Gas Token" | ||
} |
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
|
||||||
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 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
|
||||||
* 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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Suggested change
|
There was a problem hiding this comment.
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.
Committable suggestion