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
  • Useful Addresses
  • Diamond (also mentioned as State Transition contract)
  • ValidatorTimelock
  1. Developer Reference
  2. Era Contracts

L1 Contracts

Last updated 8 months ago


Useful Addresses

L1 Mainnet Contract Addresses:

  • DiamondInit:

  • DiamondProxy:

  • DiamondUpgrade:

  • ExecutorFacet:

  • GettersFacet:

  • Verifier:

  • MailboxFacet:

  • ValidatorTimelock:

  • AllowList:

L1 Testnet Contract Addresses:

  • DiamondInit:

  • DiamondProxy:

  • DiamondUpgrade:

  • ExecutorFacet:

  • GettersFacet:

  • Verifier:

  • MailboxFacet:

  • ValidatorTimelock:

  • AllowList:

This section delves into the ZKsync Era smart contracts, describing how they facilitate interactions between Ethereum (Layer 1) and ZK Chain instances (Layer 2) within ZKsync Era ecosystem. While we provide overview of ZKsync Era smart contracts here, it's important to note that this document does NOT cover the ZK Chain architecture - communication between multiple rollups and shared liquidity in details. For information on the ZK Chain and its functionalities, please refer to .

Diamond (also mentioned as State Transition contract)

Technically, this L1 smart contract acts as a connector between Ethereum (L1) and ZK Chain (L2). It checks the validity proof and data availability, handles L2 <-> L1 communication, finalizes L2 state transition, and more.

There are also important contracts deployed on the L2 that can also execute logic called . Using L2 <-> L1 communication can affect both the L1 and the L2.

DiamondProxy

One of the differences from the reference implementation is access freeze-ability. Each of the facets has an associated parameter that indicates if it is possible to freeze access to the facet. Privileged actors can freeze the diamond (not a specific facet!) and all facets with the marker isFreezable should be inaccessible until the governor or admin unfreezes the diamond. Note that it is a very dangerous thing since the diamond proxy can freeze the upgrade system and then the diamond will be frozen forever.

GettersFacet

AdminFacet

This facet responsible for the configuration setup and upgradeability, handling tasks such as:

  • Privileged Address Management: Updating key roles, including the governor and validators.

  • System Parameter Configuration: Adjusting critical system settings, such as the L2 bootloader bytecode hash, verifier address, verifier parameters, fee configurations.

  • Freeze-ability: Executing the freezing/unfreezing of facets within the diamond proxy to safeguard the ecosystem during upgrades or in response to detected vulnerabilities.

Control over the AdminFacet is divided between two main entities:

  • Admin - Multisig smart contract managed by Matter Labs that can perform non-critical changes to the system such as granting validator permissions. Note, that the Admin is the same multisig as the owner of the governance.

MailboxFacet

The Mailbox performs three functions:

  • L1 ↔ L2 Communication: Enables data and transaction requests to be sent from L1 to L2 and vice versa, supporting the implementation of multi-layer protocols.

  • Bridging Native Tokens: Allows the bridging of either ether or ERC20 tokens to L2, enabling users to use these assets within the L2 ecosystem.

  • Censorship Resistance Mechanism: Currently in the research stage.

L1->L2 communication is implemented as requesting an L2 transaction on L1 and executing it on L2. This means a user can call the function on the L1 contract to save the data about the transaction in some queue. Later on, a validator can process it on L2 and mark it as processed on the L1 priority queue. Currently, it is used for sending information from L1 to L2 or implementing multi-layer protocols. Users pays for the transaction execution in the native token when requests L1->L2 transaction.

NOTE: While user requests the transaction from L1, the initiated transaction on L2 will have such a msg.sender:

  address sender = msg.sender;
  if (sender != tx.origin) {
      sender = AddressAliasHelper.applyL1ToL2Alias(msg.sender);
  }

where

uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);

function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {
  unchecked {
    l2Address = address(uint160(l1Address) + offset);
  }
}

For most of the rollups the address aliasing needs to prevent cross-chain exploits that would otherwise be possible if we simply reused the same L1 addresses as the L2 sender. In ZKsync Era address derivation rule is different from the Ethereum, so cross-chain exploits are already impossible. However, ZKsync Era may add full EVM support in the future, so applying address aliasing leaves room for future EVM compatibility.

The L1 -> L2 communication is also used for bridging native tokens. If native token is ether (the case for ZKsync Era) - user should include a msg.value when initiating a transaction request on the L1 contract, if native token is an ERC20 then contract will spend users allowance. Before executing a transaction on L2, the specified address will be credited with the funds. To withdraw funds user should call withdraw function on the L2BaseToken system contracts. This will burn the funds on L2, allowing the user to reclaim them through the finalizeWithdrawal function on the SharedBridge (more in ZK Chain section).

ExecutorFacet

The state transition is divided into three stages:

  • commitBatches - check L2 batch timestamp, process the L2 logs, save data for a batch, and prepare data for zk-proof.

  • proveBatches - validate zk-proof.

  • executeBatches - finalize the state, marking L1 -> L2 communication processing, and saving Merkle tree with L2 logs.

Each L2 -> L1 system log will have a key that is part of the following:

enum SystemLogKey {
    L2_TO_L1_LOGS_TREE_ROOT_KEY,
    TOTAL_L2_TO_L1_PUBDATA_KEY,
    STATE_DIFF_HASH_KEY,
    PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY,
    PREV_BATCH_HASH_KEY,
    CHAINED_PRIORITY_TXN_HASH_KEY,
    NUMBER_OF_LAYER_1_TXS_KEY,
    BLOB_ONE_HASH_KEY,
    BLOB_TWO_HASH_KEY,
    EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY
}

When a batch is committed, we process L2 -> L1 system logs. Here are the invariants that are expected there:

  • In a given batch there will be either 9 or 10 system logs. The 10th log is only required for a protocol upgrade.

  • There will be a single log for each key that is contained within SystemLogKey

  • Three logs from the L2_TO_L1_MESSENGER with keys:

  • L2_TO_L1_LOGS_TREE_ROOT_KEY

  • TOTAL_L2_TO_L1_PUBDATA_KEY

  • STATE_DIFF_HASH_KEY

  • Two logs from L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR with keys:

    • PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY

    • PREV_BATCH_HASH_KEY

  • Two logs from L2_PUBDATA_CHUNK_PUBLISHER_ADDR with keys:

    • BLOB_ONE_HASH_KEY

    • BLOB_TWO_HASH_KEY

  • Two or three logs from L2_BOOTLOADER_ADDRESS with keys:

    • CHAINED_PRIORITY_TXN_HASH_KEY

    • NUMBER_OF_LAYER_1_TXS_KEY

    • EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY

  • None logs from other addresses (may be changed in the future).

DiamondInit

It is a one-function contract that implements the logic of initializing a diamond proxy. It is called only once on the diamond constructor and is not saved in the diamond as a facet.

ValidatorTimelock

An intermediate smart contract between the validator EOA account and the ZKsync smart contract. Its primary purpose is to provide a trustless means of delaying batch execution without modifying the main ZKsync contract. ZKsync actively monitors the chain activity and reacts to any suspicious activity by freezing the chain. This allows time for investigation and mitigation before resuming normal operations.

It is a temporary solution to prevent any significant impact of the validator hot key leakage, while the network is in the Alpha stage.

This contract consists of four main functions commitBatches, proveBatches, executeBatches, and revertBatches, which can be called only by the validator.

When the validator calls commitBatches, the same calldata will be propagated to the ZKsync contract (DiamondProxy through call where it invokes the ExecutorFacet through delegatecall), and also a timestamp is assigned to these batches to track the time these batches are committed by the validator to enforce a delay between committing and execution of batches. Then, the validator can prove the already committed batches regardless of the mentioned timestamp, and again the same calldata (related to the proveBatches function) will be propagated to the ZKsync contract. After the delay is elapsed, the validator is allowed to call executeBatches to propagate the same calldata to ZKsync contract.

The owner of the ValidatorTimelock contract is the same as the owner of the Governance contract - Matter Labs multisig.

diamondProxy.png

The main contract uses diamond proxy pattern. It is an in-house implementation that is inspired by the . It has no external functions, only the fallback that delegates a call to one of the facets (target/implementation contract). So even an upgrade system is a separate facet that can be replaced.

The diamond proxy pattern is very flexible and extendable. For now, it allows splitting implementation contracts by their logical meaning, removes the limit of bytecode size per contract and implements security features such as freezing. In the future, it can also be viewed as for , where each ZK Chain can implement a sub-set of allowed implementation contracts.

Separate facet, whose only function is providing view and pure methods. It also implements which makes managing facets easier. This contract must never be frozen.

STM (State Transition Manager) - Separate smart contract that can perform critical changes to the system as protocol upgrades. For more detailed information on its function and design, refer to the . Although currently only one version of the STM exists, the architecture allows for future versions to be introduced via subsequent upgrades. Control of the STM is shared between the Governance.sol contract and the Admin entity (see details below). In its turn, Governance.sol controlled by two multisigs: Admin multisig (see below) and Security council multisig (well-respected contributors in the crypto space). Collaboratively, these entities hold the power to implement instant upgrades, whereas Matter Labs alone is limited to scheduling upgrades with a delay.

The facet that handles L2 <-> L1 communication, an overview for which can be found in .

More about L1->L2 operations can be found .

L2 -> L1 communication, in contrast to L1 -> L2 communication, is based only on transferring the information, and not on the transaction execution on L1. The full description of the mechanism for sending information from L2 to L1 can be found .

A contract that accepts L2 batches, enforces data availability and checks the validity of zk-proofs. For more information on how pubdata is parsed, processed please refer to the doc on and the one on detailing out the contents.

Implementation detail - function returns a magic value just like it is designed in , but the magic value is 32 bytes in size.

0xb91d905A698c28b73C61aF60C63919b754FCF4DE
0x32400084c286cf3e17e7b677ea9583e60a000324
0xe79a6d29bB0520648F25D11d65e29FB06B195F0F
0xD059478a564dF1353A54AC0D0e7Fc55A90b92246
0xF3ACF6a03ea4a914B78Ec788624B25ceC37c14A4
0xB465882F67d236DcC0D090F78ebb0d838e9719D8
0x63b5EC36B09384fFA7106A80Ec7cfdFCa521fD08
0xa8cb082a5a689e0d594d7da1e2d72a3d63adc1bd
0x0C0dC1171258694635AA50cec5845aC1031cA6d7
0x457701fDC6CaBc7D2EfB9b85f7faB0EE4bBD3c36
0x9a6de0f62Aa270A8bCB1e2610078650D539B1Ef9
0xA6b2731c08385782fBaCfCcD63D3c7fc7b798E47
0xe6cc1455217a8BBCF2c663607A0b8c200B8732F1
0x10f328c20dD2469b7e88f374B9794471599c1c8D
0xf07ea72e071bc21612449570C365Ff3DC9176Ecb
0x2ed8eF54a16bBF721a318bd5a5C0F39Be70eaa65
0x8CaC0a609A314E4161b8070cdEe065060B2486A1
0x7546a21cd4D74fc98Ef1A50145dfd8c043e2096F
Ecosystem contracts
system contracts
EIP-2535
mudgen reference implementation
EIP-6900
ZK Stack
diamond loupe
docs
here
here
pubdata post EIP-4844
Handling pubdata
EIP-1271
ZK Chain section