Open c4-submissions opened 1 year ago
bytes032 marked the issue as primary issue
bytes032 marked the issue as sufficient quality report
The impact is medium, the probablity is low.
So, low severity can be fair.
miladpiri (sponsor) confirmed
miladpiri marked the issue as disagree with severity
While I agree with low impact, this seem to be an inconsistency in the implementation of the EVM, which makes the finding notable
I would have a different perspective for an ERC or some implementation, however in this case this is an opcode that behaves differently (although in a edge case)
At this time, I believe Medium Severity is most appropriate as the finding demonstrates an inconsistent behaviour of the EVM with the zkSyncVM
I agree with the impact, but believe that such finding belongs to the Medium Severity classification as it breaks a coding convention that goes beyond a best-practice
GalloDaSballo marked the issue as selected for report
Lines of code
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/contracts/AccountCodeStorage.sol#L89
Vulnerability details
Impact
The divergences in the emulation of the
extcodehash
EVM opcode within zkSync Era carry several potential impacts, specially on Developers relying on zkSync Era's assurance that it emulates theextcodehash
opcode as per EIP-1052 might encounter unexpected behavior in their smart contracts.Proof of Concept
The
getCodeHash
function within the zkSync Era is designed to emulate the functionality of theextcodehash
Ethereum Virtual Machine (EVM) opcode, as laid out in the Ethereum Improvement Proposal 1052 (EIP-1052). https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/contracts/AccountCodeStorage.sol#L89However, it's important to recognize that this function does not exhibit precisely identical behavior to the EVM's
extcodehash
opcode. There are specific discrepancies:EIP-161 defines an account as "empty" when it satisfies certain criteria: no code, a nonce value of zero, and a balance of zero. According to EIP-1052, the
extcodehash
of an empty account should evaluate tobytes32(0)
. In the zkSync Era, the behavior aligns with this definition whencodeHash
is0x00
,getRawNonce(account)
is0
, andisContractConstructing(codeHash)
isfalse
. If an account has nonzero balance, then based on the definition of EIP-161, it will not be considered as an empty account anymore. In this case, that account will be considered as an account with no code. So,extcodehash
of such account will bekeccak256("")
in EVM. The issue is that, zkSync Era returnsbytes32(0)
regardless of the balance of the account. It only cares about the nonce and the code.Based on EIP-1052, the
extcodehash
of an precompile contract is eitherkeccak256("")
orbytes32(0)
. For instance, theextcodehash
ofaddress(0x02)
—representing the SHA-256 precompile contract in the EVM—should bekeccak256("")
because it has no code, a nonce of zero, and a nonzero balance. In contrast, the zkSync Era consistently returnskeccak256("")
for precompile contracts, regardless of their balances. The zkSync Era's behavior is based solely on whether the address is lower/equal toCURRENT_MAX_PRECOMPILE_ADDRESS
.These observed inconsistencies could potentially raise concerns for developers who rely on zkSync Era's assertion that it accurately simulates the
extcodehash
EVM opcode as dictated by the EIP-1051 specification.Tools Used
Recommended Mitigation Steps
The following code is recommended to simulate the
extcodehash
EVM opcode precisely based on EIP-1052.https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/contracts/AccountCodeStorage.sol#L89
Assessed type
Context