crytic / slither

Static Analyzer for Solidity and Vyper
https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/
GNU Affero General Public License v3.0
5.33k stars 967 forks source link

The function get_storage_slot in read_storage.py cannot accurately determine the slot where variables in the structure are located. #2524

Open Subway2023 opened 3 months ago

Subway2023 commented 3 months ago

Describe the issue:

If the first variable x in the structure has a size of m bits (m < 256) and the second variable y has a size of n bits (n > 256 - m), then variables x and y cannot be stored in the same slot. However, the get_storage_slot function mistakenly assumes that both are stored in the same slot.

Code example to reproduce the issue:

srs = SlitherReadStorage([c], 20)
srs.get_all_storage_variables()
srs.get_storage_layout()
print("srs._slot_info",srs._slot_info)
contract C {
    struct S {
        uint64 x;
        uint256 y;
    }
    S s;
}

Version:

0.10.3

Relevant log output:

srs._slot_info {'s': SlotInfo(name='s', type_string='C.S', slot=0, size=512, offset=0, value=None, elems={'x': SlotInfo(name='s.x', type_string='uint64', slot=0, size=64, offset=0, value=None, elems={}), 'y': SlotInfo(name='s.y', type_string='uint256', slot=0, size=256, offset=64, value=None, elems={})})}

It shows that the slot of y is 0, which is an error.

0xalpharush commented 3 months ago

This should probably check if offset + size is greater than 256 https://github.com/crytic/slither/blob/9a5b4f5cff9db6475c5badff18f9882180d5f344/slither/tools/read_storage/read_storage.py#L585