Shared bridges

Explore the design and functionality of Shared Bridges within Ethereum's ZK chain ecosystem, including future features and system upgrades.

Ethereum's evolving infrastructure is shifting towards a rollup-centric future, focusing on an interconnected ecosystem of zero-knowledge Ethereum Virtual Machines (zkEVMs), collectively known as ZK chains. This transformation relies on robust Layer 1 (L1) smart contracts to maintain coherence and security across the ecosystem.

ZK Stack approach

Our approach to developing this ecosystem involves specific architectures and interfaces of L1 smart contracts. These contracts are designed to support the changing needs of the Ethereum landscape and facilitate the integration of new features as the technology advances.

High-level design goals

  • Permissionless ZK Chain Launch: Enable the launch of new ZK chains within the ecosystem without requiring permissions, promoting an open and inclusive network.
  • Unified Liquidity Through Hyperbridges: Establish bridges that allow seamless asset liquidity across the entire ecosystem, making asset management more straightforward and efficient.
  • Simplified Multi-chain Contract Development: Provide easy access to traditional bridges and supporting architecture, facilitating the development of multi-chain smart contracts.

Trust and verification

ZK chains must meet common trust and verification standards. A single set of L1 smart contracts will manage the proof verification across all ZK chains. Any upgrade to the proof system will necessitate a simultaneous upgrade across all chains to maintain uniformity and security.

Bridging and liquidity

  • Bridgehub Contract on L1: This contract will link asset bridges to all ZK chains and manage the elastic chain ecosystem's ETH reserves. It acts as the central node in the bridging architecture.
  • System Contracts on ZK Chains: Special system contracts will be added to ZK chains to enable bridging functionalities, allowing them to interact smoothly with the Bridgehub and manage assets efficiently.

Modularity and future compatibility

The design aims to be as modular as possible, providing developers with the flexibility to alter the architecture based on evolving needs, such as changes in consensus mechanisms, staking models, and data availability requirements.

Anticipating future developments

  • Layer 3 Integrations and Proof Aggregation: Future updates will consider Layer 3 technologies and proof aggregation methods to enhance scalability and efficiency.
  • Alternative State Transition Contracts and ZK IP: The design will accommodate alternative State Transition (ST) contracts and ZK IP, which will ensure unified liquidity and interoperability among all state transitions when these features become available.

The Shared Bridge and the associated smart contracts are foundational to the sustainable growth of the ZK chain ecosystem. For further details on ZK chains and their operational dynamics, refer to our blog post on ZK chains or the section on ZK chains


Architecture

Contracts

Components: Bridgehub

  • Acts as a hub for bridges, so that they have a single point of communication with all ZK chain contracts. This allows L1 assets to be locked in the same contract for all ZK chains, including L3s and validiums. The Bridgehub also implements the following:
  • Registry This is where ZK chains can register, starting in a permissioned manner, but with the goal to be permissionless in the future. This is where their chainID is determined. L3s will also register here. This Registry is also where State Transition contracts should register. Each chain has to specify its desired ST when registering (Initially, only one will be available).
    function newChain(
            uint256 _chainId,
            address _stateTransition
        ) external returns (uint256 chainId);
    
    function newStateTransition(address _stateTransition) external;
    
  • BridgehubMailbox routes messages to the Diamond proxy’s Mailbox facet based on chainID
    • Same as the current zkEVM Mailbox, just with chainId,
    • Ether needs to be deposited and withdrawn from here.
    • This is where L2 transactions can be requested.
    function requestL2Transaction(
            uint256 _chainId,
            address _contractL2,
            uint256 _l2Value,
            bytes calldata _calldata,
            uint256 _l2GasLimit,
            uint256 _l2GasPerPubdataByteLimit,
            bytes[] calldata _factoryDeps,
            address _refundRecipient
        ) public payable override returns (bytes32 canonicalTxHash) {
            address proofChain = bridgeheadStorage.proofChain[_chainId];
            canonicalTxHash = IProofChain(proofChain).requestL2TransactionBridgehead(
                _chainId,
                msg.value,
                msg.sender,
                _contractL2,
                _l2Value,
                _calldata,
                _l2GasLimit,
                _l2GasPerPubdataByteLimit,
                _factoryDeps,
                _refundRecipient
            );
        }
    
  • Hypermailbox
    • This will allow general message passing (L2<>L2, L2<>L3, etc). This is where the Mailbox sends the Hyperlogs. Hyperlogs are commitments to these messages sent from a single ZK chain. Hyperlogs are aggregated into a HyperRoot in the HyperMailbox.
    • This component has not been implemented yet

Main Asset Shared Bridges

  • Some assets have to be natively supported (ETH, WETH) and it also makes sense to support some generally accepted token standards (ERC20 tokens), as this makes it easy to bridge those tokens (and ensures a single version of them exists on the ZK chain). These canonical asset contracts are deployed from L1 by a bridge shared by all ZK chains. This is where assets are locked on L1. These bridges use the Bridgehub to communicate with all ZK chains. Currently, these bridges are the WETH and ERC20 bridges.
    • The pair on L2 is deployed from L1. The hash of the factory dependencies is stored on L1, and when a ZK chain wants to register, it can passes it in for deployment, it is verified, and the contract is deployed on L2. The actual token contracts on L2 are deployed by the L2 bridge.
    function initializeChain(
            uint256 _chainId,
            bytes[] calldata _factoryDeps,
            uint256 _deployBridgeImplementationFee,
            uint256 _deployBridgeProxyFee
        ) external payable {
        ....
        // Deploy L2 bridge proxy contract
            l2Bridge[_chainId] = BridgeInitializationHelper.requestDeployTransaction(
                _chainId,
                bridgehead,
                _deployBridgeProxyFee,
                l2WethBridgeProxyBytecodeHash,
                l2WethBridgeProxyConstructorData,
                // No factory deps are needed for L2 bridge proxy, because it is already passed in the previous step
                new bytes[](0)
            );
    

Components: State Transition

  • StateTransition A state transition manages proof verification and DA for multiple chains. It also implements the following functionalities:
    • StateTransitionRegistry The ST is shared for multiple chains, so initialization and upgrades have to be the same for all chains. Registration is not permissionless but happens based on the registrations in the bridgehub’s Registry. At registration a DiamondProxy is deployed and initialized with the appropriate Facets for each ZK chain.
    • Facets and Verifier are shared across chains that relies on the same ST: Base, Executor , Getters, Admin , Mailbox.The Verifier is the contract that actually verifies the proof, and is called by the Executor.
    • Upgrade Mechanism The system requires all chains to be up-to-date with the latest implementation, so whenever an update is needed, we have to “force” each chain to update, but due to decentralization, we have to give each chain a time frame (more information in the Upgrade Mechanism section). This is done in the update mechanism contract, this is where the bootloader and system contracts are published, and the ProposedUpgrade is stored. Then each chain can call this upgrade for themselves as needed. After the deadline is over, the not-updated chains are frozen, that is, cannot post new proofs. Frozen chains can unfreeze by updating their proof system.
  • Each chain has a DiamondProxy.
    • The Diamond Proxy is the proxy pattern that is used for the chain contracts. A diamond proxy points to multiple implementation contracts called facets. Each selector is saved in the proxy, and the correct facet is selected and called.
    • In the future the DiamondProxy can be configured by picking alternative facets e.g. Validiums will have their own Executor

Components: Chain Specific Contracts

  • A chain might implement its own specific consensus mechanism. This needs its own contracts. Only this contract will be able to submit proofs to the State Transition contract.
  • Currently, the ValidatorTimelock is an example of such a contract.

Components interactions

In this section, we will present some diagrams showing the interaction of different components.

New Chain

A chain registers in the Bridgehub, this is where the chain ID is determined. The chain’s governor specifies the State Transition that they plan to use. In the first version only a single State Transition contract will be available for use, our with Boojum proof verification.

At initialization we prepare the StateTransitionChain contract. We store the genesis batch hash in the ST contract, all chains start out with the same state. A diamond proxy is deployed and initialised with this initial value, along with predefined facets which are made available by the ST contract. These facets contain the proof verification and other features required to process proofs. The chain ID is set in the VM in a special system transaction sent from L1.

Components: WETH Contract

Ether, the native gas token is part of the core system contracts, so deploying it is not necessary. But WETH is just a smart contract, it needs to be deployed and initialised. This happens from the L1 WETH bridge. This deploys on L2 the corresponding bridge and ERC20 contract. This is deployed from L1, but the L2 address is known at deployment time.

deployWeth.png

Components: Deposit WETH

The user can deposit WETH into the ecosystem using the WETH bridge on L1. The destination chain ID has to be specified. The Bridgehub unwraps the WETH, and keeps the ETH, and send a message to the destination L2 to mint WETH to the specified address.

depositWeth.png


Common Standards and Upgrades

In this initial phase, ZK chains have to follow some common standards, so that they can trust each other. This means all chains start out with the same empty state, they have the same VM implementations and proof systems, asset contracts can trust each on different chains, and the chains are upgraded together. We elaborate on the shared upgrade mechanism here.

Upgrade mechanism

Currently, there are three types of upgrades for zkEVM. Normal upgrades (used for new features) are initiated by the Governor (a multisig) and are public for a certain timeframe before they can be applied. Shadow upgrades are similar to normal upgrades, but the data is not known at the moment the upgrade is proposed, but only when executed (they can be executed with the delay, or instantly if approved by the security council). Instant upgrades (used for security issues), on the other hand happen quickly and need to be approved by the Security Council in addition to the Governor. For ZK chains the difference is that upgrades now happen on multiple chains. This is only a problem for shadow upgrades - in this case, the chains have to tightly coordinate to make all the upgrades happen in a short time frame, as the content of the upgrade becomes public once the first chain is upgraded. The actual upgrade process is as follows:

  1. Prepare Upgrade for all chains:
    • The new facets and upgrade contracts have to be deployed,
    • The upgrade’ calldata (diamondCut, initCalldata with ProposedUpgrade) is hashed on L1 and the hash is saved.
  2. Upgrade specific chain
    • The upgrade has to be called on the specific chain. The upgrade calldata is passed in as calldata and verified. The protocol version is updated.
    • Ideally, the upgrade will be very similar for all chains. If it is not, a smart contract can calculate the differences. If this is also not possible, we have to set the diamondCut for each chain by hand.
  3. Freeze not upgraded chains
    • After a certain time the chains that are not upgraded are frozen.

Made with ❤️ by the ZKsync Community