diff --git a/slither/core/solidity_types/array_type.py b/slither/core/solidity_types/array_type.py index a86b76ae71..d00138364c 100644 --- a/slither/core/solidity_types/array_type.py +++ b/slither/core/solidity_types/array_type.py @@ -5,6 +5,7 @@ from slither.core.solidity_types.elementary_type import ElementaryType from slither.core.solidity_types.type import Type from slither.visitors.expression.constants_folding import ConstantFolding +import math if TYPE_CHECKING: from slither.core.expressions.binary_operation import BinaryOperation @@ -63,7 +64,11 @@ def is_dynamic_array(self) -> bool: def storage_size(self) -> tuple[int, bool]: if self._length_value: elem_size, _ = self._type.storage_size - return elem_size * int(str(self._length_value)), True + 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, True def __str__(self) -> str: diff --git a/tests/unit/core/test_data/storage_layout/storage_layout-0.8.10.sol b/tests/unit/core/test_data/storage_layout/storage_layout-0.8.10.sol index 28d1428eb4..47e924c9aa 100644 --- a/tests/unit/core/test_data/storage_layout/storage_layout-0.8.10.sol +++ b/tests/unit/core/test_data/storage_layout/storage_layout-0.8.10.sol @@ -36,6 +36,57 @@ contract StorageLayout { PackedStruct[] dynamicArrayOfStructs; PackedStruct[3] fixedArrayOfStructs; + struct SmallS { uint8 x; } + SmallS[3] public smallStructArr; + + struct StructWithFixedArr { + uint8 a; + uint128[2] b; + address[3] c; + uint256 d; + } + StructWithFixedArr public s1; + StructWithFixedArr[2] public arr_of_s1; + + struct StructWithDynamicArr { + uint256[] dynArr; + uint8 a; + } + StructWithDynamicArr public s2; + StructWithDynamicArr[] public dyn_arr_of_s2; + + uint256[][3] public fixed_arr_of_dyn; + uint256[3][] public fixed_arr_of_dyn2; + + struct InnerS { uint64 i; } + struct OuterS { + InnerS[2] arr; + uint256 j; + } + OuterS public s3; + + bytes16[3] public packableBytesArr; + + bytes31[3] public nonPackableBytesArr; + + struct StructWithBytes { + bytes16 b1; + bytes31 b2; + uint8 a; + } + StructWithBytes public s4; + StructWithBytes[2] public arr_of_bytes_struct; + + struct InnerNested { + uint128[3] fixedArr; + uint8 a; + } + struct OuterNested { + uint256[] dynamicArr; + InnerNested inner; + } + OuterNested[2] public nestedStructArr; + function store() external { require(_address == address(0)); _address = msg.sender; @@ -68,7 +119,7 @@ contract StorageLayout { fixedArrayOfStructs[0] = _packedStruct; fixedArrayOfStructs[1] = PackedStruct(false, 10); - mappingDynamicArrayOfStructs[_address].push(dynamicArrayOfStructs[0]); - mappingDynamicArrayOfStructs[_address].push(dynamicArrayOfStructs[1]); + mappingDynamicArrayOfStructs[_address].push(dynamicArrayOfStructs[0]); + mappingDynamicArrayOfStructs[_address].push(dynamicArrayOfStructs[1]); } -} +} \ No newline at end of file