immutable
variables?<aside> đź’ˇ https://blog.soliditylang.org/2020/05/13/immutable-keyword/
</aside>
… during contract creation, a dedicated memory area is reserved for the values of immutables. The constructor code can then store the intended values for the immutables in that memory area. The compiler-generated part of the creation code that is executed after the constructor and returns the contract’s runtime code will read back the values of the immutables and insert them into all occurrences in the runtime bytecode.
immutable
variables in solidity are stored in the contract’s runtime bytecode, however their values are not known at compile-time. To get around this, the solidity compiler instead adds placeholders that are replaced with PUSH32 <value>
upon the immutables being defined in the contract’s constructor. The runtime bytecode is then altered within the constructor, at runtime to fill these placeholders. This is much different from the behavior of constant
variables, which have known values at compile-time and can be directly inlined before deployment.
immutable
type to HuffAdding Immutables to Huff would be another high-level feature added to the compiler, which is something we have been trying to avoid for the most part. Immutables are not entirely necessary, as the compiler already supports constants as well as it storing constructor arguments at the end of the runtime bytecode. However, there are some cases where they can be useful.
Arguments against adding immutable
:
foundry-huff
in a foundry script should be sufficient due to the fact that the Huff contract is re-compiled each time the HuffDeployer
runs. After contract A is deployed, we have its address and can encode it into contract B’s constructor arguments before it is compiled.HuffDeployer
re-compiles each time a deployment is ran, they can be inlined during compilation.HuffDeployer
.huff-clones
covers the need for cheap, parametrizable clones with immutable arguments without the need for extra compiler features. Of course, this only covers the factory-style use-case for immutables, and it functions differently.Arguments for adding immutable
:
PUSH32
op. With constructor args, we must CODECOPY
them into memory and then MLOAD
them on to the stack. constant
reads, which are also just a PUSH<N>
op, can still be used of course, but as of right now they cannot be set in deploy scripts (see the proposed solution below).immutable
values. If the developer wants the option to do so, true solidity-style immutables can be a useful feature.After looking at the pros/cons, it seems there might be a solution that lies in the middle. Instead of adding an immutable
type, we could add a new flag to the CLI that allows setting new / overriding existing constant
values for the current compilation. With this method, we can add support for the new CLI flag to foundry-huff
, and developers could easily assign constant values from their deployment scripts.
This way:
constant
values, allowing for greater flexibility in deployment scripts.constant
value reads in Huff already compile down to a single PUSH<N>
op, just like immutable
does in solidity. This is much cheaper than CODECOPY
ing a constructor argument into memory and reading it.