`CURRENT_MAX_PRECOMPILE_ADDRESS` does not include `keccak256` precompile
I'm referring to the Constants:
address constant ECRECOVER_SYSTEM_CONTRACT = address(0x01);
address constant SHA256_SYSTEM_CONTRACT = address(0x02);
/// @dev The current maximum deployed precompile address.
/// Note: currently only two precompiles are deployed:
/// 0x01 - ecrecover
/// 0x02 - sha256
/// Important! So the constant should be updated if more precompiles are deployed.
uint256 constant CURRENT_MAX_PRECOMPILE_ADDRESS = uint256(uint160(SHA256_SYSTEM_CONTRACT));
I might be confused, but shouldn't this be 3 contracts? The keccak256 precompile is deployed at the address 0x0000000000000000000000000000000000008010 if am not wrong.
Hey @pcaversaccio, thanks for looking into the code!
We want to distinguish all the EVM precompiles (ecrecover/sha256/RIPEMD-160/...) and zkSync-specific ones (only keccak256 at the moment). The idea behind this is that EVM precompiles are guaranteed to have zero code size and the zkSync specific does not really need to hold this invariant.
Reference of place where constant is used:
- https://github.com/matter-labs/era-system-contracts/blob/main/contracts/AccountCodeStorage.sol#L131
The idea behind this is that EVM precompiles are guaranteed to have zero code size
Are you sure this is enforced in the clients? Check for instance create I don't see how it would revert if I would deploy via an account nonce and address that leads to the 0x01 address for instance (would appreciate if you could point me to the code, where such a revert is enforced). The same reasoning applies to Create2.
So if I understand it correctly, in theory, there is the possibility to deploy a contract to 0x0000000000000000000000000000000000008010 (i.e. keccak256)? What's the underlying reason for not enforcing the similar EVM behavior?
The contract deployer is a contract that is responsible for all create/create2 calls. Here is the place which prevents users from deploying on the system contracts zone (still a very unlikely event).
- https://github.com/matter-labs/era-system-contracts/blob/main/contracts/ContractDeployer.sol#L260
Oh I see, that makes sense. But the remaining question is whether this behavior is enforced by the clients on Ethereum. See above my links to the Geth implementations.
The deploying to the address(0x01) is basically a hash collision. If it will be the case, we will have a bigger problem.
From what I see on the Geth, there is no check on not deploying to the precompile address. But it is fine.
- That said, the probability is extremally low and will lead to other biggest issues if occurs.
- The real motivation was holding an EVM invariant
extcodesize(precompile_address) == 0andextcodehash(precompile_address) == 0 || extcodehash(precompile_address) == keccak256("")(EIP-1052)
Fully agree, I just wanted to challenge your statement: "The idea behind this is that EVM precompiles are guaranteed to have zero code size" => This is actually a probabilistic statement that holds P-a.s. (and let's hope it won't ever be broken) and is not enforced by the EVM implementations on Ethereum.
For the sake of documentation (for anyone reading this issue), the second bullet point refers to this:

A non-existent account in EIP-1052 refers to an address that does not adhere to EIP-55 correct?
"The idea behind this is that EVM precompiles are guaranteed to have zero code size" => This is actually a probabilistic statement that holds P-a.s. (and let's hope it won't ever be broken) and is not enforced by the EVM implementations on Ethereum.
Agree, it is a probabilistic statement. However, I would still stick to the current invariant enforcement.
A non-existent account in EIP-1052 refers to an address that does not adhere to EIP-55 correct?
Don't understand how the non-existent account relates to the EIP-55 (address checksum). Could you please elaborate?
Agree, it is a probabilistic statement. However, I would still stick to the current invariant enforcement.
Yes, fully agreed. So even the black swan event couldn't happen :)
Don't understand how the non-existent account relates to the EIP-55 (address checksum). Could you please elaborate?
Actually, I was confused - I wanted to refer to EIP-161. So is my understanding of the following correct on zkSync:
- An account is considered empty when it has no code and zero nonce and zero balance.
But what's your understanding of a non-existent account on zkSync? As stated in EIP-158 "Whenever the EVM checks if an account exists, emptiness is treated as equivalent to nonexistence"; so I don't see any difference anymore. Or in other words, using the following condition:
extcodehash(precompile_address) == 0 || extcodehash(precompile_address) == keccak256("")
When is the first condition true?
@vladbochok a quick reminder about my question above
Evm
AGREE