# ZKSYNC1-2021-01 Post Mortem

# Summary

On July 26, 2021, we were notified of a critical vulnerability in zkSync’s smart contracts that was introduced in zkSync’s Version 5.1 upgrade (opens new window) on July 1. The fix was deployed (opens new window) on July 27, and all funds are safe. At the time of the report, zkSync had $8.5m USD in total value locked and was the only severe vulnerability in the zkSync protocol since genesis to date.

# Technical Details

# The Vulnerability

To initialize new upgrades, the initialize (opens new window) function inside the zkSync main contract is called:

zksync1-2021-01-bug.png

This function can be external because the Proxy contract which uses this contract as a target for delegatecalls intercepts all calls of the function with such signature. However, this meant initialize could be called on the target contract with any parameters at any time, allowing anyone to set additionalZkSync in the target contract storage to any address.

If the attacker sets additionalZkSync to an address that would execute the SELFDESTRUCT opcode on any entry, and then call any function on the zkSync main contract that uses logic from additionalZkSync via delegatecall, the main zkSync target contract could have been destroyed and all funds would have been frozen.

Funds could not be stolen because the Proxy contract owns the rollup assets and it did not contain a vulnerability, only the code of the Proxy’s target.

# The Fix

Because there is a 3-day timelock from the initialization of the upgrade and the execution, we introduced the fix in a way that those who checked the code diff during the upgrade would not find the vulnerability.

To fix the vulnerability, we updated the initializeReentrancyGuard function to the new OpenZeppelin version and added a check that makes it impossible to reinitialize ReentrancyGuard and the main contract’s target consequently. For the updated version, we initialized zkSync’s target contract while deploying, so no one can reinitialize it.

zksync1-2021-01-fix.png

# Bug Bounty

In accordance with our Bug Bounty Policy, we have paid the person who made the disclosure our maximum bounty of $500,000 due to the severity of the bug found.

# Conclusion

Following this vulnerability, we have conducted a thorough internal review of our security approach and processes, introducing a number of systematic improvements not only to fix the root cause, but also to make our entire system more robust in bug prevention and reaction.

To better manage the security of a rapidly upgrading protocol, we: upgraded our security council to allow for instant upgradability with 9/15 signatures, improved our bug bounty program and are partnering with ImmuneFi. These improvements are explored in depth in this article (opens new window).

In the security section of our documentation, we have also added a JSON-formatted list of known bugs and updated our vulnerability disclosure policy.