Fix incorrect storage layout calculation for fixed-size arrays - #3068
Fix incorrect storage layout calculation for fixed-size arrays#3068Nakamura73914 wants to merge 5 commits into
Conversation
|
|
|
Hi, thanks for the PR. The issue is real however your proposed fix is not the best way to do it. For example the storage layout of the following example would be wrong. struct S { address[10] inner; }
contract C {
S s;
uint b;
}A better fix is to correctly compute the storage_size of the ArrayType slither/slither/core/solidity_types/array_type.py Lines 62 to 67 in 050cc0a Something like this should work without any other changes @property
def storage_size(self) -> tuple[int, bool]:
if self._length_value:
elem_size, _ = self._type.storage_size
length = int(str(self._length_value))
if elem_size > 32:
return length * math.ceil(elem_size / 32) * 32, True
elem_per_slot = 32 // max(elem_size, 1)
return math.ceil(length / elem_per_slot) * 32, True
return 32, TruePlease also add a few test cases. |
Thanks for sharing this approach—it's definitely much better than my original change. I've pulled your code and added some tests to cover it. All tests passed smoothly. |

This PR fixes a bug in
_compute_storage_layoutwhere Slither incorrectly calculated the storage slots for fixed-size arrays (e.g.,address[10],bytes20[10]).Root Cause
Slither incorrectly treated fixed-size arrays as a continuous byte stream (
math.ceil((elem_size * length) / 32)). However, Solidity mandates that array elements cannot cross 32-byte slot boundaries.For example,
address[10](20 bytes each):ceil(200 / 32) = 7slots.This offset error caused all subsequent state variables to be assigned incorrect slot numbers.
Fix
The fix intercepts fixed-size arrays (
ArrayTypewhereis_dynamicisFalse) and applies the correct Solidity packing logic:math.ceil(elem_size / 32)slots.32 // elem_size), and then calculate the total slots needed for all elements.A
try-exceptblock is retained as a fallback to prevent Slither from crashing if AST parsing for array length fails unexpectedly.Testing & Verification
uint256[10]uint128[10]bytes1[10]address[10]bytes20[10]