matter-labs / era-contracts

Smart Contract Submodule For zkSync Era
MIT License
481 stars 341 forks source link

Compilation Error When Using `era-contracts` in Foundry Projects #802

Open dutterbutter opened 1 month ago

dutterbutter commented 1 month ago

Description:

When users attempt to use era-contracts into their Foundry projects by running the following command:

forge install matter-labs/era-contracts

They encounter a compilation error due to an unresolved placeholder in the Constants.sol file:

Compiler run failed:
Error (6933): Expected primary expression.
  --> lib/era-contracts/system-contracts/contracts/Constants.sol:20:44:
   |
20 | uint160 constant SYSTEM_CONTRACTS_OFFSET = {{SYSTEM_CONTRACTS_OFFSET}}; // 2^15
   |                                            ^
Error:
Compilation failed

This issue occurs because SYSTEM_CONTRACTS_OFFSET is currently a placeholder ({{SYSTEM_CONTRACTS_OFFSET}}) rather than a resolved constant value.

Problematic Line:

The problematic line can be found here in the era-contracts repository: lib/era-contracts/system-contracts/contracts/Constants.sol:20

uint160 constant SYSTEM_CONTRACTS_OFFSET = {{SYSTEM_CONTRACTS_OFFSET}}; // 2^15

Impact:

This issue leads to friction in the developer experience, as users are unable to compile their projects upon immediate installation. Rather they need to go into era-contracts and build first or replace with a constant value. This additional step although may seem negligible is a point of friction.

Suggested Solution:

I am unaware of the implications, if any, to replace the placeholder {{SYSTEM_CONTRACTS_OFFSET}} with an actual constant value directly in the Constants.sol file (e.g. 0x8000) but it would be nice not to have to do any additional steps to make use of era-contracts.

dutterbutter commented 2 weeks ago

Improved understanding of the issue:

When we test system contracts we use our test-node (to have an environment that runs zkEVM code). However, unlike usual tests, here we have to replace system contracts themselves, i.e. if there is some issue in some code during the tests, the entire environment would get corrupted. That's why we have two modes in our contracts: "test mode" where all system contracts have addresses 0x9000 + X, and "prod mode" where all system contracts have addresses 0x8000 + X. So that when we replace a contract under address 0x9000 + X with a mock the entire testing infra does not collapse due to changes in the system contracts