Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zk stack components #21

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ In a very rare event when the team needs to revert the batch with the upgrade on
[reset](https://github.com/code-423n4/2023-10-zksync/blob/ef99273a8fdb19f5912ca38ba46d6bd02071363d/code/contracts/ethereum/contracts/zksync/facets/Executor.sol#L412).

Note, however, that we do not “remember” that certain batches had a version before the upgrade, i.e. if the reverted
batches will have to be reexecuted, the upgrade transaction must still be present there, even if some of the deleted
batches will have to be re-executed, the upgrade transaction must still be present there, even if some of the deleted
batches were committed before the upgrade and thus didn’t contain the transaction.

### Execute
Expand Down
31 changes: 31 additions & 0 deletions content/10.zk-stack/10.components/10.overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: Overview
description: Explore the ZK Stack, a flexible, open-source framework designed for creating sovereign ZK-powered Ethereum rollups, known as hyperchains, utilizing the foundational technology of zkSync Era.
---

The ZK Stack is a comprehensive framework aimed at revolutionizing the development of Ethereum rollups through its modular design and open-source nature.
Based on the pioneering work of zkSync Era,
the ZK Stack extends the core functionalities to enable developers
to build custom hyperchains—Layer 2 (L2) and Layer 3 (L3) solutions—that are tailored to specific needs
while ensuring compatibility and interoperability within the Ethereum ecosystem.

## Core features of the ZK Stack

### Sovereignty

The ZK Stack is built on the principle of sovereignty, granting developers complete control over their hyperchains.
This means that developers can:

- **Customize Chain Features**: Tailor aspects such as transaction rules,
data availability, and consensus mechanisms to suit specific use cases or performance requirements.
- **Own the Code**: Have full rights to the underlying code, providing the freedom to modify or enhance the chain as needed without external constraints.

### Seamless connectivity

Despite each hyperchain's independence, the ZK Stack ensures that they do not operate in isolation.
Instead, hyperchains are part of a cohesive network, linked by hyperbridges that facilitate seamless interactions:

- **Trustless Interoperability**: Hyperbridges allow for secure and reliable communication between different hyperchains
without needing to trust a central authority, making interactions as trustless as those on Ethereum itself.
- **Fast and Cost-Effective**: Communication and asset transfers between hyperchains are designed to be both rapid (completed within minutes)
and economical (incurring costs equivalent to a single standard transaction).
20 changes: 20 additions & 0 deletions content/10.zk-stack/10.components/100.block-explorer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Block Explorer
description: Explore the functionality of Block Explorer, a comprehensive tool for monitoring activities on your hyperchain.
---

[The Block Explorer](https://github.com/matter-labs/block-explorer)
is a tool designed to provide comprehensive insights into all activities occurring on a hyperchain.
This tool is especially useful for users and developers who need to monitor or interact with the blockchain. Block Explorer consists of three main components:

- **Block Explorer Worker:**
This indexer service manages hyperchain data.
Its main role is to collect data from the blockchain in real time, process this data, and populate a database that supports the API.

- **Block Explorer API:**
This component offers an HTTP API to access structured data from the hyperchain.
It retrieves data from the database maintained by the Block Explorer Worker.

- **Block Explorer App:**
This is the user interface that enables users and developers to navigate and examine transactions,
blocks, batches, contracts, tokens, and other elements within the hyperchain.
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
---
title: Smart Contracts
description: Explore the architecture of Layer 2 smart contracts on Ethereum and their role in the hyperchain ecosystem.
---

Smart contracts on Ethereum are pivotal in enabling rollups to inherit security and decentralization.
These contracts manage the state changes of rollups by storing information on Ethereum and providing validity proofs for state transitions.
They also facilitate communication mechanisms among different layers and systems.

In addition to the primary roles, some smart contracts also support the hyperchain ecosystem.
Detailed information on these contracts can be found in the [Shared Bridges](/zk-stack/components/shared-bridges) section.
The Shared Bridge utilizes these smart contracts to facilitate cross-chain interactions and enhance connectivity within the blockchain environment.

---
## Diamond

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

### DiamondProxy

The main contract uses [EIP-2535](https://eips.ethereum.org/EIPS/eip-2535) diamond proxy pattern. It is an in-house
implementation that is inspired by the [mudgen reference implementation](https://github.com/mudgen/Diamond). 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.

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.

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 [EIP-6900](https://eips.ethereum.org/EIPS/eip-6900) for
[zkStack](https://blog.matter-labs.io/introducing-the-zk-stack-c24240c2532a), where each hyperchain can implement a
sub-set of allowed implementation contracts.

### GettersFacet

Separate facet, whose only function is providing `view` and `pure` methods. It also implements
[diamond loupe](https://eips.ethereum.org/EIPS/eip-2535#diamond-loupe) which makes managing facets easier. This contract
must never be frozen.

### AdminFacet

Controls changing the privileged addresses such as governor and validators or one of the system parameters (L2
bootloader bytecode hash, verifier address, verifier parameters, etc), and it also manages the freezing/unfreezing and
execution of upgrades in the diamond proxy.

The admin facet is controlled by two entities:

- Governance - Separate smart contract that can perform critical changes to the system as protocol upgrades. This
contract controlled by two multisigs, one managed by Matter Labs team and another will be multisig with well-respected
contributors in the crypto space. Only together they can perform an instant upgrade, the Matter Labs team can only
schedule an upgrade with delay.
- 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

<!-- TODO: update link -->
<!-- The facet that handles L2 <-> L1 communication, an overview for which can be found in
[docs](../../../build/developer-reference/l1-l2-interop.md). -->

The Mailbox performs three functions:

- L1 <-> L2 communication.
- Bridging native Ether to the L2 (with the launch of the Shared Bridge this will be moved)
- Censorship resistance mechanism (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.

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

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

where

```solidity
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 zkEVM address derivation rule is different from the
Ethereum, so cross-chain exploits are already impossible. However, the zkEVM 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 ether. The user should include a `msg.value` when initiating a
transaction request on the L1 contract. 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 `L2EtherToken` system contracts. This will
burn the funds on L2, allowing the user to reclaim them through the `finalizeEthWithdrawal` function on the
`MailboxFacet`.

More about L1->L2 operations can be found
[here](https://github.com/code-423n4/2023-10-zksync/blob/main/docs/Smart%20contract%20Section/Handling%20L1→L2%20ops%20on%20zkSync.md).

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
[here](https://github.com/code-423n4/2023-10-zksync/blob/main/docs/Smart%20contract%20Section/Handling%20pubdata%20in%20Boojum.md).

### ExecutorFacet

A contract that accepts L2 batches, enforces data availability and checks the validity of zk-proofs.

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:

```solidity
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,
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 7 or 8 system logs. The 8th 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 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.

Implementation detail - function returns a magic value just like it is designed in
[EIP-1271](https://eips.ethereum.org/EIPS/eip-1271), but the magic value is 32 bytes in size.

## Bridges

Bridges are completely separate contracts from the Diamond. They are a wrapper for L1 <-> L2 communication on contracts
on both L1 and L2. Upon locking assets on L1, a request is sent to mint these bridged assets on L2. Upon burning assets
on L2, a request is sent to unlock them on L2.

Unlike the native Ether bridging, all other assets can be bridged by the custom implementation relying on the trustless
L1 <-> L2 communication.

### L1ERC20Bridge

The "standard" implementation of the ERC20 token bridge. Works only with regular ERC20 tokens, i.e. not with
fee-on-transfer tokens or other custom logic for handling user balances.

- `deposit` - lock funds inside the contract and send a request to mint bridged assets on L2.
- `claimFailedDeposit` - unlock funds if the deposit was initiated but then failed on L2.
- `finalizeWithdrawal` - unlock funds for the valid withdrawal request from L2.

The owner of the L1ERC20Bridge is the Governance contract.

### L2ERC20Bridge

The L2 counterpart of the L1 ERC20 bridge.

- `withdraw` - initiate a withdrawal by burning funds on the contract and sending a corresponding message to L1.
- `finalizeDeposit` - finalize the deposit and mint funds on L2. The function is only callable by L1 bridge.

The owner of the L2ERC20Bridge and the contracts related to it is the Governance contract.

### L1WethBridge

The custom bridge exclusively handles transfers of WETH tokens between the two domains. It is designed to streamline and
enhance the user experience for bridging WETH tokens by minimizing the number of transactions required and reducing
liquidity fragmentation thus improving efficiency and user experience.

This contract accepts WETH deposits on L1, unwraps them to ETH, and sends the ETH to the L2 WETH bridge contract, where
it is wrapped back into WETH and delivered to the L2 recipient.

Thus, the deposit is made in one transaction, and the user receives L2 WETH that can be unwrapped to ETH.

For withdrawals, the contract receives ETH from the L2 WETH bridge contract, wraps it into WETH, and sends the WETH to
the L1 recipient.

The owner of the L1WethBridge contract is the Governance contract.

### L2WethBridge

The L2 counterpart of the L1 WETH bridge.

The owner of the L2WethBridge and L2Weth contracts is the Governance contract.

## Governance

This contract manages calls for all governed zkEVM contracts on L1 and L2. Mostly, it is used for upgradability an
changing critical system parameters. The contract has minimum delay settings for the call execution.

Each upgrade consists of two steps:

- Scheduling - The owner can schedule upgrades in two different manners:
- Fully transparent data. All the targets, calldata, and upgrade conditions are known to the community before upgrade
execution.
- Shadow upgrade. The owner only shows the commitment to the upgrade. This upgrade type is mostly useful for fixing
critical issues in the production environment.
- Upgrade execution - the Owner or Security council can perform the upgrade with previously scheduled parameters.
- Upgrade with delay. Scheduled operations should elapse the delay period. Both the owner and Security Council can
execute this type of upgrade.
- Instant upgrade. Scheduled operations can be executed at any moment. Only the Security Council can perform this type
of upgrade.

Please note, that both the Owner and Security council can cancel the upgrade before its execution.

The diagram below outlines the complete journey from the initiation of an operation to its execution.

## 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.

## Allowlist

The auxiliary contract controls the permission access list. It is used in bridges and diamond proxies to control which
addresses can interact with them in the Alpha release. Currently, it is supposed to set all permissions to public.

The owner of the Allowlist contract is the Governance contract.

## Deposit Limitation

The amount of deposit can be limited. This limitation is applied on an account level and is not time-based. In other
words, each account cannot deposit more than the cap defined. The tokens and the cap can be set through governance
transactions. Moreover, there is an allow listing mechanism as well (only some allow listed accounts can call some
specific functions). So, the combination of deposit limitation and allow listing leads to limiting the deposit of the
allow listed account to be less than the defined cap.

```solidity
struct Deposit {
bool depositLimitation;
uint256 depositCap;
}

```

Currently, the limit is used only for blocking deposits of the specific token (turning on the limitation and setting the
limit to zero). And on the near future, this functionality will be completely removed.
Loading
Loading