from pathlib import Path from slither import Slither from slither.core.expressions import CallExpression from slither.core.expressions.identifier import Identifier from slither.core.expressions.literal import Literal from slither.core.variables.state_variable import StateVariable from slither.core.variables.local_variable import LocalVariable TEST_DATA_DIR = Path(__file__).resolve().parent / "test_data" def test_yul_parser_assembly_slot(solc_binary_path) -> None: # mstore(0x0, bucketId) # mstore(0x20, _counters.slot) data = { '0x0': 'bucketId', '0x20': '_counters' } solc_path = solc_binary_path("0.8.18") slither = Slither(Path(TEST_DATA_DIR, "assembly_storage_slot.sol").as_posix(), solc=solc_path) contract = slither.get_contract_from_name('XXX')[0] func = contract.get_function_from_full_name('getPackedBucketGlobalState(uint256)') calls = [node.expression for node in func.all_nodes() if node.expression and 'mstore' in str(node.expression)] for call in calls: assert isinstance(call, CallExpression) memory_location = call.arguments[0] value = call.arguments[1] assert isinstance(memory_location, Literal) assert isinstance(value, Identifier) assert value.value.name == data[memory_location.value] if value.value.name == '_counters': assert isinstance(value.value, StateVariable) elif value.value.name == 'bucketId': assert isinstance(value.value, LocalVariable)