-
Notifications
You must be signed in to change notification settings - Fork 312
docs: add Custom Gas Token v2 documentation #1914
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
Open
sbvegan
wants to merge
5
commits into
mintlify
Choose a base branch
from
sb/cgt-updates
base: mintlify
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
1463390
docs: add Custom Gas Token v2 documentation
sbvegan 333bd3a
Merge branch 'mintlify' into sb/cgt-updates
sbvegan 1e45e1a
addressing Wonderland comments
sbvegan 1fd2cfd
cleaning up the guide
sbvegan c92e3da
Merge branch 'mintlify' into sb/cgt-updates
sbvegan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
257 changes: 257 additions & 0 deletions
257
chain-operators/guides/features/custom-gas-token-guide.mdx
This file contains hidden or 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,257 @@ | ||
| --- | ||
| title: Deploy a Custom Gas Token chain | ||
| description: Learn how to deploy a Custom Gas Token chain using OP Deployer. | ||
| --- | ||
|
|
||
| This guide provides instructions for chain operators who want to deploy a Custom Gas Token (CGT) chain. | ||
| See the [Custom Gas Token overview](/op-stack/features/custom-gas-token) for a general understanding of this OP Stack feature. | ||
|
|
||
| A Custom Gas Token chain enables you to use any asset as the native fee currency instead of ETH. | ||
| This asset may be an existing L1 token, a representation of a token from another chain, or a newly defined asset (or new L2 token) created at genesis. | ||
|
|
||
| <Warning> | ||
| Custom Gas Token v2 is a new implementation that is not compatible with legacy CGT chains. | ||
| There is currently no migration path from legacy CGT to CGT v2, though one is planned to be put together. | ||
| </Warning> | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| Before deploying a CGT chain, ensure you have: | ||
|
|
||
| todo: provide op-deployer release version | ||
| * **OP Deployer installed**: See [OP Deployer installation](/chain-operators/tools/op-deployer/installation) for setup instructions | ||
| * **L1 RPC endpoint**: Access to an Ethereum L1 node for deployment | ||
| * **Funded deployer account**: ETH for L1 gas costs during deployment | ||
| * **Token design**: Clear plan for your native asset (supply, distribution, bridging mechanism) | ||
| * **Security audit**: Thorough review of any authorized minters or bridge contracts you plan to deploy | ||
|
|
||
| ## Deployment steps | ||
|
|
||
| Deploying a CGT chain follows the standard OP Stack deployment process with additional configuration for Custom Gas Token specific parameters. | ||
|
|
||
| <Steps> | ||
| <Step title="Initialize your intent file"> | ||
| Create a new intent file using OP Deployer's [init command](/chain-operators/tools/op-deployer/usage/init): | ||
|
|
||
| ```bash | ||
| op-deployer init \ | ||
| --l1-chain-id <chain ID of your L1> \ | ||
| --l2-chain-ids <comma separated list of chain IDs for your L2s> \ | ||
| --intent-type custom | ||
| ``` | ||
|
|
||
| This creates an `intent.toml` file. | ||
| </Step> | ||
|
|
||
| <Step title="Configure Custom Gas Token parameters"> | ||
| Open your `intent.toml` file and add the Custom Gas Token configuration. Below is an example with CGT-specific fields: | ||
|
|
||
| ```toml | ||
| configType = "custom" | ||
| l1ChainID = 11155111 | ||
| fundDevAccounts = false | ||
| useInterop = false | ||
| l1ContractsLocator = "tag://op-contracts/v6.0.0" | ||
| l2ContractsLocator = "tag://op-contracts/v6.0.0" | ||
|
|
||
| [superchainRoles] | ||
| SuperchainProxyAdminOwner = "0xYourMultisigAddress" | ||
| SuperchainGuardian = "0xYourMultisigAddress" | ||
| ProtocolVersionsOwner = "0xYourMultisigAddress" | ||
| Challenger = "0xYourMultisigAddress" | ||
|
|
||
| [[chains]] | ||
| id = "0x0000000000000000000000000000000000000000000000000000000000001234" | ||
| baseFeeVaultRecipient = "0xYourFeeRecipientAddress" | ||
| l1FeeVaultRecipient = "0xYourFeeRecipientAddress" | ||
| sequencerFeeVaultRecipient = "0xYourFeeRecipientAddress" | ||
| operatorFeeVaultRecipient = "0xYourFeeRecipientAddress" | ||
| eip1559DenominatorCanyon = 0 | ||
| eip1559Denominator = 0 | ||
| eip1559Elasticity = 0 | ||
| gasLimit = 60000000 | ||
| operatorFeeScalar = 0 | ||
| operatorFeeConstant = 0 | ||
| chainFeesRecipient = "0x0000000000000000000000000000000000000000" | ||
| minBaseFee = 0 | ||
| daFootprintGasScalar = 0 | ||
|
|
||
| [chains.roles] | ||
| l1ProxyAdminOwner = "0xYourMultisigAddress" | ||
| l2ProxyAdminOwner = "0xYourMultisigAddress" | ||
| systemConfigOwner = "0xYourMultisigAddress" | ||
| unsafeBlockSigner = "0xYourSequencerAddress" | ||
| batcher = "0xYourBatcherAddress" | ||
| proposer = "0xYourProposerAddress" | ||
| challenger = "0xYourChallengerAddress" | ||
|
|
||
| [chains.customGasToken] | ||
| name = "My Custom Token" | ||
| symbol = "MCT" | ||
| initialLiquidity = "0x..." # optional, default: type(uint248).max | ||
| liquidityControllerOwner = "0x..." # optional, default: L2ProxyAdminOwner | ||
| ``` | ||
|
|
||
| ### Key CGT configuration fields | ||
|
|
||
| | Field | Description | Required | | ||
| |-------|-------------|----------| | ||
| | `customGasTokenName` | Name of the native asset (e.g., "My Custom Token") | Yes | | ||
| | `customGasTokenSymbol` | Symbol for the native asset (e.g., "MCT") | Yes | | ||
| | `initialLiquiditySupply` | Initial supply minted to NativeAssetLiquidity at genesis | No, default: type(uint248).max | | ||
| | `liquidityControllerOwner` | Manages the asset supply | No, `L2ProxyAdminOwner` will be used as default | | ||
|
|
||
| <Warning> | ||
| **Fee parameter calculation is critical**: Your `minBaseFee` and `operatorFee` must accurately account for L1 gas costs and DA fees denominated in your custom token. If set too low, your chain may not cover operational costs. If set too high, users will pay excessive fees. | ||
| </Warning> | ||
|
|
||
| <Info> | ||
| **Decimal support**: CGT v2 currently supports only 18-decimal tokens. Support for other decimals may be added in future releases. | ||
| </Info> | ||
| </Step> | ||
|
|
||
| <Step title="Deploy L1 contracts"> | ||
| Deploy your L1 contracts using OP Deployer's [apply command](/chain-operators/tools/op-deployer/usage/apply) | ||
|
|
||
| ```bash | ||
| op-deployer apply \ | ||
| --l1-rpc-url <your L1 RPC URL> \ | ||
| --private-key <your deployer private key> | ||
| ``` | ||
|
|
||
| This deploys all necessary L1 contracts including `SystemConfig` with the `isCustomGasToken` flag enabled, which instructs L1 contracts to reject ETH-value transactions. | ||
|
|
||
| <Info> | ||
| The deployment process will automatically deploy the CGT-specific predeploys (`NativeAssetLiquidity` and `LiquidityController`) during genesis initialization. | ||
| </Info> | ||
| </Step> | ||
|
|
||
| <Step title="(Optional) Verify L1 contracts"> | ||
| Optionally you can use OP Deployer's [verify command](/chain-operators/tools/op-deployer/usage/verify) to verify your L1 contracts on Blockscout or Etherscan. | ||
| </Step> | ||
|
|
||
| <Step title="Create genesis file with CGT configuration"> | ||
| After L1 deployment completes, initialize your L2 genesis with OP Deployer's [apply command](/chain-operators/tools/op-deployer/usage/apply): | ||
|
|
||
| ```bash | ||
| op-deployer apply \ | ||
| --deployment-target genesis | ||
| ``` | ||
|
|
||
| The genesis configuration is applied based on your `initent.toml`. | ||
| </Step> | ||
|
|
||
| <Step title="Start your chain services"> | ||
| Start your OP Stack services to start sequencing your CGT chain: | ||
|
|
||
| * Sequencer Execution Client | ||
| * Sequencer Consensus Client | ||
| * Batcher | ||
| * Proposer | ||
| * Challenger | ||
|
|
||
| <Info> | ||
| Your rollup configuration file must include `"isCustomGasToken": true` to ensure all services correctly handle CGT mode. | ||
| </Info> | ||
| </Step> | ||
|
|
||
| <Step title="Verify and test"> | ||
| Before going live, thoroughly test your CGT chain. The following are some key areas to check: | ||
|
|
||
| **Verify flag alignment** | ||
| * Check L1 SystemConfig.isCustomGasToken() returns true | ||
| * Check L2 L1Block.isCustomGasToken() returns true | ||
| * Verify both flags match | ||
|
|
||
| **Test native asset operations** | ||
| * Test minting native assets via authorized minter | ||
| * Test burning native assets | ||
| * Test fee payments in native token | ||
| * Verify fee vault accumulation | ||
|
|
||
|
|
||
| **Test ETH rejection** | ||
| * Attempt ETH deposit via OptimismPortal (should fail) | ||
| * Attempt ETH withdrawal via L2ToL1MessagePasser (should fail) | ||
| * Verify ETH operations are properly blocked | ||
|
|
||
|
|
||
| **Test bridge functionality** | ||
|
|
||
| * Test deposits (L1 → L2 native asset minting) | ||
| * Test withdrawals (L2 native → L1 token) | ||
| * Verify proper locking/unlocking in liquidity contract | ||
|
|
||
| </Step> | ||
| </Steps> | ||
|
|
||
| ## Post-deployment considerations | ||
|
|
||
| ### Supply management | ||
|
|
||
| After deployment, you can: | ||
|
|
||
| * **Withdraw excess liquidity**: If genesis created more supply than needed, withdraw and burn via `L2ToL1MessagePasser` | ||
| * **Add new minters**: Authorize additional contracts to mint native assets as your ecosystem grows | ||
| * **Revoke minters**: Remove authorization from compromised or deprecated contracts | ||
| * **Implement rate limits**: Add safeguards to control minting velocity | ||
|
|
||
| ### Fee parameter adjustments | ||
|
|
||
| Monitor your chain's operational costs and adjust fee parameters as needed: | ||
|
|
||
| * **minBaseFee**: Adjust based on L1 gas costs and your token's value | ||
| * **operatorFee**: Adjust based on data availability costs | ||
| * Use `SystemConfig.setGasConfig()` to update parameters | ||
|
|
||
| ### Developer documentation | ||
|
|
||
| Create clear documentation for your users covering: | ||
|
|
||
| * How to acquire native assets (bridge, DEX, faucet, etc.) | ||
| * Bridge contract addresses and interfaces | ||
| * Fee structure and token economics | ||
| * Wallet configuration (RPC endpoints, chain ID, token metadata) | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Flag mismatch errors | ||
|
|
||
| **Symptom**: Transactions failing with "custom gas token mismatch" errors | ||
|
|
||
| **Solution**: Verify that `SystemConfig.isCustomGasToken()` on L1 and `L1Block.isCustomGasToken()` on L2 return the same value. If mismatched, this indicates a critical configuration error. | ||
|
|
||
| ### Fee parameter issues | ||
|
|
||
| **Symptom**: Chain operator losing money on transaction costs or users complaining about excessive fees | ||
|
|
||
| **Solution**: Review and recalculate your `minBaseFee` and `operatorFee` parameters based on: | ||
| * Current L1 gas prices | ||
| * Your token's market value or peg | ||
| * Data availability costs | ||
| * Target fee structure for users | ||
|
|
||
| ### Liquidity depletion | ||
|
|
||
| **Symptom**: Minting transactions failing due to insufficient liquidity | ||
|
|
||
| **Solution**: | ||
| * Check `NativeAssetLiquidity` balance | ||
| * If depleted, this indicates an imbalance between minting and burning | ||
| * Review bridge logic to ensure burns are occurring correctly | ||
| * Consider increasing initial liquidity supply in future deployments | ||
|
|
||
| ### Unauthorized minting attempts | ||
|
|
||
| **Symptom**: Unauthorized addresses attempting to mint native assets | ||
|
|
||
| **Solution**: | ||
| * Review access control configuration on `LiquidityController` | ||
| * Ensure only audited and secured contracts are authorized | ||
| * Implement rate limiting if not already in place | ||
| * Consider revoking and re-authorizing with additional safeguards | ||
|
|
||
| ## Resources | ||
|
|
||
| * [Custom Gas Token feature overview](/op-stack/features/custom-gas-token) | ||
| * [OP Deployer documentation](/chain-operators/tools/op-deployer/overview) | ||
This file contains hidden or 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 hidden or 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,99 @@ | ||
| --- | ||
| title: Custom Gas Token | ||
| description: Learn how utilize a Custom Gas Token for OP Stack chains. | ||
| --- | ||
|
|
||
| Custom Gas Token (CGT) enables OP Stack chains to use any asset as their native fee currency instead of ETH. | ||
| This opens up new possibilities for chain operators to align their economic model with their specific use case, whether that's using a stablecoin for predictable fees, a governance token for ecosystem alignment, or creating an entirely new native asset. | ||
|
|
||
| This iteration of CGT is a redesign that prioritizes flexibility, minimal core protocol changes, and future-proof standardization by decoupling native asset management from core bridging infrastructure. | ||
|
|
||
| ## Key features | ||
|
|
||
| * **Token flexibility**: Use any token as the native gas token - existing L1 ERC-20s, L2-native tokens, or entirely new assets | ||
| * **Application-layer bridging**: No bridge or token is enshrined in the protocol; bridges and converters live entirely at the application layer | ||
| * **Flexible supply management**: Chain governors have complete control over token supply, emission schedules, and distribution mechanisms | ||
| * **Future-proof design**: Built to support emerging standards like SuperchainERC20 and cross-chain interoperability | ||
|
|
||
| ## How it works | ||
|
|
||
| CGT is configured at genesis and comes with two new predeploy contracts to manage native assets independently from ETH bridging: | ||
|
|
||
| ### The `isCustomGasToken()` flag | ||
|
|
||
| When enabled: | ||
|
|
||
| * **On L1**: Placed in `SystemConfig`, instructs `OptimismPortal`, `L1CrossDomainMessenger`, and `L1StandardBridge` to reject transactions containing ETH value (`msg.value`) | ||
| * **On L2**: Located in `L1Block`, prevents ETH-related operations in `L2ToL1MessagePasser`, `L2CrossDomainMessenger`, `L2StandardBridge`, and `FeeVaults` | ||
|
|
||
| This enables native asset mints and burns to be decoupled from deposits and moved to the application layer. | ||
|
|
||
| ### Two new predeploy contracts | ||
|
|
||
| **NativeAssetLiquidity** | ||
|
|
||
| Holds pre-minted native assets created at genesis with two core functions: | ||
|
|
||
| * `deposit()`: Receives native assets (callable only by LiquidityController) | ||
| * `withdraw()`: Releases native assets to the controller | ||
|
|
||
| **LiquidityController** | ||
|
|
||
| Governance-controlled contract that manages asset supply through: | ||
|
|
||
| * `authorizeMinter()` / `deauthorizeMinter()`: Grants or revokes minting permissions | ||
| * `mint()`: Unlocks assets from liquidity reserves for authorized parties | ||
| * `burn()`: Accepts native assets and locks them in the liquidity contract | ||
| * Stores token metadata for wrapped asset compatibility | ||
|
|
||
| ## Use cases | ||
|
|
||
| * **Stablecoin fees**: Use USDC or other stablecoins for predictable transaction costs | ||
| * **Governance alignment**: Use your chain's governance token as the gas token to align incentives | ||
| * **L2-native economies**: Create entirely new native assets with custom supply mechanics | ||
| * **Simplified UX**: Reduce the number of tokens users need to hold for interacting with your chain | ||
|
|
||
| ## Comparison with previous design | ||
|
|
||
| Custom Gas Token v2 was introduced in Upgrade 18 and is available in `op-contracts/v6.0.0`. | ||
|
|
||
| | Aspect | Legacy CGT | CGT v2 | | ||
| |--------|-----------|---------| | ||
| | **Token basis** | Anchored to L1 ERC-20 | Independent native asset at genesis | | ||
| | **Flexibility** | Restricted to specific configurations | Supports any release mechanism | | ||
| | **Bridging** | Built into core contracts | Application-layer responsibility | | ||
| | **Supply control** | System transaction minting | Minter authorization model | | ||
| | **Adaptability** | Limited post-deployment changes | Upgradeable and flexible | | ||
|
|
||
| <Warning> | ||
| **Migration from legacy CGT**: There is currently no migration path from legacy CGT to CGT v2. A migration path is planned to be put together. Chains using the previous CGT design will need to coordinate a hard fork to adopt the new architecture. | ||
| </Warning> | ||
|
|
||
| ## Developer impact | ||
|
|
||
| * **Decoupled from core components**: Since native asset management is decoupled from core components, obtaining native assets might vary chain-by-chain. That means that bridging, conversions, and features utilized would be different. It's suggested to create some library or templates that cover basic uses cases (e.g., L2-native, bridging from L1) to standardize most implementations. | ||
| * Chain Governors are encouraged to audit their implementations. | ||
| * Developers would need to look at the chain's docs to understand how to obtain native assets. | ||
| * Ideally CGT Chain Operators can work together to formalize a common set of CGT patterns that don't come out of the box. | ||
| * **No unified API**: The flexibility of this implementation means each CGT chain may have different methods for obtaining native assets | ||
| * **ETH bridging**: ETH bridging routes through L1-WETH as an ERC-20 wrapper | ||
| * **Documentation**: Clear documentation becomes critical for users to understand how to acquire native assets | ||
|
|
||
| ## Risks and considerations | ||
|
|
||
| ### Supply management | ||
|
|
||
| * **Minter security**: Any address granted minter permissions requires thorough security review and auditing | ||
| * **Access control**: Misconfigurations in bridges or controllers could lead to unintended minting or burning | ||
| * **Rate limiting**: Consider implementing rate limits on minting velocity to reduce risk | ||
|
|
||
| ### Configuration accuracy | ||
|
|
||
| * **Flag alignment**: `isCustomGasToken` must match between L1 and L2 to prevent protocol violations | ||
| * **Fee parameters**: `minBaseFee` and `operatorFee` must accurately account for execution and data availability costs in the native token's denomination | ||
| * **Decimal support**: CGT currently supports only 18-decimal tokens. | ||
| ERC20s with different decimals require custom logic to handle rounding when converting between the token and the native asset. | ||
|
|
||
| ## Next steps | ||
|
|
||
| * **For chain operators**: See [Deploy a Custom Gas Token chain](/chain-operators/guides/features/custom-gas-token-guide) for detailed deployment instructions | ||
This file contains hidden or 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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.