How It Works
BLAST is native to Blast. It moves to Ethereum through the standard OP Stack bridge using a lock-and-mint model:- On Blast, your BLAST is locked in the L2StandardBridge.
- On Ethereum, the same amount of L1 BLAST (
0x71b9e0FD392713A14FCaB92D9aF7A21F47E3b1Fa) is minted to your recipient when the withdrawal is finalized.
OptimismMintableERC20. Its remoteToken() is L2 BLAST, and its bridge() is the L1StandardBridge, the only address that can mint it.
Before You Start
Your L2 Contract Must Be Able to Call the Bridge
The withdrawal is initiated by the contract that holds the BLAST on the L2. It must be able to make the following contract calls:approve on the BLAST token, then bridgeERC20To on the L2StandardBridge. A contract that can only transfer tokens to an address can’t start a withdrawal itself; move the BLAST to a contract or account that can.
Verify Your L1 Recipient
Before you start, verify that the intended recipient address meets the following conditions:- It exists on Ethereum. There is contract code at the address, or it’s an EOA you control. If nothing is deployed there yet, the BLAST still arrives, but whoever later deploys a contract at that address controls it. A not-yet-deployed multisig must later be deployed with exactly the same configuration to reach the same address.
- It’s the contract you expect. Its source is verified and it’s the contract type you intended. For a multisig, it has the owners and threshold you expect.
- It can transfer the BLAST out. It must be able to send ERC20 tokens it holds to another address. A contract that can receive tokens but not send them leaves the BLAST stuck permanently.
Anyone Can Prove and Finalize
proveWithdrawalTransaction and finalizeWithdrawalTransaction on Ethereum don’t check who sends them. Any EOA with ETH for gas can submit them; your L2 contract and its signers don’t need to do anything on Ethereum.
Test With a Small Amount First
Be sure to run the whole flow end-to-end with a small amount before moving large balances.Withdraw Your BLAST
1
Approve the bridge (Blast)
The bridge pulls the BLAST into escrow, so it must be approved first.
2
Initiate the withdrawal (Blast)
Record these values. The later steps and status checks use them:
- the L2 transaction hash
- its L2 block number
- the
withdrawalHash: the last field of theMessagePassedevent emitted by the L2ToL1MessagePasser (0x4200000000000000000000000000000000000016) in this transaction
3
Prove the withdrawal (Ethereum)
Wait until the L2 output containing your transaction has been posted to Ethereum, up to ~1 hour (see Ready to Prove?). Then call The proof arguments are built from your L2 transaction hash. See Building the Prove and Finalize Transactions for code that does this.
proveWithdrawalTransaction on the OptimismPortal (0x0Ec68c5B10F21EFFb74f2A5C61DFe6b08C0Db6Cb):4
Wait for the challenge period
Wait 1 day after proving.
5
Finalize the withdrawal (Ethereum)
Call See Building the Prove and Finalize Transactions for code that builds and sends this call.The L1StandardBridge mints L1 BLAST to your recipient in the same transaction. Confirm it arrived (see Delivered?).
finalizeWithdrawalTransaction on the OptimismPortal, with hintId set to 0:Building the Prove and Finalize Transactions
The examples below use TypeScript and viem2.57.3. Each builds the transaction from the L2 transaction hash of your initiate step and sends it.
Setup
Prove
Run this once the withdrawal is ready to prove.Finalize
Run this once the challenge period is over, 1 day after proving. Then confirm delivery.Checking Withdrawal Status
Every stage can be checked with read-only calls on Ethereum, from your own tooling or the Read as Proxy tab on Etherscan, using the L2 block number andwithdrawalHash you recorded when you initiated.
Ready to Prove?
Proven?
timestamp of 0 means the withdrawal hasn’t been proven. requestId is always 0 for BLAST.
Challenge Period Over?
timestamp is the proven timestamp from the previous check. The challenge period is currently 86400 seconds (1 day).
Finalized?
Delivered?
Finalizing hands the withdrawal to the L1CrossDomainMessenger (0x5D4472f31Bd9385709ec61305AFc749F0fA8e9d0), which calls the L1StandardBridge to mint. If that call fails (for example, because of a wrong _remoteToken), the withdrawal is still marked as finalized, but the messenger records the message as failed and nothing is minted.
Confirm delivery in any of these ways:
L1BLAST.balanceOf(_to)increased by your amount.- The finalize transaction emitted
ERC20BridgeFinalizedfrom the L1StandardBridge. L1CrossDomainMessenger.successfulMessages(keccak256(data))istrue, wheredatais thedatafield of your withdrawal’sMessagePassedevent.