Validium Docs
  • Overview
  • Connect to Validium
  • Start Coding 🚀
    • Quickstart
      • Overview
      • Deploy using Validium CLI
      • Deploy using Quickstart Repository
      • Deploy your first contract
      • Create an ERC20 token
  • Tooling
    • Block Explorers
    • Hardhat-Validium
      • Overview
      • Installation
      • Guides
        • Getting started
        • Migrating Hardhat project to Validium
        • Compiling non-inlinable libraries
      • Plugins
        • hardhat-zksync
        • hardhat-zksync-solc
        • hardhat-zksync-vyper
        • hardhat-zksync-deploy
        • hardhat-zksync-upgradable
        • hardhat-zksync-verify
        • hardhat-zksync-verify-vyper
        • hardhat-zksync-ethers
        • hardhat-zksync-node
        • Hardhat Community Plugins
    • Foundary
      • Overview
      • Installation
      • Getting Started
      • Migration Guide
        • Overview
        • Compilation
        • Deployment
        • Testing
  • Test and Debug
    • Getting Started
    • Docker L1 - L2 Nodes
    • In-Memory Node
    • Continuous Integration
    • Hardhat
    • Foundry
  • API Reference
    • Overview
    • Conventions
    • ZKs JSON-RPC API
    • Debug JSON-RPC API
    • Ethereum JSON-RPC API
    • PubSub JSON-RPC API
  • Concepts
    • Transaction Lifecycle
    • Blocks and Batches
    • Validium Network Fee Mechanism
    • Finality
    • System Upgrades
    • ZK Chains
    • Data Availability
      • Overview
      • Recreating L2 state from L1 pubdata
      • Validiums
    • Account Abstraction
    • L1 <-> L2 Communication
  • Components
    • Overview
    • Smart & System Contracts
      • Smart Contracts
      • System Contracts
    • Shared Bridges
    • Sequencer / Server
    • Validium Network EVM
      • Overview
      • Bootloader
      • Precompiles
      • Virtual Machine Specification
        • ZKsync Virtual Machine primer
        • VM Formal Specification
    • Prover
      • Overview
      • ZK Terminology
      • Running the Prover
      • Circuits
        • Overview
        • Circuit Testing
        • CodeDecommitter
        • DemuxLogQueue
        • ECRecover
        • KeccakRoundFunction
        • L1MessagesHasher
        • LogSorter
        • Main VM
        • RAMPermutation
        • Sha256RoundFunction
        • StorageApplication
        • Sorting and Deduplicating
          • Overview
          • SortDecommitments
          • StorageSorter
          • LogSorter
      • Boojum Gadgets
      • Boojum Function - `check_if_satisfied`
    • Compiler
      • Compiler Toolchain Overview
        • Compiler Toolchain Overview
        • Solidity Compiler
        • Vyper Compiler
        • LLVM Framework
      • Specification
        • Overview
        • Code Separation
        • System Contracts
        • Exception Handling
        • EVM Legacy Assembly Translator
        • Instructions
          • Instruction Reference
          • EVM
            • Native EVM Instructions
            • Arithmetic
            • Bitwise
            • Block
            • Call
            • Create
            • Environment
            • Logging
            • Logical
            • Memory
            • Return
            • Sha3
            • Stack
          • Extensions
            • Overview
            • Validium Network Extension Simulation (call)
            • Validium Network Extension Simulation (verbatim)
          • EVM Legacy Assembly
          • Yul
        • EraVM Binary Layout
    • Fee Withdrawer
    • Portal - Wallet + Bridge
    • Block Explorer
    • Transaction filtering
Powered by GitBook
On this page
  • Default bridges
  • Custom bridges on L1 and L2
  • Adding Tokens to the Bridge UI
  1. Developer Reference

Bridging Assets

Last updated 8 months ago


Users can deposit and withdraw assets from ZKsync Era using any of the .

Under the hood, bridging is implemented by having two contracts (one deployed to L1, and the second deployed to L2) communicating with each other using .

Developers are free to build their own however, we provide default bridges (one for ETH and one for ERC20 tokens), which can be used for basic bridging.

Addresses of tokens on L2 will always differ from the same token L1 address. Also note, that tokens bridged via the default bridge only support standard ERC20 functionality, i.e. rebase tokens and other custom behavior are not supported.

Default bridges

You can get the default bridge addresses using the endpoint or getDefaultBridgeAddresses method of Provider. Similar methods are available in the other SDKs.

Deposits (to L2)

Users must call the deposit method on the L1 bridge contract, which triggers the following actions:

  • The user's L1 tokens will be sent to the L1 bridge and become locked there.

  • The L1 bridge initiates a transaction to the L2 bridge using L1 -> L2 communication.

  • Within the L2 transaction, tokens will be minted and sent to the specified address on L2.

    • If the token does not exist on ZKsync yet, a new contract is deployed for it. Given the L2 token address is deterministic (based on the original L1 address, name and symbol), it doesn't matter who is the first person bridging it, the new L2 address will be the same.

  • For every executed L1 -> L2 transaction, there will be an L2 -> L1 log message confirming its execution.

  • Lastly, the finalizeDepositmethod is called and it finalizes the deposit and mints funds on L2.

You can find example scripts to deposit ETH and ERC20 tokens using the default bridges in the how-to section of the docs.

Withdrawals (to L1)

  • To provide additional security during the Alpha phase, withdrawals in ZKsync Era take 24 hours.

Users must call the withdraw method on the L2 bridge contract, which will trigger the following actions:

  • L2 tokens will be burned.

  • An L2 -> L1 message with the information about the withdrawal will be sent.

  • After that, the withdrawal action will be available to be finalized by anyone in the L1 bridge (by proving the inclusion of the L2 -> L1 message, which is done when calling the finalizeWithdrawal method on the L1 bridge contract).

  • After the method is called, the funds are unlocked from the L1 bridge and sent to the withdrawal recipient.

On the testnet environment, we automatically finalize all withdrawals, i.e., for every withdrawal, we will take care of it by making an L1 transaction that proves the inclusion for each message.

Custom bridges on L1 and L2

To build a custom bridge, create a regular Solidity contract which extends one of the interfaces mentioned below for the layer. The interfaces provide access to the ZKsync Era SDK deposit and withdraw implementations.

Adding Tokens to the Bridge UI

No action is required to add tokens to the bridge UI. All tokens are automatically recognized based on user balances. If you desire for your token to display an icon or price, refer to the Token Listing Guide.

For more information, read the .

L1: For more information, check out our example .

L2: For more information, check out our example .

withdrawal delay guide
IL1Bridge.sol
L1 custom bridge implementation
IL2Bridge.sol
L2 custom bridge implementation
multiple bridges
L1 <-> L2 interoperability
zks_getBridgeContracts
custom bridge for any token