diff --git a/slither/core/compilation_unit.py b/slither/core/compilation_unit.py index d97b7fbf5e..2144d4c81e 100644 --- a/slither/core/compilation_unit.py +++ b/slither/core/compilation_unit.py @@ -18,6 +18,7 @@ from slither.core.declarations.function_top_level import FunctionTopLevel from slither.core.declarations.using_for_top_level import UsingForTopLevel from slither.core.declarations.structure_top_level import StructureTopLevel +from slither.core.solidity_types.type_alias import TypeAliasTopLevel from slither.core.scope.scope import FileScope from slither.core.variables.state_variable import StateVariable from slither.core.variables.top_level_variable import TopLevelVariable @@ -46,6 +47,7 @@ def __init__(self, core: "SlitherCore", crytic_compilation_unit: CompilationUnit self._pragma_directives: List[Pragma] = [] self._import_directives: List[Import] = [] self._custom_errors: List[CustomError] = [] + self._user_defined_value_types: Dict[str, TypeAliasTopLevel] = {} self._all_functions: Set[Function] = set() self._all_modifiers: Set[Modifier] = set() @@ -215,6 +217,10 @@ def using_for_top_level(self) -> List[UsingForTopLevel]: def custom_errors(self) -> List[CustomError]: return self._custom_errors + @property + def user_defined_value_types(self) -> Dict[str, TypeAliasTopLevel]: + return self._user_defined_value_types + # endregion ################################################################################### ################################################################################### diff --git a/slither/solc_parsing/slither_compilation_unit_solc.py b/slither/solc_parsing/slither_compilation_unit_solc.py index 4f6f9ac5c8..6e7de2db9d 100644 --- a/slither/solc_parsing/slither_compilation_unit_solc.py +++ b/slither/solc_parsing/slither_compilation_unit_solc.py @@ -336,6 +336,7 @@ def parse_top_level_from_loaded_json( user_defined_type = TypeAliasTopLevel(original_type, alias, scope) user_defined_type.set_offset(top_level_data["src"], self._compilation_unit) + self._compilation_unit.user_defined_value_types[alias] = user_defined_type scope.user_defined_types[alias] = user_defined_type else: diff --git a/slither/solc_parsing/solidity_types/type_parsing.py b/slither/solc_parsing/solidity_types/type_parsing.py index b62f908d1f..91e320a425 100644 --- a/slither/solc_parsing/solidity_types/type_parsing.py +++ b/slither/solc_parsing/solidity_types/type_parsing.py @@ -243,7 +243,7 @@ def parse_type( sl = caller_context.compilation_unit next_context = caller_context renaming = {} - user_defined_types = {} + user_defined_types = sl.user_defined_value_types else: assert isinstance(caller_context, FunctionSolc) sl = caller_context.underlying_function.compilation_unit diff --git a/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.10-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.10-compact.zip new file mode 100644 index 0000000000..38be57cf8b Binary files /dev/null and b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.10-compact.zip differ diff --git a/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.11-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.11-compact.zip new file mode 100644 index 0000000000..e6a5439a3f Binary files /dev/null and b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.11-compact.zip differ diff --git a/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.12-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.12-compact.zip new file mode 100644 index 0000000000..8f3c5c654c Binary files /dev/null and b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.12-compact.zip differ diff --git a/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.13-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.13-compact.zip new file mode 100644 index 0000000000..4f8ef1b383 Binary files /dev/null and b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.13-compact.zip differ diff --git a/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.14-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.14-compact.zip new file mode 100644 index 0000000000..12359abb50 Binary files /dev/null and b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.14-compact.zip differ diff --git a/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.15-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.15-compact.zip new file mode 100644 index 0000000000..4de1fa4acd Binary files /dev/null and b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.15-compact.zip differ diff --git a/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.8-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.8-compact.zip new file mode 100644 index 0000000000..8e1d0716a1 Binary files /dev/null and b/tests/ast-parsing/compile/user_defined_value_type/top-level-0.8.8.sol-0.8.8-compact.zip differ diff --git a/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.10-compact.json b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.10-compact.json new file mode 100644 index 0000000000..c8211c6366 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.10-compact.json @@ -0,0 +1,5 @@ +{ + "Test": { + "set(StackTop,uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: INLINE ASM 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.11-compact.json b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.11-compact.json new file mode 100644 index 0000000000..c8211c6366 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.11-compact.json @@ -0,0 +1,5 @@ +{ + "Test": { + "set(StackTop,uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: INLINE ASM 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.12-compact.json b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.12-compact.json new file mode 100644 index 0000000000..c8211c6366 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.12-compact.json @@ -0,0 +1,5 @@ +{ + "Test": { + "set(StackTop,uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: INLINE ASM 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.13-compact.json b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.13-compact.json new file mode 100644 index 0000000000..c8211c6366 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.13-compact.json @@ -0,0 +1,5 @@ +{ + "Test": { + "set(StackTop,uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: INLINE ASM 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.14-compact.json b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.14-compact.json new file mode 100644 index 0000000000..c8211c6366 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.14-compact.json @@ -0,0 +1,5 @@ +{ + "Test": { + "set(StackTop,uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: INLINE ASM 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.15-compact.json b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.15-compact.json new file mode 100644 index 0000000000..c8211c6366 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.15-compact.json @@ -0,0 +1,5 @@ +{ + "Test": { + "set(StackTop,uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: INLINE ASM 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.8-compact.json b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.8-compact.json new file mode 100644 index 0000000000..c8211c6366 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/top-level-0.8.8.sol-0.8.8-compact.json @@ -0,0 +1,5 @@ +{ + "Test": { + "set(StackTop,uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: INLINE ASM 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/user_defined_value_type/top-level-0.8.8.sol b/tests/ast-parsing/user_defined_value_type/top-level-0.8.8.sol new file mode 100644 index 0000000000..7021d37443 --- /dev/null +++ b/tests/ast-parsing/user_defined_value_type/top-level-0.8.8.sol @@ -0,0 +1,27 @@ +type Operand is uint256; +type StackTop is uint256; +struct StorageOpcodesRange { + uint256 pointer; + uint256 length; +} +struct IntegrityState { + // Sources first as we read it in assembly. + bytes[] sources; + StorageOpcodesRange storageOpcodesRange; + uint256 constantsLength; + uint256 contextLength; + StackTop stackBottom; + StackTop stackMaxTop; + uint256 contextScratch; + function(IntegrityState memory, Operand, StackTop) + view + returns (StackTop)[] integrityFunctionPointers; +} + +contract Test { + function set(StackTop stackTop_, uint256 a_) internal pure { + assembly { + mstore(stackTop_, a_) + } + } +} \ No newline at end of file diff --git a/tests/test_ast_parsing.py b/tests/test_ast_parsing.py index a61ec9604a..14130b4285 100644 --- a/tests/test_ast_parsing.py +++ b/tests/test_ast_parsing.py @@ -419,6 +419,7 @@ def make_version(minor: int, patch_min: int, patch_max: int) -> List[str]: Test("user_defined_value_type/constant-0.8.8.sol", ["0.8.8"] + make_version(8, 10, 15)), Test("user_defined_value_type/erc20-0.8.8.sol", ["0.8.8"] + make_version(8, 10, 15)), Test("user_defined_value_type/in_parenthesis-0.8.8.sol", ["0.8.8"] + make_version(8, 10, 15)), + Test("user_defined_value_type/top-level-0.8.8.sol", ["0.8.8"] + make_version(8, 10, 15)), Test("user_defined_value_type/using-for-0.8.8.sol", ["0.8.8"] + make_version(8, 10, 15)), Test("bytes_call.sol", ["0.8.12"]), Test("modifier_identifier_path.sol", VERSIONS_08),