I have been encountering challenges when testing contracts that utilize immutable state variables. As we know, immutable variables are assigned only once during contract deployment and cannot be modified thereafter. This offers advantages such as efficient reading, gas optimization, and security, but makes it hard to test various scenarios as I have to redeploy the contract each time I want to change the value of an immutable variable. Previously, I would simply create a contract for testing purposes that extends the target contract in order to expose any public state variables that need to be modified to simulate different scenarios, as shown in the example code below:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.15;
import "../Hifi.sol";
/// @author Hifi
/// @dev Strictly for test purposes. Do not use in production.
contract GodModeHifi is Hifi {
constructor(address account, address minter_) Hifi(account, minter_) {}
function __godMode_setCheckpoint(
address delegatee,
uint32 index,
uint32 blockNumber,
uint32 newVotes
) external {
checkpoints[delegatee][index] = Checkpoint(blockNumber, newVotes);
}
function __godMode_setNumCheckpoints(address account, uint32 newNumCheckpoints) external {
numCheckpoints[account] = newNumCheckpoints;
}
}
The method above would not work with immutable state variables. I'm looking for an alternative method that could help me improve the testability of my contracts without compromising the benefits of utilizing immutable state variables (gas optimization, security, etc.).
** Example above is from hifi-finance/hifi-governance.
** Disclaimer: I work at Hifi Finance as a full-time blockchain engineer.