From 4f676309902a9e144bd75af1fa1db0770f0b9ec2 Mon Sep 17 00:00:00 2001 From: bart1e Date: Thu, 9 Feb 2023 19:39:58 +0100 Subject: [PATCH 1/4] Detector for incorrect using-for at the top level added --- slither/detectors/all_detectors.py | 1 + .../statements/incorrect_using_for.py | 200 ++++++++++++++++++ .../0.8.17/IncorrectUsingForTopLevel.sol | 94 ++++++++ ...TopLevel.sol.0.8.17.IncorrectUsingFor.json | 124 +++++++++++ tests/e2e/detectors/test_detectors.py | 5 + 5 files changed, 424 insertions(+) create mode 100644 slither/detectors/statements/incorrect_using_for.py create mode 100644 tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol create mode 100644 tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol.0.8.17.IncorrectUsingFor.json diff --git a/slither/detectors/all_detectors.py b/slither/detectors/all_detectors.py index 9722b8793..21374a38b 100644 --- a/slither/detectors/all_detectors.py +++ b/slither/detectors/all_detectors.py @@ -89,3 +89,4 @@ from .functions.protected_variable import ProtectedVariables from .functions.permit_domain_signature_collision import DomainSeparatorCollision from .functions.codex import Codex from .functions.cyclomatic_complexity import CyclomaticComplexity +from .statements.incorrect_using_for import IncorrectUsingFor \ No newline at end of file diff --git a/slither/detectors/statements/incorrect_using_for.py b/slither/detectors/statements/incorrect_using_for.py new file mode 100644 index 000000000..7cc18deaf --- /dev/null +++ b/slither/detectors/statements/incorrect_using_for.py @@ -0,0 +1,200 @@ +from slither.core.declarations import Contract, Structure, Enum +from slither.core.declarations.using_for_top_level import UsingForTopLevel +from slither.core.solidity_types import ( + UserDefinedType, + Type, + ElementaryType, + TypeAlias, + MappingType, + ArrayType, +) +from slither.core.solidity_types.elementary_type import Uint, Int, Byte +from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification + + +class IncorrectUsingFor(AbstractDetector): + """ + Detector for incorrect using-for statement usage. + """ + + ARGUMENT = "incorrect-using-for" + HELP = "Detects using-for statement usage when no function from a given library matches a given type" + IMPACT = DetectorClassification.INFORMATIONAL + CONFIDENCE = DetectorClassification.HIGH + + WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-using-for-usage" + + WIKI_TITLE = "Incorrect usage of using-for statement" + WIKI_DESCRIPTION = "In Solidity, it is possible to use libraries for certain types, by the `using-for` statement " \ + "(`using for `). However, the Solidity compiler doesn't check whether a given " \ + "library has at least one function matching a given type. If it doesn't, such a statement has " \ + "no effect and may be confusing. " + + # region wiki_exploit_scenario + WIKI_EXPLOIT_SCENARIO = """ + ```solidity + library L { + function f(bool) public pure {} + } + + using L for uint; + ``` + Such a code will compile despite the fact that `L` has no function with `uint` as its first argument.""" + # endregion wiki_exploit_scenario + WIKI_RECOMMENDATION = "Make sure that the libraries used in `using-for` statements have at least one function " \ + "matching a type used in these statements. " + + @staticmethod + def _implicitly_convertible_to_for_contracts(contract1: Contract, contract2: Contract) -> bool: + """ + Returns True if contract1 may be implicitly converted to contract2. + """ + return contract1 == contract2 or contract2 in contract1.inheritance + + @staticmethod + def _implicitly_convertible_to_for_uints(type1: ElementaryType, type2: ElementaryType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2 assuming they are both uints. + """ + assert type1.type in Uint and type2.type in Uint + + return type1.size <= type2.size + + @staticmethod + def _implicitly_convertible_to_for_ints(type1: ElementaryType, type2: ElementaryType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2 assuming they are both ints. + """ + assert type1.type in Int and type2.type in Int + + return type1.size <= type2.size + + @staticmethod + def _implicitly_convertible_to_for_addresses( + type1: ElementaryType, type2: ElementaryType + ) -> bool: + """ + Returns True if type1 may be implicitly converted to type2 assuming they are both addresses. + """ + assert type1.type == "address" and type2.type == "address" + # payable attribute to be implemented; for now, always return True + return True + + @staticmethod + def _implicitly_convertible_to_for_bytes(type1: ElementaryType, type2: ElementaryType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2 assuming they are both bytes. + """ + assert type1.type in Byte and type2.type in Byte + + return type1.size <= type2.size + + @staticmethod + def _implicitly_convertible_to_for_elementary_types( + type1: ElementaryType, type2: ElementaryType + ) -> bool: + """ + Returns True if type1 may be implicitly converted to type2. + """ + if type1.type == "bool" and type2.type == "bool": + return True + if type1.type == "string" and type2.type == "string": + return True + if type1.type == "bytes" and type2.type == "bytes": + return True + if type1.type == "address" and type2.type == "address": + return IncorrectUsingFor._implicitly_convertible_to_for_addresses(type1, type2) + if type1.type in Uint and type2.type in Uint: + return IncorrectUsingFor._implicitly_convertible_to_for_uints(type1, type2) + if type1.type in Int and type2.type in Int: + return IncorrectUsingFor._implicitly_convertible_to_for_ints(type1, type2) + if ( + type1.type != "bytes" + and type2.type != "bytes" + and type1.type in Byte + and type2.type in Byte + ): + return IncorrectUsingFor._implicitly_convertible_to_for_bytes(type1, type2) + return False + + @staticmethod + def _implicitly_convertible_to_for_mappings(type1: MappingType, type2: MappingType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2. + """ + return type1.type_from == type2.type_from and type1.type_to == type2.type_to + + @staticmethod + def _implicitly_convertible_to_for_arrays(type1: ArrayType, type2: ArrayType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2. + """ + return IncorrectUsingFor._implicitly_convertible_to(type1.type, type2.type) + + @staticmethod + def _implicitly_convertible_to(type1: Type, type2: Type) -> bool: + """ + Returns True if type1 may be implicitly converted to type2. + """ + if isinstance(type1, TypeAlias) or isinstance(type2, TypeAlias): + if isinstance(type1, TypeAlias) and isinstance(type2, TypeAlias): + return type1.type == type2.type + return False + + if isinstance(type1, UserDefinedType) and isinstance(type2, UserDefinedType): + if isinstance(type1.type, Contract) and isinstance(type2.type, Contract): + return IncorrectUsingFor._implicitly_convertible_to_for_contracts( + type1.type, type2.type + ) + + if isinstance(type1.type, Structure) and isinstance(type2.type, Structure): + return type1.type.canonical_name == type2.type.canonical_name + + if isinstance(type1.type, Enum) and isinstance(type2.type, Enum): + return type1.type.canonical_name == type2.type.canonical_name + + if isinstance(type1, ElementaryType) and isinstance(type2, ElementaryType): + return IncorrectUsingFor._implicitly_convertible_to_for_elementary_types(type1, type2) + + if isinstance(type1, MappingType) and isinstance(type2, MappingType): + return IncorrectUsingFor._implicitly_convertible_to_for_mappings(type1, type2) + + if isinstance(type1, ArrayType) and isinstance(type2, ArrayType): + return IncorrectUsingFor._implicitly_convertible_to_for_arrays(type1, type2) + + return False + + @staticmethod + def _is_correctly_used(type_: Type, library: Contract) -> bool: + """ + Checks if a `using library for type_` statement is used correctly (that is, does library contain any function + with type_ as the first argument). + """ + for f in library.functions: + if len(f.parameters) == 0: + continue + if not IncorrectUsingFor._implicitly_convertible_to(type_, f.parameters[0].type): + continue + return True + return False + + def _append_result(self, results: list, uf: UsingForTopLevel, type_: Type, library: Contract): + info = f"using-for statement at {uf.source_mapping} is incorrect - no matching function for {type_} found in " \ + f"{library}.\n" + res = self.generate_result(info) + results.append(res) + + def _detect(self): + results = [] + + for uf in self.compilation_unit.using_for_top_level: + # UsingForTopLevel.using_for is a dict with a single entry, which is mapped to a list of functions/libraries + # the following code extracts the type from using-for and skips using-for statements with functions + type_ = list(uf.using_for.keys())[0] + for lib_or_fcn in uf.using_for[type_]: + # checking for using-for with functions is already performed by the compiler; we only consider libraries + if isinstance(lib_or_fcn, UserDefinedType): + if not self._is_correctly_used(type_, lib_or_fcn.type): + self._append_result(results, uf, type_, lib_or_fcn.type) + + return results diff --git a/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol b/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol new file mode 100644 index 000000000..5b173e7b5 --- /dev/null +++ b/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol @@ -0,0 +1,94 @@ +pragma solidity 0.8.17; + +struct S1 +{ + uint __; +} + +struct S2 +{ + uint128 __; +} + +enum E1 +{ + A, + B +} + +enum E2 +{ + A, + B +} + +contract C0 +{ + +} + +contract C1 is C0 +{ + +} + +contract C2 is C1 +{ + +} + +contract C3 +{ + +} + +type custom_uint is uint248; +type custom_int is int248; + +library L +{ + function f0(C0) public pure {} + function f1(bool) public pure {} + function f2(string memory) public pure {} + function f3(bytes memory) public pure {} + function f4(uint248) public pure {} + function f5(int248) public pure {} + function f6(address) public pure {} + function f7(bytes17) public pure {} + function f8(S1 memory) public pure {} + function f9(E1) public pure {} + function f10(mapping(int => uint) storage) public pure {} + function f11(string[] memory) public pure {} + function f12(bytes[][][] memory) public pure {} + function f13(custom_uint) public pure {} +} + +// the following statements are correct +using L for C2; +using L for bool; +using L for string; +using L for bytes; +using L for uint240; +using L for int16; +using L for address; +using L for bytes16; +using L for S1; +using L for E1; +using L for mapping(int => uint); +using L for string[]; +using L for bytes[][][]; +using L for custom_uint; + +// the following statements are incorrect +using L for C3; +using L for bytes17[]; +using L for uint; +using L for int; +using L for bytes18; +using L for S2; +using L for E2; +using L for mapping(int => uint128); +using L for mapping(int128 => uint); +using L for string[][]; +using L for bytes[][]; +using L for custom_int; diff --git a/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol.0.8.17.IncorrectUsingFor.json b/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol.0.8.17.IncorrectUsingFor.json new file mode 100644 index 000000000..9321baa9c --- /dev/null +++ b/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol.0.8.17.IncorrectUsingFor.json @@ -0,0 +1,124 @@ +[ + [ + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#92 is incorrect - no matching function for string[][] found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#92 is incorrect - no matching function for string[][] found in L.\n", + "first_markdown_element": "", + "id": "000067f9a866a9e43f9c82b9b70b3a7657545318fb4d3334b39f03e47b63e50a", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#86 is incorrect - no matching function for int256 found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#86 is incorrect - no matching function for int256 found in L.\n", + "first_markdown_element": "", + "id": "09b0f0c08a3f0fe4ee75eff34f9c4718a5f729814eda9fa21c2ba30a01e1de0e", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#91 is incorrect - no matching function for mapping(int128 => uint256) found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#91 is incorrect - no matching function for mapping(int128 => uint256) found in L.\n", + "first_markdown_element": "", + "id": "1a051922964f790736e90754dfebf381c6e078f957ab8e7eeedf9d79ef9d56e5", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#93 is incorrect - no matching function for bytes[][] found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#93 is incorrect - no matching function for bytes[][] found in L.\n", + "first_markdown_element": "", + "id": "3b1d94dc870c0f03b4f43b34b6278adf6669b9e30e245ae21247d3839445366c", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#94 is incorrect - no matching function for custom_int found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#94 is incorrect - no matching function for custom_int found in L.\n", + "first_markdown_element": "", + "id": "6d993d086c6d6fb8cd005acd124d7d165b38e85cc23d781a8c99d9efd0d2c25a", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#84 is incorrect - no matching function for bytes17[] found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#84 is incorrect - no matching function for bytes17[] found in L.\n", + "first_markdown_element": "", + "id": "6e785ac39c18c840fc9f46fc066670776551a98bfd8d2030ee523a0c55bf5eef", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#88 is incorrect - no matching function for S2 found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#88 is incorrect - no matching function for S2 found in L.\n", + "first_markdown_element": "", + "id": "90efff9103e8469dcd2d251f27bea0ab6875f0f511fe8aedc093532cb4a52aa5", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#87 is incorrect - no matching function for bytes18 found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#87 is incorrect - no matching function for bytes18 found in L.\n", + "first_markdown_element": "", + "id": "a36393040b3e588bbfb6ff945333997a967bc50e1f9d703be020a1786514fb12", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#89 is incorrect - no matching function for E2 found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#89 is incorrect - no matching function for E2 found in L.\n", + "first_markdown_element": "", + "id": "c8be02cb293bf4e4b5bbe3def377356d8761ed34c2bc3259f7073e7840eec6c6", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#90 is incorrect - no matching function for mapping(int256 => uint128) found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#90 is incorrect - no matching function for mapping(int256 => uint128) found in L.\n", + "first_markdown_element": "", + "id": "e6abc32f0e370622f8a17cbc5eb94340b78931210ef47269e39e683cc03a34d3", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#85 is incorrect - no matching function for uint256 found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#85 is incorrect - no matching function for uint256 found in L.\n", + "first_markdown_element": "", + "id": "eec4404d65776c62a3053ef34081ca8cfdc4c32c571e543c337c5af1a0c11c9c", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#83 is incorrect - no matching function for C3 found in L.\n", + "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#83 is incorrect - no matching function for C3 found in L.\n", + "first_markdown_element": "", + "id": "f5cb90eb9284eb3935980052fc2ad410058acafa4478ebd3109cc9520510095c", + "check": "incorrect-using-for", + "impact": "Informational", + "confidence": "High" + } + ] +] \ No newline at end of file diff --git a/tests/e2e/detectors/test_detectors.py b/tests/e2e/detectors/test_detectors.py index e6b87d530..2088ac214 100644 --- a/tests/e2e/detectors/test_detectors.py +++ b/tests/e2e/detectors/test_detectors.py @@ -1639,6 +1639,11 @@ ALL_TEST_OBJECTS = [ "LowCyclomaticComplexity.sol", "0.8.16", ), + Test( + all_detectors.IncorrectUsingFor, + "IncorrectUsingForTopLevel.sol", + "0.8.17", + ), ] GENERIC_PATH = "/GENERIC_PATH" From 5a450a07e04626f590ac303aba47db72cfea9c3b Mon Sep 17 00:00:00 2001 From: bart1e Date: Thu, 9 Feb 2023 20:03:36 +0100 Subject: [PATCH 2/4] Black run --- .../statements/incorrect_using_for.py | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/slither/detectors/statements/incorrect_using_for.py b/slither/detectors/statements/incorrect_using_for.py index 7cc18deaf..4df0701a2 100644 --- a/slither/detectors/statements/incorrect_using_for.py +++ b/slither/detectors/statements/incorrect_using_for.py @@ -25,10 +25,12 @@ class IncorrectUsingFor(AbstractDetector): WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-using-for-usage" WIKI_TITLE = "Incorrect usage of using-for statement" - WIKI_DESCRIPTION = "In Solidity, it is possible to use libraries for certain types, by the `using-for` statement " \ - "(`using for `). However, the Solidity compiler doesn't check whether a given " \ - "library has at least one function matching a given type. If it doesn't, such a statement has " \ - "no effect and may be confusing. " + WIKI_DESCRIPTION = ( + "In Solidity, it is possible to use libraries for certain types, by the `using-for` statement " + "(`using for `). However, the Solidity compiler doesn't check whether a given " + "library has at least one function matching a given type. If it doesn't, such a statement has " + "no effect and may be confusing. " + ) # region wiki_exploit_scenario WIKI_EXPLOIT_SCENARIO = """ @@ -41,8 +43,10 @@ class IncorrectUsingFor(AbstractDetector): ``` Such a code will compile despite the fact that `L` has no function with `uint` as its first argument.""" # endregion wiki_exploit_scenario - WIKI_RECOMMENDATION = "Make sure that the libraries used in `using-for` statements have at least one function " \ - "matching a type used in these statements. " + WIKI_RECOMMENDATION = ( + "Make sure that the libraries used in `using-for` statements have at least one function " + "matching a type used in these statements. " + ) @staticmethod def _implicitly_convertible_to_for_contracts(contract1: Contract, contract2: Contract) -> bool: @@ -179,8 +183,10 @@ class IncorrectUsingFor(AbstractDetector): return False def _append_result(self, results: list, uf: UsingForTopLevel, type_: Type, library: Contract): - info = f"using-for statement at {uf.source_mapping} is incorrect - no matching function for {type_} found in " \ - f"{library}.\n" + info = ( + f"using-for statement at {uf.source_mapping} is incorrect - no matching function for {type_} found in " + f"{library}.\n" + ) res = self.generate_result(info) results.append(res) From 32d4bba9efaaffa72b36bca448e0fce2c01b0abd Mon Sep 17 00:00:00 2001 From: bart1e Date: Wed, 3 May 2023 18:01:22 +0200 Subject: [PATCH 3/4] Tests updated --- slither/detectors/all_detectors.py | 2 +- ...TopLevel.sol.0.8.17.IncorrectUsingFor.json | 124 ------------------ ..._8_17_IncorrectUsingForTopLevel_sol__0.txt | 24 ++++ .../0.8.17/IncorrectUsingForTopLevel.sol | 0 .../IncorrectUsingForTopLevel.sol-0.8.17.zip | Bin 0 -> 10081 bytes 5 files changed, 25 insertions(+), 125 deletions(-) delete mode 100644 tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol.0.8.17.IncorrectUsingFor.json create mode 100644 tests/e2e/detectors/snapshots/detectors__detector_IncorrectUsingFor_0_8_17_IncorrectUsingForTopLevel_sol__0.txt rename tests/{detectors => e2e/detectors/test_data}/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol (100%) create mode 100644 tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol-0.8.17.zip diff --git a/slither/detectors/all_detectors.py b/slither/detectors/all_detectors.py index 21374a38b..324c97052 100644 --- a/slither/detectors/all_detectors.py +++ b/slither/detectors/all_detectors.py @@ -89,4 +89,4 @@ from .functions.protected_variable import ProtectedVariables from .functions.permit_domain_signature_collision import DomainSeparatorCollision from .functions.codex import Codex from .functions.cyclomatic_complexity import CyclomaticComplexity -from .statements.incorrect_using_for import IncorrectUsingFor \ No newline at end of file +from .statements.incorrect_using_for import IncorrectUsingFor diff --git a/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol.0.8.17.IncorrectUsingFor.json b/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol.0.8.17.IncorrectUsingFor.json deleted file mode 100644 index 9321baa9c..000000000 --- a/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol.0.8.17.IncorrectUsingFor.json +++ /dev/null @@ -1,124 +0,0 @@ -[ - [ - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#92 is incorrect - no matching function for string[][] found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#92 is incorrect - no matching function for string[][] found in L.\n", - "first_markdown_element": "", - "id": "000067f9a866a9e43f9c82b9b70b3a7657545318fb4d3334b39f03e47b63e50a", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#86 is incorrect - no matching function for int256 found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#86 is incorrect - no matching function for int256 found in L.\n", - "first_markdown_element": "", - "id": "09b0f0c08a3f0fe4ee75eff34f9c4718a5f729814eda9fa21c2ba30a01e1de0e", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#91 is incorrect - no matching function for mapping(int128 => uint256) found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#91 is incorrect - no matching function for mapping(int128 => uint256) found in L.\n", - "first_markdown_element": "", - "id": "1a051922964f790736e90754dfebf381c6e078f957ab8e7eeedf9d79ef9d56e5", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#93 is incorrect - no matching function for bytes[][] found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#93 is incorrect - no matching function for bytes[][] found in L.\n", - "first_markdown_element": "", - "id": "3b1d94dc870c0f03b4f43b34b6278adf6669b9e30e245ae21247d3839445366c", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#94 is incorrect - no matching function for custom_int found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#94 is incorrect - no matching function for custom_int found in L.\n", - "first_markdown_element": "", - "id": "6d993d086c6d6fb8cd005acd124d7d165b38e85cc23d781a8c99d9efd0d2c25a", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#84 is incorrect - no matching function for bytes17[] found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#84 is incorrect - no matching function for bytes17[] found in L.\n", - "first_markdown_element": "", - "id": "6e785ac39c18c840fc9f46fc066670776551a98bfd8d2030ee523a0c55bf5eef", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#88 is incorrect - no matching function for S2 found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#88 is incorrect - no matching function for S2 found in L.\n", - "first_markdown_element": "", - "id": "90efff9103e8469dcd2d251f27bea0ab6875f0f511fe8aedc093532cb4a52aa5", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#87 is incorrect - no matching function for bytes18 found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#87 is incorrect - no matching function for bytes18 found in L.\n", - "first_markdown_element": "", - "id": "a36393040b3e588bbfb6ff945333997a967bc50e1f9d703be020a1786514fb12", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#89 is incorrect - no matching function for E2 found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#89 is incorrect - no matching function for E2 found in L.\n", - "first_markdown_element": "", - "id": "c8be02cb293bf4e4b5bbe3def377356d8761ed34c2bc3259f7073e7840eec6c6", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#90 is incorrect - no matching function for mapping(int256 => uint128) found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#90 is incorrect - no matching function for mapping(int256 => uint128) found in L.\n", - "first_markdown_element": "", - "id": "e6abc32f0e370622f8a17cbc5eb94340b78931210ef47269e39e683cc03a34d3", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#85 is incorrect - no matching function for uint256 found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#85 is incorrect - no matching function for uint256 found in L.\n", - "first_markdown_element": "", - "id": "eec4404d65776c62a3053ef34081ca8cfdc4c32c571e543c337c5af1a0c11c9c", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [], - "description": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#83 is incorrect - no matching function for C3 found in L.\n", - "markdown": "using-for statement at tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#83 is incorrect - no matching function for C3 found in L.\n", - "first_markdown_element": "", - "id": "f5cb90eb9284eb3935980052fc2ad410058acafa4478ebd3109cc9520510095c", - "check": "incorrect-using-for", - "impact": "Informational", - "confidence": "High" - } - ] -] \ No newline at end of file diff --git a/tests/e2e/detectors/snapshots/detectors__detector_IncorrectUsingFor_0_8_17_IncorrectUsingForTopLevel_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_IncorrectUsingFor_0_8_17_IncorrectUsingForTopLevel_sol__0.txt new file mode 100644 index 000000000..4a85bca5f --- /dev/null +++ b/tests/e2e/detectors/snapshots/detectors__detector_IncorrectUsingFor_0_8_17_IncorrectUsingForTopLevel_sol__0.txt @@ -0,0 +1,24 @@ +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#84 is incorrect - no matching function for bytes17[] found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#85 is incorrect - no matching function for uint256 found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#90 is incorrect - no matching function for mapping(int256 => uint128) found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#86 is incorrect - no matching function for int256 found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#89 is incorrect - no matching function for E2 found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#93 is incorrect - no matching function for bytes[][] found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#92 is incorrect - no matching function for string[][] found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#91 is incorrect - no matching function for mapping(int128 => uint256) found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#87 is incorrect - no matching function for bytes18 found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#88 is incorrect - no matching function for S2 found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#83 is incorrect - no matching function for C3 found in L. + +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#94 is incorrect - no matching function for custom_int found in L. + diff --git a/tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol b/tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol similarity index 100% rename from tests/detectors/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol rename to tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol diff --git a/tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol-0.8.17.zip b/tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol-0.8.17.zip new file mode 100644 index 0000000000000000000000000000000000000000..9afc56d39e442ef3a41f3541db7a05857656332c GIT binary patch literal 10081 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 Date: Fri, 19 May 2023 14:43:55 +0200 Subject: [PATCH 4/4] Minor python improvements --- .../statements/incorrect_using_for.py | 305 +++++++++--------- ..._8_17_IncorrectUsingForTopLevel_sol__0.txt | 24 +- 2 files changed, 173 insertions(+), 156 deletions(-) diff --git a/slither/detectors/statements/incorrect_using_for.py b/slither/detectors/statements/incorrect_using_for.py index 4df0701a2..e2e87e7e0 100644 --- a/slither/detectors/statements/incorrect_using_for.py +++ b/slither/detectors/statements/incorrect_using_for.py @@ -1,3 +1,5 @@ +from typing import List + from slither.core.declarations import Contract, Structure, Enum from slither.core.declarations.using_for_top_level import UsingForTopLevel from slither.core.solidity_types import ( @@ -9,7 +11,148 @@ from slither.core.solidity_types import ( ArrayType, ) from slither.core.solidity_types.elementary_type import Uint, Int, Byte -from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification +from slither.detectors.abstract_detector import ( + AbstractDetector, + DetectorClassification, + DETECTOR_INFO, +) +from slither.utils.output import Output + + +def _is_correctly_used(type_: Type, library: Contract) -> bool: + """ + Checks if a `using library for type_` statement is used correctly (that is, does library contain any function + with type_ as the first argument). + """ + for f in library.functions: + if len(f.parameters) == 0: + continue + if f.parameters[0].type and not _implicitly_convertible_to(type_, f.parameters[0].type): + continue + return True + return False + + +def _implicitly_convertible_to(type1: Type, type2: Type) -> bool: + """ + Returns True if type1 may be implicitly converted to type2. + """ + if isinstance(type1, TypeAlias) or isinstance(type2, TypeAlias): + if isinstance(type1, TypeAlias) and isinstance(type2, TypeAlias): + return type1.type == type2.type + return False + + if isinstance(type1, UserDefinedType) and isinstance(type2, UserDefinedType): + if isinstance(type1.type, Contract) and isinstance(type2.type, Contract): + return _implicitly_convertible_to_for_contracts(type1.type, type2.type) + + if isinstance(type1.type, Structure) and isinstance(type2.type, Structure): + return type1.type.canonical_name == type2.type.canonical_name + + if isinstance(type1.type, Enum) and isinstance(type2.type, Enum): + return type1.type.canonical_name == type2.type.canonical_name + + if isinstance(type1, ElementaryType) and isinstance(type2, ElementaryType): + return _implicitly_convertible_to_for_elementary_types(type1, type2) + + if isinstance(type1, MappingType) and isinstance(type2, MappingType): + return _implicitly_convertible_to_for_mappings(type1, type2) + + if isinstance(type1, ArrayType) and isinstance(type2, ArrayType): + return _implicitly_convertible_to_for_arrays(type1, type2) + + return False + + +def _implicitly_convertible_to_for_arrays(type1: ArrayType, type2: ArrayType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2. + """ + return _implicitly_convertible_to(type1.type, type2.type) + + +def _implicitly_convertible_to_for_mappings(type1: MappingType, type2: MappingType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2. + """ + return type1.type_from == type2.type_from and type1.type_to == type2.type_to + + +def _implicitly_convertible_to_for_elementary_types( + type1: ElementaryType, type2: ElementaryType +) -> bool: + """ + Returns True if type1 may be implicitly converted to type2. + """ + if type1.type == "bool" and type2.type == "bool": + return True + if type1.type == "string" and type2.type == "string": + return True + if type1.type == "bytes" and type2.type == "bytes": + return True + if type1.type == "address" and type2.type == "address": + return _implicitly_convertible_to_for_addresses(type1, type2) + if type1.type in Uint and type2.type in Uint: + return _implicitly_convertible_to_for_uints(type1, type2) + if type1.type in Int and type2.type in Int: + return _implicitly_convertible_to_for_ints(type1, type2) + if ( + type1.type != "bytes" + and type2.type != "bytes" + and type1.type in Byte + and type2.type in Byte + ): + return _implicitly_convertible_to_for_bytes(type1, type2) + return False + + +def _implicitly_convertible_to_for_bytes(type1: ElementaryType, type2: ElementaryType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2 assuming they are both bytes. + """ + assert type1.type in Byte and type2.type in Byte + assert type1.size is not None + assert type2.size is not None + + return type1.size <= type2.size + + +def _implicitly_convertible_to_for_addresses(type1: ElementaryType, type2: ElementaryType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2 assuming they are both addresses. + """ + assert type1.type == "address" and type2.type == "address" + # payable attribute to be implemented; for now, always return True + return True + + +def _implicitly_convertible_to_for_ints(type1: ElementaryType, type2: ElementaryType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2 assuming they are both ints. + """ + assert type1.type in Int and type2.type in Int + assert type1.size is not None + assert type2.size is not None + + return type1.size <= type2.size + + +def _implicitly_convertible_to_for_uints(type1: ElementaryType, type2: ElementaryType) -> bool: + """ + Returns True if type1 may be implicitly converted to type2 assuming they are both uints. + """ + assert type1.type in Uint and type2.type in Uint + assert type1.size is not None + assert type2.size is not None + + return type1.size <= type2.size + + +def _implicitly_convertible_to_for_contracts(contract1: Contract, contract2: Contract) -> bool: + """ + Returns True if contract1 may be implicitly converted to contract2. + """ + return contract1 == contract2 or contract2 in contract1.inheritance class IncorrectUsingFor(AbstractDetector): @@ -48,150 +191,19 @@ class IncorrectUsingFor(AbstractDetector): "matching a type used in these statements. " ) - @staticmethod - def _implicitly_convertible_to_for_contracts(contract1: Contract, contract2: Contract) -> bool: - """ - Returns True if contract1 may be implicitly converted to contract2. - """ - return contract1 == contract2 or contract2 in contract1.inheritance - - @staticmethod - def _implicitly_convertible_to_for_uints(type1: ElementaryType, type2: ElementaryType) -> bool: - """ - Returns True if type1 may be implicitly converted to type2 assuming they are both uints. - """ - assert type1.type in Uint and type2.type in Uint - - return type1.size <= type2.size - - @staticmethod - def _implicitly_convertible_to_for_ints(type1: ElementaryType, type2: ElementaryType) -> bool: - """ - Returns True if type1 may be implicitly converted to type2 assuming they are both ints. - """ - assert type1.type in Int and type2.type in Int - - return type1.size <= type2.size - - @staticmethod - def _implicitly_convertible_to_for_addresses( - type1: ElementaryType, type2: ElementaryType - ) -> bool: - """ - Returns True if type1 may be implicitly converted to type2 assuming they are both addresses. - """ - assert type1.type == "address" and type2.type == "address" - # payable attribute to be implemented; for now, always return True - return True - - @staticmethod - def _implicitly_convertible_to_for_bytes(type1: ElementaryType, type2: ElementaryType) -> bool: - """ - Returns True if type1 may be implicitly converted to type2 assuming they are both bytes. - """ - assert type1.type in Byte and type2.type in Byte - - return type1.size <= type2.size - - @staticmethod - def _implicitly_convertible_to_for_elementary_types( - type1: ElementaryType, type2: ElementaryType - ) -> bool: - """ - Returns True if type1 may be implicitly converted to type2. - """ - if type1.type == "bool" and type2.type == "bool": - return True - if type1.type == "string" and type2.type == "string": - return True - if type1.type == "bytes" and type2.type == "bytes": - return True - if type1.type == "address" and type2.type == "address": - return IncorrectUsingFor._implicitly_convertible_to_for_addresses(type1, type2) - if type1.type in Uint and type2.type in Uint: - return IncorrectUsingFor._implicitly_convertible_to_for_uints(type1, type2) - if type1.type in Int and type2.type in Int: - return IncorrectUsingFor._implicitly_convertible_to_for_ints(type1, type2) - if ( - type1.type != "bytes" - and type2.type != "bytes" - and type1.type in Byte - and type2.type in Byte - ): - return IncorrectUsingFor._implicitly_convertible_to_for_bytes(type1, type2) - return False - - @staticmethod - def _implicitly_convertible_to_for_mappings(type1: MappingType, type2: MappingType) -> bool: - """ - Returns True if type1 may be implicitly converted to type2. - """ - return type1.type_from == type2.type_from and type1.type_to == type2.type_to - - @staticmethod - def _implicitly_convertible_to_for_arrays(type1: ArrayType, type2: ArrayType) -> bool: - """ - Returns True if type1 may be implicitly converted to type2. - """ - return IncorrectUsingFor._implicitly_convertible_to(type1.type, type2.type) - - @staticmethod - def _implicitly_convertible_to(type1: Type, type2: Type) -> bool: - """ - Returns True if type1 may be implicitly converted to type2. - """ - if isinstance(type1, TypeAlias) or isinstance(type2, TypeAlias): - if isinstance(type1, TypeAlias) and isinstance(type2, TypeAlias): - return type1.type == type2.type - return False - - if isinstance(type1, UserDefinedType) and isinstance(type2, UserDefinedType): - if isinstance(type1.type, Contract) and isinstance(type2.type, Contract): - return IncorrectUsingFor._implicitly_convertible_to_for_contracts( - type1.type, type2.type - ) - - if isinstance(type1.type, Structure) and isinstance(type2.type, Structure): - return type1.type.canonical_name == type2.type.canonical_name - - if isinstance(type1.type, Enum) and isinstance(type2.type, Enum): - return type1.type.canonical_name == type2.type.canonical_name - - if isinstance(type1, ElementaryType) and isinstance(type2, ElementaryType): - return IncorrectUsingFor._implicitly_convertible_to_for_elementary_types(type1, type2) - - if isinstance(type1, MappingType) and isinstance(type2, MappingType): - return IncorrectUsingFor._implicitly_convertible_to_for_mappings(type1, type2) - - if isinstance(type1, ArrayType) and isinstance(type2, ArrayType): - return IncorrectUsingFor._implicitly_convertible_to_for_arrays(type1, type2) - - return False - - @staticmethod - def _is_correctly_used(type_: Type, library: Contract) -> bool: - """ - Checks if a `using library for type_` statement is used correctly (that is, does library contain any function - with type_ as the first argument). - """ - for f in library.functions: - if len(f.parameters) == 0: - continue - if not IncorrectUsingFor._implicitly_convertible_to(type_, f.parameters[0].type): - continue - return True - return False - - def _append_result(self, results: list, uf: UsingForTopLevel, type_: Type, library: Contract): - info = ( - f"using-for statement at {uf.source_mapping} is incorrect - no matching function for {type_} found in " - f"{library}.\n" - ) + def _append_result( + self, results: List[Output], uf: UsingForTopLevel, type_: Type, library: Contract + ) -> None: + info: DETECTOR_INFO = [ + f"using-for statement at {uf.source_mapping} is incorrect - no matching function for {type_} found in ", + library, + ".\n", + ] res = self.generate_result(info) results.append(res) - def _detect(self): - results = [] + def _detect(self) -> List[Output]: + results: List[Output] = [] for uf in self.compilation_unit.using_for_top_level: # UsingForTopLevel.using_for is a dict with a single entry, which is mapped to a list of functions/libraries @@ -200,7 +212,12 @@ class IncorrectUsingFor(AbstractDetector): for lib_or_fcn in uf.using_for[type_]: # checking for using-for with functions is already performed by the compiler; we only consider libraries if isinstance(lib_or_fcn, UserDefinedType): - if not self._is_correctly_used(type_, lib_or_fcn.type): - self._append_result(results, uf, type_, lib_or_fcn.type) + lib_or_fcn_type = lib_or_fcn.type + if ( + isinstance(type_, Type) + and isinstance(lib_or_fcn_type, Contract) + and not _is_correctly_used(type_, lib_or_fcn_type) + ): + self._append_result(results, uf, type_, lib_or_fcn_type) return results diff --git a/tests/e2e/detectors/snapshots/detectors__detector_IncorrectUsingFor_0_8_17_IncorrectUsingForTopLevel_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_IncorrectUsingFor_0_8_17_IncorrectUsingForTopLevel_sol__0.txt index 4a85bca5f..518fba20d 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_IncorrectUsingFor_0_8_17_IncorrectUsingForTopLevel_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_IncorrectUsingFor_0_8_17_IncorrectUsingForTopLevel_sol__0.txt @@ -1,24 +1,24 @@ -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#84 is incorrect - no matching function for bytes17[] found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#84 is incorrect - no matching function for bytes17[] found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#85 is incorrect - no matching function for uint256 found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#85 is incorrect - no matching function for uint256 found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#90 is incorrect - no matching function for mapping(int256 => uint128) found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#90 is incorrect - no matching function for mapping(int256 => uint128) found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#86 is incorrect - no matching function for int256 found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#86 is incorrect - no matching function for int256 found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#89 is incorrect - no matching function for E2 found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#89 is incorrect - no matching function for E2 found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#93 is incorrect - no matching function for bytes[][] found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#93 is incorrect - no matching function for bytes[][] found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#92 is incorrect - no matching function for string[][] found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#92 is incorrect - no matching function for string[][] found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#91 is incorrect - no matching function for mapping(int128 => uint256) found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#91 is incorrect - no matching function for mapping(int128 => uint256) found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#87 is incorrect - no matching function for bytes18 found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#87 is incorrect - no matching function for bytes18 found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#88 is incorrect - no matching function for S2 found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#88 is incorrect - no matching function for S2 found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#83 is incorrect - no matching function for C3 found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#83 is incorrect - no matching function for C3 found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64). -using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#94 is incorrect - no matching function for custom_int found in L. +using-for statement at tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#94 is incorrect - no matching function for custom_int found in L (tests/e2e/detectors/test_data/incorrect-using-for/0.8.17/IncorrectUsingForTopLevel.sol#48-64).