- Total Prize Pool: $250,000 in USDC
- HM awards: $208,526 in USDC
- Analysis awards: $0 in USDC
- QA awards: $5,487 in USDC
- Bot Race awards: $0 USDC
- Gas awards: $5,487 in USDC
- Judge awards: $18,000 in USDC
- Lookout awards: $12,000 in USDC
- Scout awards: $500 in USDC
- Join C4 Discord to register
- Submit findings using the C4 form
- Read our guidelines for more details
- Starts March 7, 2024 20:00 UTC
- Ends March 28, 2024 20:00 UTC
The 4naly3er report can be found here.
Note for C4 wardens: Anything included in the 4naly3er report is considered a publicly known issue and is ineligible for awards.
DefaultAccount, while it should always behave as an EOA (i.e. any call to it should return success(0,0)
), if called with a selector of one of its methods and incorrect ABI-encoding of its parameters, will fail with empty error. This happens due to the fact that the ABI decoding fails before the modifier is triggered.
According to the EIP-161, an account is “empty” when it meets the following conditions: it has no deployed code, its nonce value is zero, and it holds a balance of zero. According to EIP-1052, the extcodehash of an empty account should evaluate to bytes32(0)
, otherwice it is keccak256(deployedBytecode)
. On zkSync, bytes32(0)
is returned in case there is no deployed code and nonce is zero regardless of the account balance.
In the current implementation, the mechanism for bytecode compression is not strictly unambiguous. That means the validator has the flexibility to choose a less efficient compression for the bytecode to increase the deployment cost for the end user. Besides that, there is another non-fixed issue, that gives a way for the operator to forces the user to pay more for the bytecode compression or even burn all the transaction gas during bytecode compression verification.
All unfixed issues from the previous audits are considered out of scope.
More known differences from Ethereum can be found in our documentation.
zkSync Era is a fully-fledged Layer-2 scaling solution that enhances Ethereum's scalability and efficiency. It achieves this through a combination of smart contracts deployed on the Ethereum and the zkEVM, which facilitates EVM-compatible smart contract execution in a more efficient manner.
This repository is dedicated to providing comprehensive documentation and code pertaining exclusively to the Smart Contracts aspect of the zkSync Era Protocol. Below, you will find a high-level overview of the smart contracts section, accompanied by relevant documentation links. We highly encourage auditors to consult these resources for an in-depth understanding of the protocol's smart contracts framework before and during the audit.
As part of this security audit, we are focusing on the changes and updates made to the smart contracts since our last security review with code4rena. Our goal is to ensure the continued security, efficiency, and reliability of the zkSync Era platform as it evolves.
Relevant Documentation:
- L1 smart contracts
- L1 ecosystem contracts
- System Contracts/Bootloader Description
- zkSync Era Fee Model
- Handling L1→L2 Ops on zkSync
- Batches & L2 Blocks on zkSync
- Elliptic Curve Precompiles
- Handling Pubdata
- Pubdata post EIP-4844
The VM section is related to the zkSync Era Virtual Machine.
- ZkSync Era Virtual Machine Primer
- This primer is designed to provide auditors with a foundational understanding of the zkSync Era Virtual Machine. It offers insights into the operational mechanics and integral components of EraVM, serving as an essential guide for those seeking to explore the zkSync EraVM environment.
- zkSync Era: The Equivalence Compiler Documentation
- The document describes how zkSync Solidity compiler represents high-level programming language constructions into low-level EraVM instruction set, how to use unique features without extending Solidity language with new syntax and why system contracts are needed.
- Ensure to go through each section and related documents thoroughly.
- Keep in mind the overall working of the zkSync protocol while reviewing individual components.
- Review the code and documentation with a focus on security, correctness, and optimization, particularly concerning gas consumption.
For any clarifications, doubts, or discussion, please contact Code4rena staff, and we will address your concerns promptly.
- Documentation: https://era.zksync.io/docs/
- Website: https://zksync.io/
- Twitter: https://twitter.com/zksync
- Discord: https://join.zksync.dev/
- Previous Audits: https://era.zksync.io/docs/reference/troubleshooting/audit-bug-bounty.html
Contract | SLOC | Libraries used |
---|---|---|
contracts/ethereum/contracts/bridge/L1ERC20Bridge.sol | 119 | @openzeppelin |
contracts/ethereum/contracts/bridge/L1SharedBridge.sol | 448 | @openzeppelin |
contracts/ethereum/contracts/bridgehub/Bridgehub.sol | 246 | @openzeppelin |
Contract | SLOC | Libraries used |
---|---|---|
contracts/ethereum/contracts/governance/Governance.sol | 133 | @openzeppelin |
Contract | SLOC | Libraries used |
---|---|---|
system-contracts/bootloader/bootloader.yul | 2314 |
Contract | SLOC | Libraries used |
---|---|---|
contracts/zksync/contracts/bridge/L2SharedBridge.sol | 103 | @openzeppelin |
contracts/zksync/contracts/bridge/L2StandardERC20.sol | 97 | @openzeppelin |
Contract | SLOC | Libraries used |
---|---|---|
contracts/ethereum/contracts/state-transition/Verifier.sol | 1161 | |
contracts/ethereum/contracts/upgrades/Upgrade_4844.sol | 11 | |
contracts/ethereum/contracts/upgrades/Upgrade_v1_4_1.sol | 27 | |
contracts/ethereum/contracts/common/Dependencies.sol | 3 | @openzeppelin |
contracts/zksync/contracts/Dependencies.sol | 3 | @openzeppelin |
contracts/zksync/contracts/Config.sol | 3 | |
contracts/zksync/contracts/TestnetPaymaster.sol | 51 | @openzeppelin |
contracts/zksync/contracts/bridge/L2WrappedBaseToken.sol | 116 | @openzeppelin |
It is important to examine access control and permissions for any contract that contains potentially dangerous logic (including upgrades). While the assumption is that either governance or security council are not malicious, neither governance, nor the security council should be able to circumvent the limitations imposed on them.
Special scrutiny should be paid to the powers of the operator. While currently the operator is controlled by Matter Labs and is also partially trusted (for instance, it is responsible for supplying the correct L1 gas price), it should never be able to directly steal users' funds or conduct malicious upgrades. An example of such an issue, which was detected and resolved by the team before the contest.
Another important invariant is that the state of the rollup can be restored based on the pubdata sent to L1. Make sure that for a block that gets executed regardless of what a potentially malicious operator does:
- Users can always get preimages for all the bytecodes that were deployed to the system.
- Users can always recover the leaves of the Merkle tree of L2->L1 logs.
- Users can always recover the storage merkle tree.
In general, there should be always a possibility to have a new operator that fully recovers the state available solely from L1 and is able to execute transactions successfully.
Make sure that access to any dangerous logic is well-constrained. For instance:
- Access to potentially dangerous system contracts' methods is protected by the
isSystemCall
flag, permitting only the contracts that are aware of the zkSync-specific features to call it. - Using innocent Solidity code without zkSync-specific features should not lead to unexpected behaviour. An example of a relevant finding.
- If you have a public code repo, please share it here: https://github.com/matter-labs/era-contracts
- How many contracts are in scope?: 114
- Total SLoC for these contracts?: 10,663
- How many external imports are there?: 13
- How many separate interfaces and struct definitions are there for the contracts within scope?: 94
- Does most of your code generally use composition or inheritance?: inheritance
- Is this an upgrade of an existing system?: Yes
- Check all that apply (e.g. timelock, NFT, AMM, ERC20, rollups, etc.): timelock, ERC20, rollups
- Is there a need to understand a separate part of the codebase / get context in order to audit this part of the protocol?: No
- Please describe required context: ZK rollup
- Does it use an oracle?: No
- Describe any novel or unique curve logic or mathematical models your code uses: No
- Is this either a fork of or an alternate implementation of another project?: No
- Does it use a side-chain?: No
- Describe any specific areas you would like addressed: Logical errors, malicious input for bootloader, EVM compatibility issues
rm -Rf 2024-03-zksync || true && git clone https://github.com/code-423n4/2024-03-zksync.git && cd 2024-03-zksync/code/contracts/ethereum && yarn --ignore-engines && yarn test:foundry
rm -Rf 2024-03-zksync || true && git clone https://github.com/code-423n4/2024-03-zksync.git && cd 2024-03-zksync/code/contracts/ethereum && yarn --ignore-engines && yarn test
Run the test-node from the code/system-contracts
in the first terminal:
yarn # if first time
yarn test-node
Then run the tests in the second:
yarn test
⚠️ You should rerun the test-node for every tests run
Run the test-node from the code/system-contracts
in the first terminal:
yarn # if first time
yarn test-node
Then run the tests from the code/contracts/zksync
in the second:
yarn # if first time
yarn test
⚠️ You should rerun the test-node for every tests run
Employees of zkSync and employees' family members are ineligible to participate in this audit.