Solidity – Why Functions Accessing Immutable Variables Are Not Pure

constantimmutablepuresoliditystorage

My understanding is that immutable variables are basically equivalent to constant variables however the former is initialised in the constructor whereas the later at declaration, however both are interpolated into the bytecode therefore no additional gas is incurred whenever they are used since they are not stored in state and hence do not have to be read from state.

Why then can functions that access immutable variables not be considered pure whereas functions that access constant variables are?

pragma solidity ^0.8.0;

contract Immutable {
    
    uint constant number1 = 1;
    uint immutable number2;
    
    constructor() {
        number2 = 2;
    }

    // compiles fine
    function getNumber1() pure external returns(uint) {
        return number1;
    }
    
    // compile error
    function getNumber2() pure external returns(uint) {
        return number2;
    }    
}

Best Answer

Not reading the storage is not the only requisite to be a pure function.

Summarizing discussions made on GitHub about this topic, pure implies that the output can be computed without any state, other than the functions themselves.

From the official Solidity documentation:

Pure Functions

Functions can be declared pure in which case they promise not to read from or modify the state. In particular, it should be possible to evaluate a pure function at compile-time given only its inputs and msg.data, but without any knowledge of the current blockchain state. This means that reading from immutable variables can be a non-pure operation.

Quoting chriseth:

In the following example the value of the immutable depends on the blockchain state:

contract C {
 uint immutable x = block.number;
}

A copy of the contract deployed at a different time will have a different value. The idea of a pure function is that if you compile it again and put it in a different contract, it will return the same value, which it does not if it accesses the immutable in the example above.