Hardcoded storage slot number
The addressListStart
constant is set to the storage slot of the first element of the dynamic addressList
array. This practice is error prone as the hardcoded value must be updated as the storage layout of the contract changes during development.
The following snippet demonstrates how it is possible to initialize an immutable variable with the storage slot of the first element of the array without hardcoding it.
pragma solidity ^0.8.13;
contract Storage {
address[] addressList;
uint256 private immutable addressListStart;
constructor() {
// Computed according to Solidity documentation
// https://docs.soliditylang.org/en/v0.8.17/internals/layout_in
// _storage.html#mappings-and-dynamic-arrays
uint _addressListStart;
assembly { _addressListStart := addressList.slot }
addressListStart = uint256(keccak256(abi.encode(_addressListStart)));
addressList.push(address(0x123));
addressList.push(address(0x456));
addressList.push(address(0x789));
}
function getSlot() public view returns (uint i) {
// Accessing immutable variables directly from YUL is not supported
uint _addressListStart = addressListStart;
assembly {
i := _addressListStart
}
}
function read(uint idx) public view returns (address addr) {
return addressList[idx];
}
function read_asm(uint idx) public view returns (address addr) {
// Accessing immutable variables directly from YUL is not supported
uint _addressListStart = addressListStart;
assembly {
addr := sload(add(_addressListStart, idx))
}
}
}