The proposal is not (yet) formulated as an official improvement proposal and is currently presented to gauge the interest and get feedback.
Abstract
The usual flow for minting a new ERC-20 or ERC-721 token on an Ethereum L2 is:
- Mint the token on L1
- Mint the token on L2
- Link them together with the appropriate bridge.
So even if there is no immediate need to deploy the token on L1, minting has to be initially done on L1, and only then bridged to L2. This creates unnecessary cost overhead and requires the deployer to be knowledgeable of development in both environments, and their bridging functionality.
Furthermore, if token governance is handled on L2, it makes little sense to create a complex L1 token that mimics the functionality of the L2 token.
It should be possible to mint the token on L2, and then easily port it to L1, keeping only the functionality required to enable interoperability and settlement. ( e.g discussion thread)
This proposal describes a standard that enables developers to first mint tokens on L2 and then use a known and secure bridge to port the token to L1.
The standard heavily uses the ability of StarkNet’s L1↔L2 messaging. The mechanism allows messages to be passed relatively quickly between L2 and L1, by any contract and with any data. This allows for both fungible and non-fungible assets to be transferred without relying on third party liquidity providers or waiting for long timeouts.
Components
The standard requires the following components:
- A bridge per standard (e.g. ERC-20, ERC-721) on L1, receives a request to create an L1 instance of a token from L2.
- The asset minted on L2 must support the
L2Bridgable
interface, and be aware of the bridge address on L1.
L1 Bridge
L1 Bridge operation
The bridge on L1 serves several purposes.
- Creates a new token instance on L1 after receiving a request from L2
- Keeps a mapping for L1↔L2 addresses (can also be calculated without storage costs)
- Handles requests to bridge tokens from L2
- Handles requests to bridge tokens to L2
Extra benefits:
- Since only basic token functionality is required, the bridge creates a standard token implementation instance, with all the best practices in mind. It does not require the token deployer on L2 to be mindful of the implementation on L1.
- Since all L1 functionality is standard, all new instances only maintain storage, and delegate the calls to the factory contract, making the mining of the original contract on L1 substantially cheaper.
Bridge Interface
-
createL1Instance
:- Clones the contract, with the l2_address as the salt for CREATE2
- Receives:
- L2 Token address (sent implicitly from L2)
- Token name
- Token symbol
- These must match the message sent by the L2 token
-
BridgeTokensFromL2
:- Mints new tokens on L1
- Requires the contract on L1 to be initiated
- Receives:
- L2 Token address (sent implicitly from L2)
- L1 recipient
- Token Amount / ID
-
BridgeTokensToL2
- Burns the tokens of the sender on L1 and sends a message to L2
- Receives:
- L2 token address
- L2 recipient
- Token amount / ID
L1Bridgable
interface (ERC-20 example)
The interface has the following functions
func create_l1_instance( name : felt, symbol : felt )
Sends the message to the known L1 bridge. The message passes the contract address, the token name, the token symbol.
(In ERC721 it should also send the URI of the token and possibly other metadata)
func bridge_tokens_to_l1( l1_recipient : felt, amount : Uint256)
Once an instance on L1 is created, tokens can be bridged directly from the contract to L1.
- Sends a message to a known bridge on L1
- Burns/locks the tokens of the message sender on L2
- Message to L1 includes:
- L1_recipient
- Token amount / ID
func bridge_tokens_from_l1( from_address : felt, l2_recipient : felt, amount : Uint256)
- L1_handler to receive bridged tokens from l1
- Received message:
- L2_recipient
- Token amount
- Checks the bridge is authorized
- Mints/Unlocks tokens on L1 to the specified address
Flow diagram
An example flow for a token contract minted on L2 and later deployed on L1
Example flow of bridging a token to an L1 instance
Implementation example
An example implementation for both L1 and L2 can be found here:
The following contracts have been deployed to StarkNet and Goerli testnet to demonstrate functionality:
Example contracts
Contract | Link |
---|---|
L2 ERC20 Contract Class | L2 ERC20 Contract Class |
L2 ERC20 Contract | L2 ERC20 Contract |
L1 ERC20 Goerli Bridge | L1 ERC20 Goerli Bridge |
L1 ERC20 Goerli Instance | L1 ERC20 Goerli Instance |
This implementation is only an example. To make this proposal concrete, both the L1 bridge and the L2 interface should be finalized and implemented by serious people