Skip to content

Tests for ContractImmutable failing due to gas check — suggest immutability check instead #50

@jmakwana0x1

Description

@jmakwana0x1

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 🚀


Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions