-
Notifications
You must be signed in to change notification settings - Fork 153
Description
Hi team 👋
I ran into an issue with the ContractImmutable exercise.
The provided tests currently use deployment gas as a proxy for immutability:
uint256 startGas = gasleft();
contractImmutable = new ContractImmutable(10);
uint256 gasUsed = startGas - gasleft();
if (gasUsed < 90000) assertFalse(false);
else assertFalse(true);On my setup (latest forge-std v1.5.0 submodule), the tests are failing even with the correct solution:
contract ContractImmutable {
uint256 immutable public value;
constructor(uint256 _value) {
value = _value;
}
}The deployment gas sometimes exceeds the 90k threshold, so the test fails even though value is properly declared immutable.
✅ Suggested solution
Instead of measuring gas, we can directly verify immutability by checking that the variable is not stored in contract storage. Immutable variables are compiled into the bytecode and won’t occupy a storage slot.
Here’s a more reliable test:
function testImmutableNotInStorage() external {
contractImmutable = new ContractImmutable(99);
// slot 0 would hold `value` if it were a normal state var
bytes32 slot0 = vm.load(address(contractImmutable), bytes32(uint256(0)));
// since `value` is immutable, it won't be in storage
assertEq(slot0, bytes32(0));
assertEq(contractImmutable.value(), 99);
}This avoids false negatives by proving immutability directly, rather than indirectly via gas usage.
💡 I’d be happy to open a pull request to update the tests if the team thinks this approach makes sense.
Thanks for the great exercises 🚀
