From faed6d7fb2039c231d4631dbed625c7c3d6ae6b5 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Sun, 6 Nov 2022 21:38:45 -0600 Subject: [PATCH 01/61] update constable-states to consider constructor vars which can be immutable --- .../possible_const_state_variables.py | 101 +-- ...es.sol.0.4.25.ConstCandidateStateVars.json | 206 +++--- .../0.5.16/const_state_variables.sol | 1 + ...es.sol.0.5.16.ConstCandidateStateVars.json | 261 ++++--- .../0.6.11/const_state_variables.sol | 8 +- ...es.sol.0.6.11.ConstCandidateStateVars.json | 286 +++++--- .../0.7.6/const_state_variables.sol | 14 +- ...les.sol.0.7.6.ConstCandidateStateVars.json | 480 +++++++++--- .../0.8.0/const_state_variables.sol | 52 ++ ...les.sol.0.8.0.ConstCandidateStateVars.json | 690 ++++++++++++++++++ .../constable-states/0.8.0/immutable.sol | 7 - ...ble.sol.0.8.0.ConstCandidateStateVars.json | 3 - tests/test_detectors.py | 2 +- 13 files changed, 1651 insertions(+), 460 deletions(-) create mode 100644 tests/detectors/constable-states/0.8.0/const_state_variables.sol create mode 100644 tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.ConstCandidateStateVars.json delete mode 100644 tests/detectors/constable-states/0.8.0/immutable.sol delete mode 100644 tests/detectors/constable-states/0.8.0/immutable.sol.0.8.0.ConstCandidateStateVars.json diff --git a/slither/detectors/variables/possible_const_state_variables.py b/slither/detectors/variables/possible_const_state_variables.py index e5b35bb79..4337b3075 100644 --- a/slither/detectors/variables/possible_const_state_variables.py +++ b/slither/detectors/variables/possible_const_state_variables.py @@ -14,6 +14,7 @@ from slither.core.declarations import Contract, Function from slither.core.declarations.solidity_variables import SolidityFunction from slither.core.variables.state_variable import StateVariable from slither.formatters.variables.possible_const_state_variables import custom_format +from slither.core.expressions import CallExpression, NewContract def _is_valid_type(v: StateVariable) -> bool: @@ -44,15 +45,17 @@ class ConstCandidateStateVars(AbstractDetector): """ ARGUMENT = "constable-states" - HELP = "State variables that could be declared constant" + HELP = "State variables that could be declared constant or immutable" IMPACT = DetectorClassification.OPTIMIZATION CONFIDENCE = DetectorClassification.HIGH - WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-constant" + WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-constant-or-immutable" - WIKI_TITLE = "State variables that could be declared constant" - WIKI_DESCRIPTION = "Constant state variables should be declared constant to save gas." - WIKI_RECOMMENDATION = "Add the `constant` attributes to state variables that never change." + WIKI_TITLE = "State variables that could be declared constant or immutable" + WIKI_DESCRIPTION = "State variables that are not updated following deployment should be declared constant or immutable to save gas." + WIKI_RECOMMENDATION = ( + "Add the `constant` or `immutable` attribute to state variables that never change." + ) # https://solidity.readthedocs.io/en/v0.5.2/contracts.html#constant-state-variables valid_solidity_function = [ @@ -71,54 +74,66 @@ class ConstCandidateStateVars(AbstractDetector): if not v.expression: return True + # B b = new B(); b cannot be constant, so filter out and recommend it be immutable + if isinstance(v.expression, CallExpression) and isinstance( + v.expression.called, NewContract + ): + return False + export = ExportValues(v.expression) values = export.result() if not values: return True - if all((val in self.valid_solidity_function or _is_constant_var(val) for val in values)): - return True - return False + else: + return all( + (val in self.valid_solidity_function or _is_constant_var(val) for val in values) + ) def _detect(self) -> List[Output]: - """Detect state variables that could be const""" - results = [] + """Detect state variables that could be constant or immutable""" + results = {} + + variables = [] + functions = [] + for c in self.compilation_unit.contracts: + variables.append(c.state_variables) + functions.append(c.all_functions_called) - all_variables_l = [c.state_variables for c in self.compilation_unit.contracts] - all_variables: Set[StateVariable] = { - item for sublist in all_variables_l for item in sublist + valid_candidates: Set[StateVariable] = { + item for sublist in variables for item in sublist if _valid_candidate(item) } - all_non_constant_elementary_variables = {v for v in all_variables if _valid_candidate(v)} - - all_functions_nested = [c.all_functions_called for c in self.compilation_unit.contracts] - all_functions = list( - { - item1 - for sublist in all_functions_nested - for item1 in sublist - if isinstance(item1, Function) - } + + all_functions: List[Function] = list( + {item1 for sublist in functions for item1 in sublist if isinstance(item1, Function)} ) - all_variables_written = [ - f.state_variables_written for f in all_functions if not f.is_constructor_variables - ] - all_variables_written = {item for sublist in all_variables_written for item in sublist} - - constable_variables: List[Variable] = [ - v - for v in all_non_constant_elementary_variables - if (v not in all_variables_written) and self._constant_initial_expression(v) - ] - # Order for deterministic results - constable_variables = sorted(constable_variables, key=lambda x: x.canonical_name) - - # Create a result for each finding - for v in constable_variables: - info = [v, " should be constant\n"] - json = self.generate_result(info) - results.append(json) - - return results + variables_written = [] + constructor_variables_written = [] + for f in all_functions: + if f.is_constructor_variables: + constructor_variables_written.append(f.state_variables_written) + else: + variables_written.append(f.state_variables_written) + + variables_written = {item for sublist in variables_written for item in sublist} + constructor_variables_written = { + item for sublist in constructor_variables_written for item in sublist + } + for v in valid_candidates: + if v not in variables_written: + if self._constant_initial_expression(v): + results[v.canonical_name] = self.generate_result([v, " should be constant \n"]) + + # immutable attribute available in Solidity 0.6.5 and above + # https://blog.soliditylang.org/2020/04/06/solidity-0.6.5-release-announcement/ + elif ( + v in constructor_variables_written + and self.compilation_unit.solc_version > "0.6.4" + ): + results[v.canonical_name] = self.generate_result([v, " should be immutable \n"]) + + # Order by canonical name for deterministic results + return [results[k] for k in sorted(results)] @staticmethod def _format(compilation_unit: SlitherCompilationUnit, result: Dict) -> None: diff --git a/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.ConstCandidateStateVars.json index 4ab2cfa83..a46384f06 100644 --- a/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.ConstCandidateStateVars.json +++ b/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.ConstCandidateStateVars.json @@ -4,19 +4,19 @@ "elements": [ { "type": "variable", - "name": "myFriendsAddress", + "name": "text2", "source_mapping": { - "start": 132, - "length": 76, + "start": 333, + "length": 20, "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "is_dependency": false, "lines": [ - 7 + 14 ], "starting_column": 5, - "ending_column": 81 + "ending_column": 25 }, "type_specific_fields": { "parent": { @@ -56,10 +56,10 @@ } } ], - "description": "A.myFriendsAddress (tests/detectors/constable-states/0.4.25/const_state_variables.sol#7) should be constant\n", - "markdown": "[A.myFriendsAddress](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L7) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L7", - "id": "1454db80653b732bf6acbe54ff0ae4707002207a2a8216708c12d61c88a43e5f", + "description": "A.text2 (tests/detectors/constable-states/0.4.25/const_state_variables.sol#14) should be constant \n", + "markdown": "[A.text2](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L14) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L14", + "id": "2f06e04545cea7e7a8998c65d5419f335bf2579a6ce6a832eac9c87392fd5c1a", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -68,19 +68,79 @@ "elements": [ { "type": "variable", - "name": "test", + "name": "mySistersAddress", "source_mapping": { - "start": 237, - "length": 20, + "start": 496, + "length": 76, "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "is_dependency": false, "lines": [ - 10 + 26 ], "starting_column": 5, - "ending_column": 25 + "ending_column": 81 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "B", + "source_mapping": { + "start": 473, + "length": 271, + "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "B.mySistersAddress (tests/detectors/constable-states/0.4.25/const_state_variables.sol#26) should be constant \n", + "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L26) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L26", + "id": "3b5bff93954a48a79387e7981e8c45d78edc575a0988a10f1c7f439b9f930539", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "myFriendsAddress", + "source_mapping": { + "start": 132, + "length": 76, + "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 7 + ], + "starting_column": 5, + "ending_column": 81 }, "type_specific_fields": { "parent": { @@ -120,10 +180,10 @@ } } ], - "description": "A.test (tests/detectors/constable-states/0.4.25/const_state_variables.sol#10) should be constant\n", - "markdown": "[A.test](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L10) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L10", - "id": "5d9e3fb413322b71a93e90f7e89bd8c83cd4884d577d039598c681fe9db38b1d", + "description": "A.myFriendsAddress (tests/detectors/constable-states/0.4.25/const_state_variables.sol#7) should be constant \n", + "markdown": "[A.myFriendsAddress](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L7) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L7", + "id": "52fd72f6870c4b504d1bcf9fb44249658e2077474d66208a33a47d2668b8db49", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -132,19 +192,19 @@ "elements": [ { "type": "variable", - "name": "should_be_constant_2", + "name": "should_be_constant", "source_mapping": { - "start": 841, - "length": 33, + "start": 793, + "length": 42, "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "is_dependency": false, "lines": [ - 43 + 42 ], "starting_column": 5, - "ending_column": 38 + "ending_column": 47 }, "type_specific_fields": { "parent": { @@ -180,70 +240,10 @@ } } ], - "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.4.25/const_state_variables.sol#43) should be constant\n", - "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L43) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L43", - "id": "9a48a4122de1a6a4774a9f1e0d4917bd0fa08f17b4af41b86ba07689e51bf711", - "check": "constable-states", - "impact": "Optimization", - "confidence": "High" - }, - { - "elements": [ - { - "type": "variable", - "name": "mySistersAddress", - "source_mapping": { - "start": 496, - "length": 76, - "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 26 - ], - "starting_column": 5, - "ending_column": 81 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "B", - "source_mapping": { - "start": 473, - "length": 271, - "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37 - ], - "starting_column": 1, - "ending_column": 2 - } - } - } - } - ], - "description": "B.mySistersAddress (tests/detectors/constable-states/0.4.25/const_state_variables.sol#26) should be constant\n", - "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L26) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L26", - "id": "bee93a722c8eae4a48aade67d8ef537d84c106f48fc9eb738c795fce10d3bc63", + "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.4.25/const_state_variables.sol#42) should be constant \n", + "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L42) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L42", + "id": "8d08797efc8230b480ec669c7e2bf53c3b3d16bc59bf7770934b34fd892934f8", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -252,19 +252,19 @@ "elements": [ { "type": "variable", - "name": "should_be_constant", + "name": "should_be_constant_2", "source_mapping": { - "start": 793, - "length": 42, + "start": 841, + "length": 33, "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "is_dependency": false, "lines": [ - 42 + 43 ], "starting_column": 5, - "ending_column": 47 + "ending_column": 38 }, "type_specific_fields": { "parent": { @@ -300,10 +300,10 @@ } } ], - "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.4.25/const_state_variables.sol#42) should be constant\n", - "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L42) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L42", - "id": "cbcafa2a3efba4d21ac1b51b4b823e5082d556bc3d6cf3fd2ab3188f9f218fc1", + "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.4.25/const_state_variables.sol#43) should be constant \n", + "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L43) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L43", + "id": "d08c6d1e331083b42c45c222691dd1e6d880814c66d114971875337ca61ba9c9", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -312,16 +312,16 @@ "elements": [ { "type": "variable", - "name": "text2", + "name": "test", "source_mapping": { - "start": 333, + "start": 237, "length": 20, "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "is_dependency": false, "lines": [ - 14 + 10 ], "starting_column": 5, "ending_column": 25 @@ -364,10 +364,10 @@ } } ], - "description": "A.text2 (tests/detectors/constable-states/0.4.25/const_state_variables.sol#14) should be constant\n", - "markdown": "[A.text2](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L14) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L14", - "id": "df11e6201c4558a8c5cd90b55b134b9ca8f07203b2264d3aa93bd7745e8cb4ba", + "description": "A.test (tests/detectors/constable-states/0.4.25/const_state_variables.sol#10) should be constant \n", + "markdown": "[A.test](tests/detectors/constable-states/0.4.25/const_state_variables.sol#L10) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.4.25/const_state_variables.sol#L10", + "id": "e407a1b57b4d25949ef7c4e6d97197605857099a94774a9c7a848d7dd3463668", "check": "constable-states", "impact": "Optimization", "confidence": "High" diff --git a/tests/detectors/constable-states/0.5.16/const_state_variables.sol b/tests/detectors/constable-states/0.5.16/const_state_variables.sol index aed05d97f..7d018ca2d 100644 --- a/tests/detectors/constable-states/0.5.16/const_state_variables.sol +++ b/tests/detectors/constable-states/0.5.16/const_state_variables.sol @@ -41,6 +41,7 @@ contract MyConc{ uint constant A = 1; bytes32 should_be_constant = sha256('abc'); uint should_be_constant_2 = A + 1; + B should_be_constant_3 = B(address(0)); address not_constant = msg.sender; uint not_constant_2 = getNumber(); uint not_constant_3 = 10 + block.number; diff --git a/tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.ConstCandidateStateVars.json index 9b435a4a8..36de0ff0b 100644 --- a/tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.ConstCandidateStateVars.json +++ b/tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.ConstCandidateStateVars.json @@ -4,50 +4,47 @@ "elements": [ { "type": "variable", - "name": "myFriendsAddress", + "name": "should_be_constant_3", "source_mapping": { - "start": 132, - "length": 76, + "start": 880, + "length": 38, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "is_dependency": false, "lines": [ - 7 + 44 ], "starting_column": 5, - "ending_column": 81 + "ending_column": 43 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "A", + "name": "MyConc", "source_mapping": { - "start": 29, - "length": 441, + "start": 746, + "length": 386, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "is_dependency": false, "lines": [ - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21 + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53 ], "starting_column": 1, "ending_column": 2 @@ -56,10 +53,10 @@ } } ], - "description": "A.myFriendsAddress (tests/detectors/constable-states/0.5.16/const_state_variables.sol#7) should be constant\n", - "markdown": "[A.myFriendsAddress](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L7) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L7", - "id": "1454db80653b732bf6acbe54ff0ae4707002207a2a8216708c12d61c88a43e5f", + "description": "MyConc.should_be_constant_3 (tests/detectors/constable-states/0.5.16/const_state_variables.sol#44) should be constant \n", + "markdown": "[MyConc.should_be_constant_3](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L44) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L44", + "id": "29247b0a9939e854ad51bf3b2f58705156aa8b7e446e646b1832467d362b5b3e", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -68,16 +65,16 @@ "elements": [ { "type": "variable", - "name": "test", + "name": "text2", "source_mapping": { - "start": 237, + "start": 333, "length": 20, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "is_dependency": false, "lines": [ - 10 + 14 ], "starting_column": 5, "ending_column": 25 @@ -120,10 +117,10 @@ } } ], - "description": "A.test (tests/detectors/constable-states/0.5.16/const_state_variables.sol#10) should be constant\n", - "markdown": "[A.test](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L10) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L10", - "id": "5d9e3fb413322b71a93e90f7e89bd8c83cd4884d577d039598c681fe9db38b1d", + "description": "A.text2 (tests/detectors/constable-states/0.5.16/const_state_variables.sol#14) should be constant \n", + "markdown": "[A.text2](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L14) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L14", + "id": "2f06e04545cea7e7a8998c65d5419f335bf2579a6ce6a832eac9c87392fd5c1a", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -132,46 +129,46 @@ "elements": [ { "type": "variable", - "name": "should_be_constant_2", + "name": "mySistersAddress", "source_mapping": { - "start": 841, - "length": 33, + "start": 496, + "length": 76, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "is_dependency": false, "lines": [ - 43 + 26 ], "starting_column": 5, - "ending_column": 38 + "ending_column": 81 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "B", "source_mapping": { - "start": 746, - "length": 342, + "start": 473, + "length": 271, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "is_dependency": false, "lines": [ - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37 ], "starting_column": 1, "ending_column": 2 @@ -180,10 +177,10 @@ } } ], - "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.5.16/const_state_variables.sol#43) should be constant\n", - "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L43) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L43", - "id": "9a48a4122de1a6a4774a9f1e0d4917bd0fa08f17b4af41b86ba07689e51bf711", + "description": "B.mySistersAddress (tests/detectors/constable-states/0.5.16/const_state_variables.sol#26) should be constant \n", + "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L26) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L26", + "id": "3b5bff93954a48a79387e7981e8c45d78edc575a0988a10f1c7f439b9f930539", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -192,16 +189,16 @@ "elements": [ { "type": "variable", - "name": "mySistersAddress", + "name": "myFriendsAddress", "source_mapping": { - "start": 496, + "start": 132, "length": 76, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "is_dependency": false, "lines": [ - 26 + 7 ], "starting_column": 5, "ending_column": 81 @@ -209,29 +206,33 @@ "type_specific_fields": { "parent": { "type": "contract", - "name": "B", + "name": "A", "source_mapping": { - "start": 473, - "length": 271, + "start": 29, + "length": 441, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "is_dependency": false, "lines": [ - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37 + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21 ], "starting_column": 1, "ending_column": 2 @@ -240,10 +241,10 @@ } } ], - "description": "B.mySistersAddress (tests/detectors/constable-states/0.5.16/const_state_variables.sol#26) should be constant\n", - "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L26) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L26", - "id": "bee93a722c8eae4a48aade67d8ef537d84c106f48fc9eb738c795fce10d3bc63", + "description": "A.myFriendsAddress (tests/detectors/constable-states/0.5.16/const_state_variables.sol#7) should be constant \n", + "markdown": "[A.myFriendsAddress](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L7) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L7", + "id": "52fd72f6870c4b504d1bcf9fb44249658e2077474d66208a33a47d2668b8db49", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -272,7 +273,7 @@ "name": "MyConc", "source_mapping": { "start": 746, - "length": 342, + "length": 386, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", @@ -291,7 +292,8 @@ 49, 50, 51, - 52 + 52, + 53 ], "starting_column": 1, "ending_column": 2 @@ -300,10 +302,10 @@ } } ], - "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.5.16/const_state_variables.sol#42) should be constant\n", - "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L42) should be constant\n", + "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.5.16/const_state_variables.sol#42) should be constant \n", + "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L42) should be constant \n", "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L42", - "id": "cbcafa2a3efba4d21ac1b51b4b823e5082d556bc3d6cf3fd2ab3188f9f218fc1", + "id": "8d08797efc8230b480ec669c7e2bf53c3b3d16bc59bf7770934b34fd892934f8", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -312,16 +314,77 @@ "elements": [ { "type": "variable", - "name": "text2", + "name": "should_be_constant_2", "source_mapping": { - "start": 333, + "start": 841, + "length": 33, + "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 43 + ], + "starting_column": 5, + "ending_column": 38 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 746, + "length": 386, + "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.5.16/const_state_variables.sol#43) should be constant \n", + "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L43) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L43", + "id": "d08c6d1e331083b42c45c222691dd1e6d880814c66d114971875337ca61ba9c9", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "test", + "source_mapping": { + "start": 237, "length": 20, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "is_dependency": false, "lines": [ - 14 + 10 ], "starting_column": 5, "ending_column": 25 @@ -364,10 +427,10 @@ } } ], - "description": "A.text2 (tests/detectors/constable-states/0.5.16/const_state_variables.sol#14) should be constant\n", - "markdown": "[A.text2](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L14) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L14", - "id": "df11e6201c4558a8c5cd90b55b134b9ca8f07203b2264d3aa93bd7745e8cb4ba", + "description": "A.test (tests/detectors/constable-states/0.5.16/const_state_variables.sol#10) should be constant \n", + "markdown": "[A.test](tests/detectors/constable-states/0.5.16/const_state_variables.sol#L10) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.5.16/const_state_variables.sol#L10", + "id": "e407a1b57b4d25949ef7c4e6d97197605857099a94774a9c7a848d7dd3463668", "check": "constable-states", "impact": "Optimization", "confidence": "High" diff --git a/tests/detectors/constable-states/0.6.11/const_state_variables.sol b/tests/detectors/constable-states/0.6.11/const_state_variables.sol index 3b0c1a436..66415fd9d 100644 --- a/tests/detectors/constable-states/0.6.11/const_state_variables.sol +++ b/tests/detectors/constable-states/0.6.11/const_state_variables.sol @@ -1,5 +1,3 @@ -//pragma solidity ^0.4.24; - contract A { @@ -36,15 +34,17 @@ contract B is A { } } -contract MyConc{ +contract MyConc { uint constant A = 1; bytes32 should_be_constant = sha256('abc'); uint should_be_constant_2 = A + 1; + B should_be_constant_3 = B(address(0)); address not_constant = msg.sender; uint not_constant_2 = getNumber(); uint not_constant_3 = 10 + block.number; - + B not_constant_4 = new B(); + function getNumber() public returns(uint){ return block.number; } diff --git a/tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.ConstCandidateStateVars.json index 3c7812877..cbb8ecbc1 100644 --- a/tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.ConstCandidateStateVars.json +++ b/tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.ConstCandidateStateVars.json @@ -4,50 +4,48 @@ "elements": [ { "type": "variable", - "name": "myFriendsAddress", + "name": "should_be_constant_3", "source_mapping": { - "start": 132, - "length": 76, + "start": 853, + "length": 38, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 7 + 42 ], "starting_column": 5, - "ending_column": 81 + "ending_column": 43 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "A", + "name": "MyConc", "source_mapping": { - "start": 29, - "length": 441, + "start": 718, + "length": 415, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21 + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 ], "starting_column": 1, "ending_column": 2 @@ -56,10 +54,10 @@ } } ], - "description": "A.myFriendsAddress (tests/detectors/constable-states/0.6.11/const_state_variables.sol#7) should be constant\n", - "markdown": "[A.myFriendsAddress](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L7) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L7", - "id": "1454db80653b732bf6acbe54ff0ae4707002207a2a8216708c12d61c88a43e5f", + "description": "MyConc.should_be_constant_3 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#42) should be constant \n", + "markdown": "[MyConc.should_be_constant_3](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L42) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L42", + "id": "29247b0a9939e854ad51bf3b2f58705156aa8b7e446e646b1832467d362b5b3e", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -68,16 +66,16 @@ "elements": [ { "type": "variable", - "name": "test", + "name": "text2", "source_mapping": { - "start": 237, + "start": 305, "length": 20, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 10 + 12 ], "starting_column": 5, "ending_column": 25 @@ -87,13 +85,15 @@ "type": "contract", "name": "A", "source_mapping": { - "start": 29, + "start": 1, "length": 441, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ + 2, + 3, 4, 5, 6, @@ -109,9 +109,7 @@ 16, 17, 18, - 19, - 20, - 21 + 19 ], "starting_column": 1, "ending_column": 2 @@ -120,10 +118,10 @@ } } ], - "description": "A.test (tests/detectors/constable-states/0.6.11/const_state_variables.sol#10) should be constant\n", - "markdown": "[A.test](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L10) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L10", - "id": "5d9e3fb413322b71a93e90f7e89bd8c83cd4884d577d039598c681fe9db38b1d", + "description": "A.text2 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#12) should be constant \n", + "markdown": "[A.text2](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L12) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L12", + "id": "2f06e04545cea7e7a8998c65d5419f335bf2579a6ce6a832eac9c87392fd5c1a", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -132,46 +130,46 @@ "elements": [ { "type": "variable", - "name": "should_be_constant_2", + "name": "mySistersAddress", "source_mapping": { - "start": 841, - "length": 33, + "start": 468, + "length": 76, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 43 + 24 ], "starting_column": 5, - "ending_column": 38 + "ending_column": 81 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "B", "source_mapping": { - "start": 746, - "length": 342, + "start": 445, + "length": 271, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35 ], "starting_column": 1, "ending_column": 2 @@ -180,10 +178,10 @@ } } ], - "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#43) should be constant\n", - "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L43) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L43", - "id": "9a48a4122de1a6a4774a9f1e0d4917bd0fa08f17b4af41b86ba07689e51bf711", + "description": "B.mySistersAddress (tests/detectors/constable-states/0.6.11/const_state_variables.sol#24) should be constant \n", + "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L24) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L24", + "id": "3b5bff93954a48a79387e7981e8c45d78edc575a0988a10f1c7f439b9f930539", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -192,16 +190,16 @@ "elements": [ { "type": "variable", - "name": "mySistersAddress", + "name": "myFriendsAddress", "source_mapping": { - "start": 496, + "start": 104, "length": 76, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 26 + 5 ], "starting_column": 5, "ending_column": 81 @@ -209,29 +207,33 @@ "type_specific_fields": { "parent": { "type": "contract", - "name": "B", + "name": "A", "source_mapping": { - "start": 473, - "length": 271, + "start": 1, + "length": 441, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37 + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19 ], "starting_column": 1, "ending_column": 2 @@ -240,10 +242,10 @@ } } ], - "description": "B.mySistersAddress (tests/detectors/constable-states/0.6.11/const_state_variables.sol#26) should be constant\n", - "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L26) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L26", - "id": "bee93a722c8eae4a48aade67d8ef537d84c106f48fc9eb738c795fce10d3bc63", + "description": "A.myFriendsAddress (tests/detectors/constable-states/0.6.11/const_state_variables.sol#5) should be constant \n", + "markdown": "[A.myFriendsAddress](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L5) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L5", + "id": "52fd72f6870c4b504d1bcf9fb44249658e2077474d66208a33a47d2668b8db49", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -254,14 +256,14 @@ "type": "variable", "name": "should_be_constant", "source_mapping": { - "start": 793, + "start": 766, "length": 42, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 42 + 40 ], "starting_column": 5, "ending_column": 47 @@ -271,13 +273,15 @@ "type": "contract", "name": "MyConc", "source_mapping": { - "start": 746, - "length": 342, + "start": 718, + "length": 415, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ + 37, + 38, 39, 40, 41, @@ -300,10 +304,10 @@ } } ], - "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.6.11/const_state_variables.sol#42) should be constant\n", - "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L42) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L42", - "id": "cbcafa2a3efba4d21ac1b51b4b823e5082d556bc3d6cf3fd2ab3188f9f218fc1", + "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.6.11/const_state_variables.sol#40) should be constant \n", + "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L40) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L40", + "id": "8d08797efc8230b480ec669c7e2bf53c3b3d16bc59bf7770934b34fd892934f8", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -312,16 +316,78 @@ "elements": [ { "type": "variable", - "name": "text2", + "name": "should_be_constant_2", + "source_mapping": { + "start": 814, + "length": 33, + "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 41 + ], + "starting_column": 5, + "ending_column": 38 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 415, + "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#41) should be constant \n", + "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L41) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L41", + "id": "d08c6d1e331083b42c45c222691dd1e6d880814c66d114971875337ca61ba9c9", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "test", "source_mapping": { - "start": 333, + "start": 209, "length": 20, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 14 + 8 ], "starting_column": 5, "ending_column": 25 @@ -331,13 +397,15 @@ "type": "contract", "name": "A", "source_mapping": { - "start": 29, + "start": 1, "length": 441, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ + 2, + 3, 4, 5, 6, @@ -353,9 +421,7 @@ 16, 17, 18, - 19, - 20, - 21 + 19 ], "starting_column": 1, "ending_column": 2 @@ -364,10 +430,10 @@ } } ], - "description": "A.text2 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#14) should be constant\n", - "markdown": "[A.text2](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L14) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L14", - "id": "df11e6201c4558a8c5cd90b55b134b9ca8f07203b2264d3aa93bd7745e8cb4ba", + "description": "A.test (tests/detectors/constable-states/0.6.11/const_state_variables.sol#8) should be constant \n", + "markdown": "[A.test](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L8) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L8", + "id": "e407a1b57b4d25949ef7c4e6d97197605857099a94774a9c7a848d7dd3463668", "check": "constable-states", "impact": "Optimization", "confidence": "High" diff --git a/tests/detectors/constable-states/0.7.6/const_state_variables.sol b/tests/detectors/constable-states/0.7.6/const_state_variables.sol index 3b0c1a436..93292dc47 100644 --- a/tests/detectors/constable-states/0.7.6/const_state_variables.sol +++ b/tests/detectors/constable-states/0.7.6/const_state_variables.sol @@ -1,5 +1,3 @@ -//pragma solidity ^0.4.24; - contract A { @@ -36,15 +34,17 @@ contract B is A { } } -contract MyConc{ +contract MyConc { uint constant A = 1; bytes32 should_be_constant = sha256('abc'); uint should_be_constant_2 = A + 1; - address not_constant = msg.sender; - uint not_constant_2 = getNumber(); - uint not_constant_3 = 10 + block.number; - + B should_be_constant_3 = B(address(0)); + address should_be_immutable = msg.sender; + uint should_be_immutable_2 = getNumber(); + uint should_be_immutable_3 = 10 + block.number; + B should_be_immutable_4 = new B(); + function getNumber() public returns(uint){ return block.number; } diff --git a/tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.ConstCandidateStateVars.json index 3cb6d44c4..18c869d56 100644 --- a/tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.ConstCandidateStateVars.json +++ b/tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.ConstCandidateStateVars.json @@ -4,32 +4,96 @@ "elements": [ { "type": "variable", - "name": "myFriendsAddress", + "name": "should_be_constant_3", "source_mapping": { - "start": 132, - "length": 76, + "start": 853, + "length": 38, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 7 + 42 ], "starting_column": 5, - "ending_column": 81 + "ending_column": 43 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_constant_3 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#42) should be constant \n", + "markdown": "[MyConc.should_be_constant_3](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L42) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L42", + "id": "29247b0a9939e854ad51bf3b2f58705156aa8b7e446e646b1832467d362b5b3e", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "text2", + "source_mapping": { + "start": 305, + "length": 20, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 12 + ], + "starting_column": 5, + "ending_column": 25 }, "type_specific_fields": { "parent": { "type": "contract", "name": "A", "source_mapping": { - "start": 29, + "start": 1, "length": 441, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ + 2, + 3, 4, 5, 6, @@ -45,9 +109,7 @@ 16, 17, 18, - 19, - 20, - 21 + 19 ], "starting_column": 1, "ending_column": 2 @@ -56,10 +118,10 @@ } } ], - "description": "A.myFriendsAddress (tests/detectors/constable-states/0.7.6/const_state_variables.sol#7) should be constant\n", - "markdown": "[A.myFriendsAddress](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L7) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L7", - "id": "1454db80653b732bf6acbe54ff0ae4707002207a2a8216708c12d61c88a43e5f", + "description": "A.text2 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#12) should be constant \n", + "markdown": "[A.text2](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L12) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L12", + "id": "2f06e04545cea7e7a8998c65d5419f335bf2579a6ce6a832eac9c87392fd5c1a", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -68,32 +130,156 @@ "elements": [ { "type": "variable", - "name": "test", + "name": "mySistersAddress", "source_mapping": { - "start": 237, - "length": 20, + "start": 468, + "length": 76, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 10 + 24 ], "starting_column": 5, - "ending_column": 25 + "ending_column": 81 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "B", + "source_mapping": { + "start": 445, + "length": 271, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "B.mySistersAddress (tests/detectors/constable-states/0.7.6/const_state_variables.sol#24) should be constant \n", + "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L24) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L24", + "id": "3b5bff93954a48a79387e7981e8c45d78edc575a0988a10f1c7f439b9f930539", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable", + "source_mapping": { + "start": 897, + "length": 40, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 43 + ], + "starting_column": 5, + "ending_column": 45 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_immutable (tests/detectors/constable-states/0.7.6/const_state_variables.sol#43) should be immutable \n", + "markdown": "[MyConc.should_be_immutable](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L43) should be immutable \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L43", + "id": "3cabd54a4d3fa32f960965a41bb09b62052286195b47b2b7db670f87e8df21bf", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "myFriendsAddress", + "source_mapping": { + "start": 104, + "length": 76, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 5 + ], + "starting_column": 5, + "ending_column": 81 }, "type_specific_fields": { "parent": { "type": "contract", "name": "A", "source_mapping": { - "start": 29, + "start": 1, "length": 441, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ + 2, + 3, 4, 5, 6, @@ -109,9 +295,7 @@ 16, 17, 18, - 19, - 20, - 21 + 19 ], "starting_column": 1, "ending_column": 2 @@ -120,10 +304,10 @@ } } ], - "description": "A.test (tests/detectors/constable-states/0.7.6/const_state_variables.sol#10) should be constant\n", - "markdown": "[A.test](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L10) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L10", - "id": "5d9e3fb413322b71a93e90f7e89bd8c83cd4884d577d039598c681fe9db38b1d", + "description": "A.myFriendsAddress (tests/detectors/constable-states/0.7.6/const_state_variables.sol#5) should be constant \n", + "markdown": "[A.myFriendsAddress](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L5) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L5", + "id": "52fd72f6870c4b504d1bcf9fb44249658e2077474d66208a33a47d2668b8db49", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -132,16 +316,78 @@ "elements": [ { "type": "variable", - "name": "should_be_constant_2", + "name": "should_be_constant", "source_mapping": { - "start": 841, + "start": 766, + "length": 42, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 40 + ], + "starting_column": 5, + "ending_column": 47 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.7.6/const_state_variables.sol#40) should be constant \n", + "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L40) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L40", + "id": "8d08797efc8230b480ec669c7e2bf53c3b3d16bc59bf7770934b34fd892934f8", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_4", + "source_mapping": { + "start": 1041, "length": 33, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 43 + 46 ], "starting_column": 5, "ending_column": 38 @@ -151,13 +397,15 @@ "type": "contract", "name": "MyConc", "source_mapping": { - "start": 746, - "length": 342, + "start": 718, + "length": 443, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ + 37, + 38, 39, 40, 41, @@ -180,10 +428,10 @@ } } ], - "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#43) should be constant\n", - "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L43) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L43", - "id": "9a48a4122de1a6a4774a9f1e0d4917bd0fa08f17b4af41b86ba07689e51bf711", + "description": "MyConc.should_be_immutable_4 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#46) should be immutable \n", + "markdown": "[MyConc.should_be_immutable_4](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L46) should be immutable \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L46", + "id": "a15e34bd516e604d7ba3e0746ad0234d0baea38da2e747648316d5d15ee9b3bc", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -192,46 +440,48 @@ "elements": [ { "type": "variable", - "name": "mySistersAddress", + "name": "should_be_immutable_2", "source_mapping": { - "start": 496, - "length": 76, + "start": 943, + "length": 40, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 26 + 44 ], "starting_column": 5, - "ending_column": 81 + "ending_column": 45 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "B", + "name": "MyConc", "source_mapping": { - "start": 473, - "length": 271, + "start": 718, + "length": 443, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37 + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 ], "starting_column": 1, "ending_column": 2 @@ -240,10 +490,10 @@ } } ], - "description": "B.mySistersAddress (tests/detectors/constable-states/0.7.6/const_state_variables.sol#26) should be constant\n", - "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L26) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L26", - "id": "bee93a722c8eae4a48aade67d8ef537d84c106f48fc9eb738c795fce10d3bc63", + "description": "MyConc.should_be_immutable_2 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#44) should be immutable \n", + "markdown": "[MyConc.should_be_immutable_2](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L44) should be immutable \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L44", + "id": "cb6df1f1ce2f32505c81f257863ceef6d5145ee5a2835af1c6719ad695d145e2", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -252,32 +502,34 @@ "elements": [ { "type": "variable", - "name": "should_be_constant", + "name": "should_be_constant_2", "source_mapping": { - "start": 793, - "length": 42, + "start": 814, + "length": 33, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 42 + 41 ], "starting_column": 5, - "ending_column": 47 + "ending_column": 38 }, "type_specific_fields": { "parent": { "type": "contract", "name": "MyConc", "source_mapping": { - "start": 746, - "length": 342, + "start": 718, + "length": 443, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ + 37, + 38, 39, 40, 41, @@ -300,10 +552,10 @@ } } ], - "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.7.6/const_state_variables.sol#42) should be constant\n", - "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L42) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L42", - "id": "cbcafa2a3efba4d21ac1b51b4b823e5082d556bc3d6cf3fd2ab3188f9f218fc1", + "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#41) should be constant \n", + "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L41) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L41", + "id": "d08c6d1e331083b42c45c222691dd1e6d880814c66d114971875337ca61ba9c9", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -312,16 +564,78 @@ "elements": [ { "type": "variable", - "name": "text2", + "name": "should_be_immutable_3", + "source_mapping": { + "start": 989, + "length": 46, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 45 + ], + "starting_column": 5, + "ending_column": 51 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_immutable_3 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#45) should be immutable \n", + "markdown": "[MyConc.should_be_immutable_3](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L45) should be immutable \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L45", + "id": "dc5903ef8f6ec62f53df486fa768a0d817643efe30c90c1308079eee99c316d4", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "test", "source_mapping": { - "start": 333, + "start": 209, "length": 20, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 14 + 8 ], "starting_column": 5, "ending_column": 25 @@ -331,13 +645,15 @@ "type": "contract", "name": "A", "source_mapping": { - "start": 29, + "start": 1, "length": 441, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ + 2, + 3, 4, 5, 6, @@ -353,9 +669,7 @@ 16, 17, 18, - 19, - 20, - 21 + 19 ], "starting_column": 1, "ending_column": 2 @@ -364,10 +678,10 @@ } } ], - "description": "A.text2 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#14) should be constant\n", - "markdown": "[A.text2](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L14) should be constant\n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L14", - "id": "df11e6201c4558a8c5cd90b55b134b9ca8f07203b2264d3aa93bd7745e8cb4ba", + "description": "A.test (tests/detectors/constable-states/0.7.6/const_state_variables.sol#8) should be constant \n", + "markdown": "[A.test](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L8) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L8", + "id": "e407a1b57b4d25949ef7c4e6d97197605857099a94774a9c7a848d7dd3463668", "check": "constable-states", "impact": "Optimization", "confidence": "High" diff --git a/tests/detectors/constable-states/0.8.0/const_state_variables.sol b/tests/detectors/constable-states/0.8.0/const_state_variables.sol new file mode 100644 index 000000000..93292dc47 --- /dev/null +++ b/tests/detectors/constable-states/0.8.0/const_state_variables.sol @@ -0,0 +1,52 @@ + +contract A { + + address constant public MY_ADDRESS = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9; + address public myFriendsAddress = 0xc0ffee254729296a45a3885639AC7E10F9d54979; + + uint public used; + uint public test = 5; + + uint constant X = 32**22 + 8; + string constant TEXT1 = "abc"; + string text2 = "xyz"; + + function setUsed() public { + if (msg.sender == MY_ADDRESS) { + used = test; + } + } +} + + +contract B is A { + + address public mySistersAddress = 0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E; + + fallback () external { + used = 0; + } + + function setUsed(uint a) public { + if (msg.sender == MY_ADDRESS) { + used = a; + } + } +} + +contract MyConc { + + uint constant A = 1; + bytes32 should_be_constant = sha256('abc'); + uint should_be_constant_2 = A + 1; + B should_be_constant_3 = B(address(0)); + address should_be_immutable = msg.sender; + uint should_be_immutable_2 = getNumber(); + uint should_be_immutable_3 = 10 + block.number; + B should_be_immutable_4 = new B(); + + function getNumber() public returns(uint){ + return block.number; + } + +} diff --git a/tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.ConstCandidateStateVars.json new file mode 100644 index 000000000..e36a2988d --- /dev/null +++ b/tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.ConstCandidateStateVars.json @@ -0,0 +1,690 @@ +[ + [ + { + "elements": [ + { + "type": "variable", + "name": "should_be_constant_3", + "source_mapping": { + "start": 853, + "length": 38, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 42 + ], + "starting_column": 5, + "ending_column": 43 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_constant_3 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#42) should be constant \n", + "markdown": "[MyConc.should_be_constant_3](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L42) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L42", + "id": "29247b0a9939e854ad51bf3b2f58705156aa8b7e446e646b1832467d362b5b3e", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "text2", + "source_mapping": { + "start": 305, + "length": 20, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 12 + ], + "starting_column": 5, + "ending_column": 25 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "A", + "source_mapping": { + "start": 1, + "length": 441, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "A.text2 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#12) should be constant \n", + "markdown": "[A.text2](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L12) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L12", + "id": "2f06e04545cea7e7a8998c65d5419f335bf2579a6ce6a832eac9c87392fd5c1a", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "mySistersAddress", + "source_mapping": { + "start": 468, + "length": 76, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 24 + ], + "starting_column": 5, + "ending_column": 81 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "B", + "source_mapping": { + "start": 445, + "length": 271, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "B.mySistersAddress (tests/detectors/constable-states/0.8.0/const_state_variables.sol#24) should be constant \n", + "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L24) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L24", + "id": "3b5bff93954a48a79387e7981e8c45d78edc575a0988a10f1c7f439b9f930539", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable", + "source_mapping": { + "start": 897, + "length": 40, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 43 + ], + "starting_column": 5, + "ending_column": 45 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_immutable (tests/detectors/constable-states/0.8.0/const_state_variables.sol#43) should be immutable \n", + "markdown": "[MyConc.should_be_immutable](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L43) should be immutable \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L43", + "id": "3cabd54a4d3fa32f960965a41bb09b62052286195b47b2b7db670f87e8df21bf", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "myFriendsAddress", + "source_mapping": { + "start": 104, + "length": 76, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 5 + ], + "starting_column": 5, + "ending_column": 81 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "A", + "source_mapping": { + "start": 1, + "length": 441, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "A.myFriendsAddress (tests/detectors/constable-states/0.8.0/const_state_variables.sol#5) should be constant \n", + "markdown": "[A.myFriendsAddress](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L5) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L5", + "id": "52fd72f6870c4b504d1bcf9fb44249658e2077474d66208a33a47d2668b8db49", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_constant", + "source_mapping": { + "start": 766, + "length": 42, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 40 + ], + "starting_column": 5, + "ending_column": 47 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.8.0/const_state_variables.sol#40) should be constant \n", + "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L40) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L40", + "id": "8d08797efc8230b480ec669c7e2bf53c3b3d16bc59bf7770934b34fd892934f8", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_4", + "source_mapping": { + "start": 1041, + "length": 33, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 46 + ], + "starting_column": 5, + "ending_column": 38 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_immutable_4 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#46) should be immutable \n", + "markdown": "[MyConc.should_be_immutable_4](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L46) should be immutable \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L46", + "id": "a15e34bd516e604d7ba3e0746ad0234d0baea38da2e747648316d5d15ee9b3bc", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_2", + "source_mapping": { + "start": 943, + "length": 40, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 44 + ], + "starting_column": 5, + "ending_column": 45 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_immutable_2 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#44) should be immutable \n", + "markdown": "[MyConc.should_be_immutable_2](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L44) should be immutable \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L44", + "id": "cb6df1f1ce2f32505c81f257863ceef6d5145ee5a2835af1c6719ad695d145e2", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_constant_2", + "source_mapping": { + "start": 814, + "length": 33, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 41 + ], + "starting_column": 5, + "ending_column": 38 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#41) should be constant \n", + "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L41) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L41", + "id": "d08c6d1e331083b42c45c222691dd1e6d880814c66d114971875337ca61ba9c9", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_3", + "source_mapping": { + "start": 989, + "length": 46, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 45 + ], + "starting_column": 5, + "ending_column": 51 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "MyConc", + "source_mapping": { + "start": 718, + "length": 443, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "MyConc.should_be_immutable_3 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#45) should be immutable \n", + "markdown": "[MyConc.should_be_immutable_3](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L45) should be immutable \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L45", + "id": "dc5903ef8f6ec62f53df486fa768a0d817643efe30c90c1308079eee99c316d4", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "test", + "source_mapping": { + "start": 209, + "length": 20, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 8 + ], + "starting_column": 5, + "ending_column": 25 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "A", + "source_mapping": { + "start": 1, + "length": 441, + "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", + "is_dependency": false, + "lines": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "A.test (tests/detectors/constable-states/0.8.0/const_state_variables.sol#8) should be constant \n", + "markdown": "[A.test](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L8) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L8", + "id": "e407a1b57b4d25949ef7c4e6d97197605857099a94774a9c7a848d7dd3463668", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + } + ] +] \ No newline at end of file diff --git a/tests/detectors/constable-states/0.8.0/immutable.sol b/tests/detectors/constable-states/0.8.0/immutable.sol deleted file mode 100644 index aeb9fbfa7..000000000 --- a/tests/detectors/constable-states/0.8.0/immutable.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract C{ - uint immutable v; - - constructor() public{ - v = 0; - } -} diff --git a/tests/detectors/constable-states/0.8.0/immutable.sol.0.8.0.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.8.0/immutable.sol.0.8.0.ConstCandidateStateVars.json deleted file mode 100644 index 5825bcacc..000000000 --- a/tests/detectors/constable-states/0.8.0/immutable.sol.0.8.0.ConstCandidateStateVars.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - [] -] \ No newline at end of file diff --git a/tests/test_detectors.py b/tests/test_detectors.py index 7a27e2d4b..46fff79b0 100644 --- a/tests/test_detectors.py +++ b/tests/test_detectors.py @@ -497,7 +497,7 @@ ALL_TEST_OBJECTS = [ ), Test( all_detectors.ConstCandidateStateVars, - "immutable.sol", + "const_state_variables.sol", "0.8.0", ), Test( From cf5d04f2901c02fc942a978d26373550bd4c8ffb Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Mon, 28 Nov 2022 08:33:00 -0600 Subject: [PATCH 02/61] ignore openzeppelin contracts --- .../variables/possible_const_state_variables.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/slither/detectors/variables/possible_const_state_variables.py b/slither/detectors/variables/possible_const_state_variables.py index 4337b3075..60a45dfac 100644 --- a/slither/detectors/variables/possible_const_state_variables.py +++ b/slither/detectors/variables/possible_const_state_variables.py @@ -15,6 +15,7 @@ from slither.core.declarations.solidity_variables import SolidityFunction from slither.core.variables.state_variable import StateVariable from slither.formatters.variables.possible_const_state_variables import custom_format from slither.core.expressions import CallExpression, NewContract +from slither.utils.standard_libraries import is_openzeppelin def _is_valid_type(v: StateVariable) -> bool: @@ -84,10 +85,8 @@ class ConstCandidateStateVars(AbstractDetector): values = export.result() if not values: return True - else: - return all( - (val in self.valid_solidity_function or _is_constant_var(val) for val in values) - ) + + return all((val in self.valid_solidity_function or _is_constant_var(val) for val in values)) def _detect(self) -> List[Output]: """Detect state variables that could be constant or immutable""" @@ -96,6 +95,8 @@ class ConstCandidateStateVars(AbstractDetector): variables = [] functions = [] for c in self.compilation_unit.contracts: + if is_openzeppelin(c): + continue variables.append(c.state_variables) functions.append(c.all_functions_called) From e7aa92bbb055068d3c95f2a3eca612d3ec31c64e Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Mon, 5 Dec 2022 17:57:29 +0100 Subject: [PATCH 03/61] Use Codex to generate solidity documentation --- setup.py | 1 + slither/core/declarations/function.py | 3 + slither/solc_parsing/declarations/function.py | 3 + slither/tools/documentation/README.md | 6 + slither/tools/documentation/__init__.py | 0 slither/tools/documentation/__main__.py | 141 ++++++++++++++++++ 6 files changed, 154 insertions(+) create mode 100644 slither/tools/documentation/README.md create mode 100644 slither/tools/documentation/__init__.py create mode 100644 slither/tools/documentation/__main__.py diff --git a/setup.py b/setup.py index 510efd097..81680a39a 100644 --- a/setup.py +++ b/setup.py @@ -45,6 +45,7 @@ setup( "slither-mutate = slither.tools.mutator.__main__:main", "slither-read-storage = slither.tools.read_storage.__main__:main", "slither-doctor = slither.tools.doctor.__main__:main", + "slither-documentation = slither.tools.documentation.__main__:main", ] }, ) diff --git a/slither/core/declarations/function.py b/slither/core/declarations/function.py index a4624feec..2fdea7210 100644 --- a/slither/core/declarations/function.py +++ b/slither/core/declarations/function.py @@ -220,6 +220,9 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu self._id: Optional[str] = None + # To be improved with a parsing of the documentation + self.has_documentation: bool = False + ################################################################################### ################################################################################### # region General properties diff --git a/slither/solc_parsing/declarations/function.py b/slither/solc_parsing/declarations/function.py index 130375211..40ddba07e 100644 --- a/slither/solc_parsing/declarations/function.py +++ b/slither/solc_parsing/declarations/function.py @@ -91,6 +91,9 @@ class FunctionSolc(CallerContextExpression): Union[LocalVariableSolc, LocalVariableInitFromTupleSolc] ] = [] + if "documentation" in function_data: + function.has_documentation = True + @property def underlying_function(self) -> Function: return self._function diff --git a/slither/tools/documentation/README.md b/slither/tools/documentation/README.md new file mode 100644 index 000000000..2ed90692c --- /dev/null +++ b/slither/tools/documentation/README.md @@ -0,0 +1,6 @@ +# Demo + +This directory contains an example of Slither utility. + +See the [utility documentation](https://github.com/crytic/slither/wiki/Adding-a-new-utility) + diff --git a/slither/tools/documentation/__init__.py b/slither/tools/documentation/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/slither/tools/documentation/__main__.py b/slither/tools/documentation/__main__.py new file mode 100644 index 000000000..b01072d1c --- /dev/null +++ b/slither/tools/documentation/__main__.py @@ -0,0 +1,141 @@ +import argparse +import logging +from typing import Optional, Dict +import os +import openai +from crytic_compile import cryticparser +from slither import Slither +from slither.core.compilation_unit import SlitherCompilationUnit + +from slither.formatters.utils.patches import create_patch, apply_patch, create_diff + +logging.basicConfig() +logging.getLogger("Slither").setLevel(logging.INFO) + +logger = logging.getLogger("Slither-demo") + + +def parse_args() -> argparse.Namespace: + """ + Parse the underlying arguments for the program. + :return: Returns the arguments for the program. + """ + parser = argparse.ArgumentParser(description="Demo", usage="slither-documentation filename") + + parser.add_argument("project", help="The target directory/Solidity file.") + + parser.add_argument( + "--overwrite", help="Overwrite the files (be careful).", action="store_true", default=False + ) + + # Add default arguments from crytic-compile + cryticparser.init(parser) + + return parser.parse_args() + + +def _post_processesing(answer: str, starting_column: int) -> Optional[str]: + """ + Clean answers from codex + + Args: + answer: + starting_column: + + Returns: + + """ + if answer.count("/**") != 1 or answer.count("*/") != 1: + return None + if answer.find("/**") > answer.find("*/"): + return None + answer = answer[answer.find("/**") : answer.find("*/") + 2] + answer_lines = answer.splitlines() + # Add indentation to all the lines, aside the first one + if len(answer_lines) > 0: + answer = ( + answer_lines[0] + + "\n" + + "\n".join([" " * (starting_column - 1) + line for line in answer_lines[1:] if line]) + ) + answer += "\n" + " " * (starting_column - 1) + return answer + return answer_lines[0] + + +def _handle_codex(answer: Dict, starting_column: int) -> Optional[str]: + if "choices" in answer: + if answer["choices"]: + if "text" in answer["choices"][0]: + answer_processed = _post_processesing(answer["choices"][0]["text"], starting_column) + if answer_processed is None: + return None + return answer_processed + return None + +# pylint: disable=too-many-locals +def _handle_compilation_unit(compilation_unit: SlitherCompilationUnit, overwrite: bool) -> None: + all_patches: Dict = {} + + for function in compilation_unit.functions: + if function.source_mapping.is_dependency or function.has_documentation: + continue + prompt = "Create a documentation for the solidity code using natspec (use only notice, dev, params, return)\n" + src_mapping = function.source_mapping + content = compilation_unit.core.source_code[src_mapping.filename.absolute] + start = src_mapping.start + end = src_mapping.start + src_mapping.length + prompt += content[start:end] + answer = openai.Completion.create( # type: ignore + model="text-davinci-003", prompt=prompt, temperature=0, max_tokens=200 + ) + + answer_processed = _handle_codex(answer, src_mapping.starting_column) + if answer_processed is None: + print(f"Codex could not generate a well formatted answer for {function.canonical_name}") + print(answer) + continue + + create_patch(all_patches, src_mapping.filename.absolute, start, start, "", answer_processed) + + # cat math.sol + # slither-documentation math.sol --overwrite + # cat math.sol + # exit + for file in all_patches["patches"]: + original_txt = compilation_unit.core.source_code[file].encode("utf8") + patched_txt = original_txt + + patches = all_patches["patches"][file] + offset = 0 + patches.sort(key=lambda x: x["start"]) + + for patch in patches: + patched_txt, offset = apply_patch(patched_txt, patch, offset) + + if overwrite: + with open(file, "w", encoding="utf8") as f: + f.write(patched_txt.decode("utf8")) + else: + diff = create_diff(compilation_unit, original_txt, patched_txt, file) + with open(f"{file}.patch", "w", encoding="utf8") as f: + f.write(diff) + + +def main() -> None: + args = parse_args() + + slither = Slither(args.project, **vars(args)) + + api_key = os.getenv("OPENAI_API_KEY") + if api_key is None: + print("Please provide an Open API Key (https://beta.openai.com/account/api-keys)") + return + openai.api_key = api_key + + for compilation_unit in slither.compilation_units: + _handle_compilation_unit(compilation_unit, args.overwrite) + + +if __name__ == "__main__": + main() From c38c4cb23780eb06e3d49672488057530af40155 Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Mon, 5 Dec 2022 18:13:07 +0100 Subject: [PATCH 04/61] Fix CI --- .github/workflows/ci.yml | 2 +- slither/tools/documentation/__main__.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ae5326a8..3c188ce56 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: matrix: os: ["ubuntu-latest", "windows-2022"] type: ["cli", - "dapp", + # "dapp", "data_dependency", "path_filtering", # "embark", diff --git a/slither/tools/documentation/__main__.py b/slither/tools/documentation/__main__.py index b01072d1c..c3979de64 100644 --- a/slither/tools/documentation/__main__.py +++ b/slither/tools/documentation/__main__.py @@ -73,6 +73,7 @@ def _handle_codex(answer: Dict, starting_column: int) -> Optional[str]: return answer_processed return None + # pylint: disable=too-many-locals def _handle_compilation_unit(compilation_unit: SlitherCompilationUnit, overwrite: bool) -> None: all_patches: Dict = {} From b484bde1f39a595f34ffa261b1a494c297099f3f Mon Sep 17 00:00:00 2001 From: Feist Josselin Date: Mon, 5 Dec 2022 19:33:50 +0100 Subject: [PATCH 05/61] Update ci.yml --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c188ce56..f25929ea4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,6 @@ jobs: matrix: os: ["ubuntu-latest", "windows-2022"] type: ["cli", - # "dapp", "data_dependency", "path_filtering", # "embark", From 2d64e16fadc2913bfcd3a7b1bc4776c1ad59cd7c Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Tue, 6 Dec 2022 11:04:49 +0100 Subject: [PATCH 06/61] Reenable dapp --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f25929ea4..1ae5326a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,7 @@ jobs: matrix: os: ["ubuntu-latest", "windows-2022"] type: ["cli", + "dapp", "data_dependency", "path_filtering", # "embark", From 3537b95661759721823139369d3d1712faf31361 Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Wed, 7 Dec 2022 17:36:07 +0100 Subject: [PATCH 07/61] Improvements --- slither/__main__.py | 44 +---- slither/tools/documentation/__main__.py | 224 ++++++++++++++++++------ slither/utils/codex.py | 60 +++++++ 3 files changed, 229 insertions(+), 99 deletions(-) diff --git a/slither/__main__.py b/slither/__main__.py index 75707af06..d8fce1ce5 100644 --- a/slither/__main__.py +++ b/slither/__main__.py @@ -24,6 +24,7 @@ from slither.detectors.abstract_detector import AbstractDetector, DetectorClassi from slither.printers import all_printers from slither.printers.abstract_printer import AbstractPrinter from slither.slither import Slither +from slither.utils import codex from slither.utils.output import output_to_json, output_to_zip, output_to_sarif, ZIP_TYPES_ACCEPTED from slither.utils.output_capture import StandardOutputCapture from slither.utils.colors import red, set_colorization_enabled @@ -314,7 +315,6 @@ def parse_args( "Checklist (consider using https://github.com/crytic/slither-action)" ) group_misc = parser.add_argument_group("Additional options") - group_codex = parser.add_argument_group("Codex (https://beta.openai.com/docs/guides/code)") group_detector.add_argument( "--detect", @@ -555,47 +555,7 @@ def parse_args( default=False, ) - group_codex.add_argument( - "--codex", - help="Enable codex (require an OpenAI API Key)", - action="store_true", - default=defaults_flag_in_config["codex"], - ) - - group_codex.add_argument( - "--codex-log", - help="Log codex queries (in crytic_export/codex/)", - action="store_true", - default=False, - ) - - group_codex.add_argument( - "--codex-contracts", - help="Comma separated list of contracts to submit to OpenAI Codex", - action="store", - default=defaults_flag_in_config["codex_contracts"], - ) - - group_codex.add_argument( - "--codex-model", - help="Name of the Codex model to use (affects pricing). Defaults to 'text-davinci-003'", - action="store", - default=defaults_flag_in_config["codex_model"], - ) - - group_codex.add_argument( - "--codex-temperature", - help="Temperature to use with Codex. Lower number indicates a more precise answer while higher numbers return more creative answers. Defaults to 0", - action="store", - default=defaults_flag_in_config["codex_temperature"], - ) - - group_codex.add_argument( - "--codex-max-tokens", - help="Maximum amount of tokens to use on the response. This number plus the size of the prompt can be no larger than the limit (4097 for text-davinci-003)", - action="store", - default=defaults_flag_in_config["codex_max_tokens"], - ) + codex.init_parser(parser) # debugger command parser.add_argument("--debug", help=argparse.SUPPRESS, action="store_true", default=False) diff --git a/slither/tools/documentation/__main__.py b/slither/tools/documentation/__main__.py index c3979de64..ea45ed8e1 100644 --- a/slither/tools/documentation/__main__.py +++ b/slither/tools/documentation/__main__.py @@ -1,18 +1,19 @@ import argparse import logging -from typing import Optional, Dict -import os -import openai +import uuid +from typing import Optional, Dict, List from crytic_compile import cryticparser from slither import Slither from slither.core.compilation_unit import SlitherCompilationUnit +from slither.core.declarations import Function from slither.formatters.utils.patches import create_patch, apply_patch, create_diff +from slither.utils import codex logging.basicConfig() logging.getLogger("Slither").setLevel(logging.INFO) -logger = logging.getLogger("Slither-demo") +logger = logging.getLogger("Slither") def parse_args() -> argparse.Namespace: @@ -28,13 +29,43 @@ def parse_args() -> argparse.Namespace: "--overwrite", help="Overwrite the files (be careful).", action="store_true", default=False ) + parser.add_argument( + "--force-answer-parsing", + help="Apply heuristics to better parse codex output (might lead to incorrect results)", + action="store_true", + default=False, + ) + + parser.add_argument("--retry", help="Retry failed query (default 1). Each retry increases the temperature by 0.1", action="store", default=1) + # Add default arguments from crytic-compile cryticparser.init(parser) + codex.init_parser(parser, always_enable_codex=True) + return parser.parse_args() -def _post_processesing(answer: str, starting_column: int) -> Optional[str]: +def _use_tab(char: str) -> Optional[bool]: + """ + Check if the char is a tab + + Args: + char: + + Returns: + + """ + if char == " ": + return False + if char == "\t": + return True + return None + + +def _post_processesing( + answer: str, starting_column: int, use_tab: Optional[bool], force_and_stopped: bool +) -> Optional[str]: """ Clean answers from codex @@ -45,29 +76,46 @@ def _post_processesing(answer: str, starting_column: int) -> Optional[str]: Returns: """ - if answer.count("/**") != 1 or answer.count("*/") != 1: + if answer.count("/**") != 1: return None + # Sometimes codex will miss the */, even if it finished properly the request + # In this case, we allow slither-documentation to force the */ + if answer.count("*/") != 1: + if force_and_stopped: + answer += "*/" + else: + return None if answer.find("/**") > answer.find("*/"): return None answer = answer[answer.find("/**") : answer.find("*/") + 2] answer_lines = answer.splitlines() # Add indentation to all the lines, aside the first one + + space_char = "\t" if use_tab else " " + if len(answer_lines) > 0: answer = ( answer_lines[0] + "\n" - + "\n".join([" " * (starting_column - 1) + line for line in answer_lines[1:] if line]) + + "\n".join( + [space_char * (starting_column - 1) + line for line in answer_lines[1:] if line] + ) ) - answer += "\n" + " " * (starting_column - 1) + answer += "\n" + space_char * (starting_column - 1) return answer return answer_lines[0] -def _handle_codex(answer: Dict, starting_column: int) -> Optional[str]: +def _handle_codex( + answer: Dict, starting_column: int, use_tab: Optional[bool], force: bool +) -> Optional[str]: if "choices" in answer: if answer["choices"]: if "text" in answer["choices"][0]: - answer_processed = _post_processesing(answer["choices"][0]["text"], starting_column) + has_stopped = answer["choices"][0].get("finish_reason", "") == "stop" + answer_processed = _post_processesing( + answer["choices"][0]["text"], starting_column, use_tab, force and has_stopped + ) if answer_processed is None: return None return answer_processed @@ -75,67 +123,129 @@ def _handle_codex(answer: Dict, starting_column: int) -> Optional[str]: # pylint: disable=too-many-locals -def _handle_compilation_unit(compilation_unit: SlitherCompilationUnit, overwrite: bool) -> None: - all_patches: Dict = {} - - for function in compilation_unit.functions: - if function.source_mapping.is_dependency or function.has_documentation: +def _handle_compilation_unit( + slither: Slither, + compilation_unit: SlitherCompilationUnit, + overwrite: bool, + force: bool, + retry: int, +) -> None: + + logging_file = str(uuid.uuid4()) + + for scope in compilation_unit.scopes.values(): + + # TODO remove hardcoded filtering + if ( + ".t.sol" in scope.filename.absolute + or "mock" in scope.filename.absolute.lower() + or "test" in scope.filename.absolute.lower() + ): continue - prompt = "Create a documentation for the solidity code using natspec (use only notice, dev, params, return)\n" - src_mapping = function.source_mapping - content = compilation_unit.core.source_code[src_mapping.filename.absolute] - start = src_mapping.start - end = src_mapping.start + src_mapping.length - prompt += content[start:end] - answer = openai.Completion.create( # type: ignore - model="text-davinci-003", prompt=prompt, temperature=0, max_tokens=200 - ) - answer_processed = _handle_codex(answer, src_mapping.starting_column) - if answer_processed is None: - print(f"Codex could not generate a well formatted answer for {function.canonical_name}") - print(answer) + functions_target: List[Function] = [] + + for contract in scope.contracts.values(): + functions_target += contract.functions_declared + + functions_target += list(scope.functions) + + all_patches: Dict = {} + + for function in functions_target: + + if function.source_mapping.is_dependency or function.has_documentation or function.is_constructor_variables: + continue + prompt = ( + "Create a natpsec documentation for this solidity code with only notice and dev.\n" + ) + src_mapping = function.source_mapping + content = compilation_unit.core.source_code[src_mapping.filename.absolute] + start = src_mapping.start + end = src_mapping.start + src_mapping.length + prompt += content[start:end] + + use_tab = _use_tab(content[start - 1]) + if use_tab is None and src_mapping.starting_column > 1: + logger.info(f"Non standard space indentation found {content[start-1:end]}") + if overwrite: + logger.info("Disable overwrite to avoid mistakes") + overwrite = False + + openai = codex.openai_module() # type: ignore + if openai is None: + return + + if slither.codex_log: + codex.log_codex(logging_file, "Q: " + prompt) + + tentative = 0 + answer_processed: Optional[str] = None + while tentative < retry: + tentative += 1 + + answer = openai.Completion.create( # type: ignore + prompt=prompt, + model=slither.codex_model, + temperature=min(slither.codex_temperature + tentative*0.1, 1), + max_tokens=slither.codex_max_tokens, + ) + + if slither.codex_log: + codex.log_codex(logging_file, "A: " + str(answer)) + + answer_processed = _handle_codex( + answer, src_mapping.starting_column, use_tab, force + ) + if answer_processed: + break + + logger.info( + f"Codex could not generate a well formatted answer for {function.canonical_name}" + ) + logger.info(answer) + + if not answer_processed: + continue + + create_patch( + all_patches, src_mapping.filename.absolute, start, start, "", answer_processed + ) + + # all_patches["patches"] should have only 1 file + if "patches" not in all_patches: continue + for file in all_patches["patches"]: + original_txt = compilation_unit.core.source_code[file].encode("utf8") + patched_txt = original_txt - create_patch(all_patches, src_mapping.filename.absolute, start, start, "", answer_processed) - - # cat math.sol - # slither-documentation math.sol --overwrite - # cat math.sol - # exit - for file in all_patches["patches"]: - original_txt = compilation_unit.core.source_code[file].encode("utf8") - patched_txt = original_txt - - patches = all_patches["patches"][file] - offset = 0 - patches.sort(key=lambda x: x["start"]) + patches = all_patches["patches"][file] + offset = 0 + patches.sort(key=lambda x: x["start"]) - for patch in patches: - patched_txt, offset = apply_patch(patched_txt, patch, offset) + for patch in patches: + patched_txt, offset = apply_patch(patched_txt, patch, offset) - if overwrite: - with open(file, "w", encoding="utf8") as f: - f.write(patched_txt.decode("utf8")) - else: - diff = create_diff(compilation_unit, original_txt, patched_txt, file) - with open(f"{file}.patch", "w", encoding="utf8") as f: - f.write(diff) + if overwrite: + with open(file, "w", encoding="utf8") as f: + f.write(patched_txt.decode("utf8")) + else: + diff = create_diff(compilation_unit, original_txt, patched_txt, file) + with open(f"{file}.patch", "w", encoding="utf8") as f: + f.write(diff) def main() -> None: args = parse_args() + logger.info("This tool is a WIP, use it with cautious") + logger.info("Be aware of OpenAI ToS: https://openai.com/api/policies/terms/") slither = Slither(args.project, **vars(args)) - api_key = os.getenv("OPENAI_API_KEY") - if api_key is None: - print("Please provide an Open API Key (https://beta.openai.com/account/api-keys)") - return - openai.api_key = api_key - for compilation_unit in slither.compilation_units: - _handle_compilation_unit(compilation_unit, args.overwrite) + _handle_compilation_unit( + slither, compilation_unit, args.overwrite, args.force_answer_parsing, int(args.retry) + ) if __name__ == "__main__": diff --git a/slither/utils/codex.py b/slither/utils/codex.py index 0040fb03c..3b06efe6f 100644 --- a/slither/utils/codex.py +++ b/slither/utils/codex.py @@ -1,10 +1,70 @@ import logging import os +from argparse import ArgumentParser from pathlib import Path +from slither.utils.command_line import defaults_flag_in_config + logger = logging.getLogger("Slither") +def init_parser(parser: ArgumentParser, always_enable_codex: bool = False) -> None: + """ + Init the cli arg with codex features + + Args: + parser: + always_enable_codex (Optional(bool)): if true, --codex is not enabled + + Returns: + + """ + group_codex = parser.add_argument_group("Codex (https://beta.openai.com/docs/guides/code)") + + if not always_enable_codex: + group_codex.add_argument( + "--codex", + help="Enable codex (require an OpenAI API Key)", + action="store_true", + default=defaults_flag_in_config["codex"], + ) + + group_codex.add_argument( + "--codex-log", + help="Log codex queries (in crytic_export/codex/)", + action="store_true", + default=False, + ) + + group_codex.add_argument( + "--codex-contracts", + help="Comma separated list of contracts to submit to OpenAI Codex", + action="store", + default=defaults_flag_in_config["codex_contracts"], + ) + + group_codex.add_argument( + "--codex-model", + help="Name of the Codex model to use (affects pricing). Defaults to 'text-davinci-003'", + action="store", + default=defaults_flag_in_config["codex_model"], + ) + + group_codex.add_argument( + "--codex-temperature", + help="Temperature to use with Codex. Lower number indicates a more precise answer while higher numbers return more creative answers. Defaults to 0", + action="store", + default=defaults_flag_in_config["codex_temperature"], + ) + + group_codex.add_argument( + "--codex-max-tokens", + help="Maximum amount of tokens to use on the response. This number plus the size of the prompt can be no larger than the limit (4097 for text-davinci-003)", + action="store", + default=defaults_flag_in_config["codex_max_tokens"], + ) + + # TODO: investigate how to set the correct return type # So that the other modules can work with openai def openai_module(): # type: ignore From 74122a6bd68cdef07b178deb6b7624b51cfcb517 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 15 Dec 2022 18:19:04 -0600 Subject: [PATCH 08/61] fold binary expressions with constant operands for fuzzing guidance --- slither/core/expressions/literal.py | 9 ++++++- slither/printers/guidance/echidna.py | 6 +++++ .../visitors/expression/constants_folding.py | 25 ++++++++++++------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/slither/core/expressions/literal.py b/slither/core/expressions/literal.py index 87090b93f..0dc06cb20 100644 --- a/slither/core/expressions/literal.py +++ b/slither/core/expressions/literal.py @@ -20,6 +20,13 @@ class Literal(Expression): def value(self) -> Union[int, str]: return self._value + @property + def converted_value(self) -> int: + """Return the value of the literal, accounting for subdenomination e.g. ether""" + if self.subdenomination: + return convert_subdenomination(self._value, self.subdenomination) + return self._value + @property def type(self) -> "Type": return self._type @@ -30,7 +37,7 @@ class Literal(Expression): def __str__(self): if self.subdenomination: - return str(convert_subdenomination(self._value, self.subdenomination)) + return str(self.converted_value) if self.type in Int + Uint + Fixed + Ufixed + ["address"]: return str(convert_string_to_int(self._value)) diff --git a/slither/printers/guidance/echidna.py b/slither/printers/guidance/echidna.py index dbfa54121..45b3ab332 100644 --- a/slither/printers/guidance/echidna.py +++ b/slither/printers/guidance/echidna.py @@ -30,6 +30,7 @@ from slither.slithir.operations import ( ) from slither.slithir.operations.binary import Binary from slither.slithir.variables import Constant +from slither.visitors.expression.constants_folding import ConstantFolding def _get_name(f: Union[Function, Variable]) -> str: @@ -175,6 +176,11 @@ def _extract_constants_from_irs( # pylint: disable=too-many-branches,too-many-n all_cst_used_in_binary[str(ir.type)].append( ConstantValue(str(r.value), str(r.type)) ) + if isinstance(ir.variable_left, Constant) and isinstance(ir.variable_right, Constant): + if ir.lvalue: + type_ = ir.lvalue.type + cst = ConstantFolding(ir.expression, type_).result() + all_cst_used.append(ConstantValue(str(cst.value), str(type_))) if isinstance(ir, TypeConversion): if isinstance(ir.variable, Constant): all_cst_used.append(ConstantValue(str(ir.variable.value), str(ir.type))) diff --git a/slither/visitors/expression/constants_folding.py b/slither/visitors/expression/constants_folding.py index b324ed842..601eebcce 100644 --- a/slither/visitors/expression/constants_folding.py +++ b/slither/visitors/expression/constants_folding.py @@ -1,4 +1,11 @@ -from slither.core.expressions import BinaryOperationType, Literal, UnaryOperationType +from slither.core.expressions import ( + BinaryOperationType, + Literal, + UnaryOperationType, + Identifier, + BinaryOperation, + UnaryOperation, +) from slither.utils.integer_conversion import convert_string_to_fraction, convert_string_to_int from slither.visitors.expression.expression import ExpressionVisitor @@ -29,7 +36,7 @@ class ConstantFolding(ExpressionVisitor): def result(self): return Literal(int(get_val(self._expression)), self._type) - def _post_identifier(self, expression): + def _post_identifier(self, expression: Identifier): if not expression.value.is_constant: raise NotConstant expr = expression.value.expression @@ -37,9 +44,9 @@ class ConstantFolding(ExpressionVisitor): if not isinstance(expr, Literal): cf = ConstantFolding(expr, self._type) expr = cf.result() - set_val(expression, convert_string_to_int(expr.value)) + set_val(expression, convert_string_to_int(expr.converted_value)) - def _post_binary_operation(self, expression): + def _post_binary_operation(self, expression: BinaryOperation): left = get_val(expression.expression_left) right = get_val(expression.expression_right) if expression.type == BinaryOperationType.POWER: @@ -64,7 +71,7 @@ class ConstantFolding(ExpressionVisitor): else: raise NotConstant - def _post_unary_operation(self, expression): + def _post_unary_operation(self, expression: UnaryOperation): # Case of uint a = -7; uint[-a] arr; if expression.type == UnaryOperationType.MINUS_PRE: expr = expression.expression @@ -72,13 +79,13 @@ class ConstantFolding(ExpressionVisitor): cf = ConstantFolding(expr, self._type) expr = cf.result() assert isinstance(expr, Literal) - set_val(expression, -convert_string_to_fraction(expr.value)) + set_val(expression, -convert_string_to_fraction(expr.converted_value)) else: raise NotConstant - def _post_literal(self, expression): + def _post_literal(self, expression: Literal): try: - set_val(expression, convert_string_to_fraction(expression.value)) + set_val(expression, convert_string_to_fraction(expression.converted_value)) except ValueError as e: raise NotConstant from e @@ -115,7 +122,7 @@ class ConstantFolding(ExpressionVisitor): cf = ConstantFolding(expression.expressions[0], self._type) expr = cf.result() assert isinstance(expr, Literal) - set_val(expression, convert_string_to_fraction(expr.value)) + set_val(expression, convert_string_to_fraction(expr.converted_value)) return raise NotConstant From fcd7b68e27ec157fd65d643c774c2b088344163b Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 16 Dec 2022 08:48:59 -0600 Subject: [PATCH 09/61] support bitwise and logical ops in constant folding, add tests --- slither/core/expressions/literal.py | 3 ++ .../visitors/expression/constants_folding.py | 38 +++++++++++---- tests/constant_folding_binop.sol | 13 +++++ tests/test_constant_folding.py | 48 +++++++++++++++++++ 4 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 tests/constant_folding_binop.sol diff --git a/slither/core/expressions/literal.py b/slither/core/expressions/literal.py index 0dc06cb20..7999ccf02 100644 --- a/slither/core/expressions/literal.py +++ b/slither/core/expressions/literal.py @@ -4,6 +4,7 @@ from slither.core.expressions.expression import Expression from slither.core.solidity_types.elementary_type import Fixed, Int, Ufixed, Uint from slither.utils.arithmetic import convert_subdenomination from slither.utils.integer_conversion import convert_string_to_int +from fractions import Fraction if TYPE_CHECKING: from slither.core.solidity_types.type import Type @@ -12,6 +13,8 @@ if TYPE_CHECKING: class Literal(Expression): def __init__(self, value, custom_type, subdenomination=None): super().__init__() + if isinstance(value, Fraction): + value = int(value) self._value: Union[int, str] = value self._type = custom_type self._subdenomination: Optional[str] = subdenomination diff --git a/slither/visitors/expression/constants_folding.py b/slither/visitors/expression/constants_folding.py index 601eebcce..22691a086 100644 --- a/slither/visitors/expression/constants_folding.py +++ b/slither/visitors/expression/constants_folding.py @@ -34,7 +34,7 @@ class ConstantFolding(ExpressionVisitor): super().__init__(expression) def result(self): - return Literal(int(get_val(self._expression)), self._type) + return Literal(get_val(self._expression), self._type) def _post_identifier(self, expression: Identifier): if not expression.value.is_constant: @@ -60,14 +60,33 @@ class ConstantFolding(ExpressionVisitor): elif expression.type == BinaryOperationType.ADDITION: set_val(expression, left + right) elif expression.type == BinaryOperationType.SUBTRACTION: - if (left - right) < 0: - # Could trigger underflow - raise NotConstant set_val(expression, left - right) elif expression.type == BinaryOperationType.LEFT_SHIFT: set_val(expression, left << right) elif expression.type == BinaryOperationType.RIGHT_SHIFT: set_val(expression, left >> right) + elif expression.type == BinaryOperationType.AND: + set_val(expression, int(left) & int(right)) + elif expression.type == BinaryOperationType.CARET: + set_val(expression, int(left) ^ int(right)) + elif expression.type == BinaryOperationType.OR: + set_val(expression, int(left) | int(right)) + elif expression.type == BinaryOperationType.LESS: + set_val(expression, int(left) < int(right)) + elif expression.type == BinaryOperationType.LESS_EQUAL: + set_val(expression, int(left) <= int(right)) + elif expression.type == BinaryOperationType.GREATER: + set_val(expression, int(left) > int(right)) + elif expression.type == BinaryOperationType.GREATER_EQUAL: + set_val(expression, int(left) >= int(right)) + elif expression.type == BinaryOperationType.EQUAL: + set_val(expression, int(left) == int(right)) + elif expression.type == BinaryOperationType.NOT_EQUAL: + set_val(expression, int(left) != int(right)) + elif expression.type == BinaryOperationType.ANDAND: + set_val(expression, left == "true" and right == "true") + elif expression.type == BinaryOperationType.OROR: + set_val(expression, left == "true" or right == "true") else: raise NotConstant @@ -84,10 +103,13 @@ class ConstantFolding(ExpressionVisitor): raise NotConstant def _post_literal(self, expression: Literal): - try: - set_val(expression, convert_string_to_fraction(expression.converted_value)) - except ValueError as e: - raise NotConstant from e + if expression.converted_value in ["true", "false"]: + set_val(expression, expression.converted_value) + else: + try: + set_val(expression, convert_string_to_fraction(expression.converted_value)) + except ValueError as e: + raise NotConstant from e def _post_assignement_operation(self, expression): raise NotConstant diff --git a/tests/constant_folding_binop.sol b/tests/constant_folding_binop.sol new file mode 100644 index 000000000..baab7147f --- /dev/null +++ b/tests/constant_folding_binop.sol @@ -0,0 +1,13 @@ +contract BinOp { + uint a = 1 & 2; + uint b = 1 ^ 2; + uint c = 1 | 2; + bool d = 2 < 1; + bool e = 1 > 2; + bool f = 1 <= 2; + bool g = 1 >= 2; + bool h = 1 == 2; + bool i = 1 != 2; + bool j = true && false; + bool k = true || false; +} \ No newline at end of file diff --git a/tests/test_constant_folding.py b/tests/test_constant_folding.py index efc3119a8..459e2e3c9 100644 --- a/tests/test_constant_folding.py +++ b/tests/test_constant_folding.py @@ -43,3 +43,51 @@ def test_constant_folding_rational(): variable_g = contract.get_state_variable_from_name("g") assert str(variable_g.type) == "int64" assert str(ConstantFolding(variable_g.expression, "int64").result()) == "-7" + +def test_constant_folding_binary_expressions(): + sl = Slither("./tests/constant_folding_binop.sol") + contract = sl.get_contract_from_name("BinOp")[0] + + variable_a = contract.get_state_variable_from_name("a") + assert str(variable_a.type) == "uint256" + assert str(ConstantFolding(variable_a.expression, "uint256").result()) == "0" + + variable_b = contract.get_state_variable_from_name("b") + assert str(variable_b.type) == "uint256" + assert str(ConstantFolding(variable_b.expression, "uint256").result()) == "3" + + variable_c = contract.get_state_variable_from_name("c") + assert str(variable_c.type) == "uint256" + assert str(ConstantFolding(variable_c.expression, "uint256").result()) == "3" + + variable_d = contract.get_state_variable_from_name("d") + assert str(variable_d.type) == "bool" + assert str(ConstantFolding(variable_d.expression, "bool").result()) == "False" + + variable_e = contract.get_state_variable_from_name("e") + assert str(variable_e.type) == "bool" + assert str(ConstantFolding(variable_e.expression, "bool").result()) == "False" + + variable_f = contract.get_state_variable_from_name("f") + assert str(variable_f.type) == "bool" + assert str(ConstantFolding(variable_f.expression, "bool").result()) == "True" + + variable_g = contract.get_state_variable_from_name("g") + assert str(variable_g.type) == "bool" + assert str(ConstantFolding(variable_g.expression, "bool").result()) == "False" + + variable_h = contract.get_state_variable_from_name("h") + assert str(variable_h.type) == "bool" + assert str(ConstantFolding(variable_h.expression, "bool").result()) == "False" + + variable_i = contract.get_state_variable_from_name("i") + assert str(variable_i.type) == "bool" + assert str(ConstantFolding(variable_i.expression, "bool").result()) == "True" + + variable_j = contract.get_state_variable_from_name("j") + assert str(variable_j.type) == "bool" + assert str(ConstantFolding(variable_j.expression, "bool").result()) == "False" + + variable_k = contract.get_state_variable_from_name("k") + assert str(variable_k.type) == "bool" + assert str(ConstantFolding(variable_k.expression, "bool").result()) == "True" \ No newline at end of file From 887002407a90f596c61ee27357d44f3e0c8d1f6a Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 16 Dec 2022 08:54:20 -0600 Subject: [PATCH 10/61] convert to int for operations not supported by Fraction --- slither/visitors/expression/constants_folding.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/slither/visitors/expression/constants_folding.py b/slither/visitors/expression/constants_folding.py index 22691a086..e4cd09eb8 100644 --- a/slither/visitors/expression/constants_folding.py +++ b/slither/visitors/expression/constants_folding.py @@ -61,10 +61,11 @@ class ConstantFolding(ExpressionVisitor): set_val(expression, left + right) elif expression.type == BinaryOperationType.SUBTRACTION: set_val(expression, left - right) + # Convert to int for operations not supported by Fraction elif expression.type == BinaryOperationType.LEFT_SHIFT: - set_val(expression, left << right) + set_val(expression, int(left) << int(right)) elif expression.type == BinaryOperationType.RIGHT_SHIFT: - set_val(expression, left >> right) + set_val(expression, int(left) >> int(right)) elif expression.type == BinaryOperationType.AND: set_val(expression, int(left) & int(right)) elif expression.type == BinaryOperationType.CARET: @@ -83,6 +84,7 @@ class ConstantFolding(ExpressionVisitor): set_val(expression, int(left) == int(right)) elif expression.type == BinaryOperationType.NOT_EQUAL: set_val(expression, int(left) != int(right)) + # Convert boolean literals from string to bool elif expression.type == BinaryOperationType.ANDAND: set_val(expression, left == "true" and right == "true") elif expression.type == BinaryOperationType.OROR: From 9d811e4d9ea094b73e52200fd7566bba1734210e Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 16 Dec 2022 09:04:55 -0600 Subject: [PATCH 11/61] format tests --- tests/test_constant_folding.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_constant_folding.py b/tests/test_constant_folding.py index 459e2e3c9..32ecd0bbc 100644 --- a/tests/test_constant_folding.py +++ b/tests/test_constant_folding.py @@ -44,6 +44,7 @@ def test_constant_folding_rational(): assert str(variable_g.type) == "int64" assert str(ConstantFolding(variable_g.expression, "int64").result()) == "-7" + def test_constant_folding_binary_expressions(): sl = Slither("./tests/constant_folding_binop.sol") contract = sl.get_contract_from_name("BinOp")[0] @@ -85,9 +86,9 @@ def test_constant_folding_binary_expressions(): assert str(ConstantFolding(variable_i.expression, "bool").result()) == "True" variable_j = contract.get_state_variable_from_name("j") - assert str(variable_j.type) == "bool" + assert str(variable_j.type) == "bool" assert str(ConstantFolding(variable_j.expression, "bool").result()) == "False" variable_k = contract.get_state_variable_from_name("k") assert str(variable_k.type) == "bool" - assert str(ConstantFolding(variable_k.expression, "bool").result()) == "True" \ No newline at end of file + assert str(ConstantFolding(variable_k.expression, "bool").result()) == "True" From 43aba2a1df25c8d8e0acc3d04f9150316a2f6a1f Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 16 Dec 2022 09:30:41 -0600 Subject: [PATCH 12/61] make pylint happy --- slither/core/expressions/literal.py | 2 +- slither/visitors/expression/constants_folding.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/slither/core/expressions/literal.py b/slither/core/expressions/literal.py index 7999ccf02..1b3d1f7fc 100644 --- a/slither/core/expressions/literal.py +++ b/slither/core/expressions/literal.py @@ -1,10 +1,10 @@ from typing import Optional, Union, TYPE_CHECKING +from fractions import Fraction from slither.core.expressions.expression import Expression from slither.core.solidity_types.elementary_type import Fixed, Int, Ufixed, Uint from slither.utils.arithmetic import convert_subdenomination from slither.utils.integer_conversion import convert_string_to_int -from fractions import Fraction if TYPE_CHECKING: from slither.core.solidity_types.type import Type diff --git a/slither/visitors/expression/constants_folding.py b/slither/visitors/expression/constants_folding.py index e4cd09eb8..9f74c7543 100644 --- a/slither/visitors/expression/constants_folding.py +++ b/slither/visitors/expression/constants_folding.py @@ -46,6 +46,7 @@ class ConstantFolding(ExpressionVisitor): expr = cf.result() set_val(expression, convert_string_to_int(expr.converted_value)) + # pylint: disable=too-many-branches def _post_binary_operation(self, expression: BinaryOperation): left = get_val(expression.expression_left) right = get_val(expression.expression_right) From e065fbe8f48d03ab82b29caafe0467ef14557c4a Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 16 Dec 2022 13:07:22 -0600 Subject: [PATCH 13/61] emulate wrapped arithmetic behavior --- slither/core/expressions/literal.py | 3 +++ slither/visitors/expression/constants_folding.py | 6 +++++- tests/constant_folding_binop.sol | 1 + tests/test_constant_folding.py | 7 +++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/slither/core/expressions/literal.py b/slither/core/expressions/literal.py index 1b3d1f7fc..30b35c11a 100644 --- a/slither/core/expressions/literal.py +++ b/slither/core/expressions/literal.py @@ -15,6 +15,9 @@ class Literal(Expression): super().__init__() if isinstance(value, Fraction): value = int(value) + # emulate 256-bit wrapping + if str(custom_type).startswith("uint"): + value = value & (2**256 - 1) self._value: Union[int, str] = value self._type = custom_type self._subdenomination: Optional[str] = subdenomination diff --git a/slither/visitors/expression/constants_folding.py b/slither/visitors/expression/constants_folding.py index 9f74c7543..3e934772b 100644 --- a/slither/visitors/expression/constants_folding.py +++ b/slither/visitors/expression/constants_folding.py @@ -152,4 +152,8 @@ class ConstantFolding(ExpressionVisitor): raise NotConstant def _post_type_conversion(self, expression): - raise NotConstant + cf = ConstantFolding(expression.expression, self._type) + expr = cf.result() + assert isinstance(expr, Literal) + set_val(expression, convert_string_to_fraction(expr.converted_value)) + return diff --git a/tests/constant_folding_binop.sol b/tests/constant_folding_binop.sol index baab7147f..923418ce7 100644 --- a/tests/constant_folding_binop.sol +++ b/tests/constant_folding_binop.sol @@ -10,4 +10,5 @@ contract BinOp { bool i = 1 != 2; bool j = true && false; bool k = true || false; + uint l = uint(1) - uint(2); } \ No newline at end of file diff --git a/tests/test_constant_folding.py b/tests/test_constant_folding.py index 32ecd0bbc..21517ddc4 100644 --- a/tests/test_constant_folding.py +++ b/tests/test_constant_folding.py @@ -92,3 +92,10 @@ def test_constant_folding_binary_expressions(): variable_k = contract.get_state_variable_from_name("k") assert str(variable_k.type) == "bool" assert str(ConstantFolding(variable_k.expression, "bool").result()) == "True" + + variable_l = contract.get_state_variable_from_name("l") + assert str(variable_l.type) == "uint256" + assert ( + str(ConstantFolding(variable_l.expression, "uint256").result()) + == "115792089237316195423570985008687907853269984665640564039457584007913129639935" + ) From a59f4f12175e984b3bfc9020dda01f943469ddc9 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 16 Dec 2022 13:19:07 -0600 Subject: [PATCH 14/61] move folding logic out of Literal class --- slither/core/expressions/literal.py | 14 +++++--------- slither/visitors/expression/constants_folding.py | 9 ++++++++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/slither/core/expressions/literal.py b/slither/core/expressions/literal.py index 30b35c11a..328ec9674 100644 --- a/slither/core/expressions/literal.py +++ b/slither/core/expressions/literal.py @@ -1,5 +1,4 @@ from typing import Optional, Union, TYPE_CHECKING -from fractions import Fraction from slither.core.expressions.expression import Expression from slither.core.solidity_types.elementary_type import Fixed, Int, Ufixed, Uint @@ -11,16 +10,13 @@ if TYPE_CHECKING: class Literal(Expression): - def __init__(self, value, custom_type, subdenomination=None): + def __init__( + self, value: Union[int, str], custom_type: "Type", subdenomination: Optional[str] = None + ): super().__init__() - if isinstance(value, Fraction): - value = int(value) - # emulate 256-bit wrapping - if str(custom_type).startswith("uint"): - value = value & (2**256 - 1) - self._value: Union[int, str] = value + self._value = value self._type = custom_type - self._subdenomination: Optional[str] = subdenomination + self._subdenomination = subdenomination @property def value(self) -> Union[int, str]: diff --git a/slither/visitors/expression/constants_folding.py b/slither/visitors/expression/constants_folding.py index 3e934772b..547cfe50c 100644 --- a/slither/visitors/expression/constants_folding.py +++ b/slither/visitors/expression/constants_folding.py @@ -1,3 +1,4 @@ +from fractions import Fraction from slither.core.expressions import ( BinaryOperationType, Literal, @@ -34,7 +35,13 @@ class ConstantFolding(ExpressionVisitor): super().__init__(expression) def result(self): - return Literal(get_val(self._expression), self._type) + value = get_val(self._expression) + if isinstance(value, Fraction): + value = int(value) + # emulate 256-bit wrapping + if str(self._type).startswith("uint"): + value = value & (2**256 - 1) + return Literal(value, self._type) def _post_identifier(self, expression: Identifier): if not expression.value.is_constant: From 2684717087b37a097e6e54bf2388c8183f3318a3 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Tue, 20 Dec 2022 09:26:11 -0600 Subject: [PATCH 15/61] remove unnecessary return --- slither/visitors/expression/constants_folding.py | 1 - 1 file changed, 1 deletion(-) diff --git a/slither/visitors/expression/constants_folding.py b/slither/visitors/expression/constants_folding.py index 547cfe50c..797d1f46e 100644 --- a/slither/visitors/expression/constants_folding.py +++ b/slither/visitors/expression/constants_folding.py @@ -163,4 +163,3 @@ class ConstantFolding(ExpressionVisitor): expr = cf.result() assert isinstance(expr, Literal) set_val(expression, convert_string_to_fraction(expr.converted_value)) - return From feafd9bbc65e57e2b4c08518de2b9b89870caf5b Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Tue, 3 Jan 2023 14:20:21 +0100 Subject: [PATCH 16/61] Improvements --- slither/tools/documentation/__main__.py | 158 ++++++++++++++---------- 1 file changed, 93 insertions(+), 65 deletions(-) diff --git a/slither/tools/documentation/__main__.py b/slither/tools/documentation/__main__.py index ea45ed8e1..1f2280de7 100644 --- a/slither/tools/documentation/__main__.py +++ b/slither/tools/documentation/__main__.py @@ -36,7 +36,12 @@ def parse_args() -> argparse.Namespace: default=False, ) - parser.add_argument("--retry", help="Retry failed query (default 1). Each retry increases the temperature by 0.1", action="store", default=1) + parser.add_argument( + "--retry", + help="Retry failed query (default 1). Each retry increases the temperature by 0.1", + action="store", + default=1, + ) # Add default arguments from crytic-compile cryticparser.init(parser) @@ -122,7 +127,75 @@ def _handle_codex( return None -# pylint: disable=too-many-locals +# pylint: disable=too-many-locals,too-many-arguments +def _handle_function( + function: Function, + overwrite: bool, + all_patches: Dict, + logging_file: Optional[str], + slither: Slither, + retry: int, + force: bool, +) -> bool: + if ( + function.source_mapping.is_dependency + or function.has_documentation + or function.is_constructor_variables + ): + return overwrite + prompt = "Create a natpsec documentation for this solidity code with only notice and dev.\n" + src_mapping = function.source_mapping + content = function.compilation_unit.core.source_code[src_mapping.filename.absolute] + start = src_mapping.start + end = src_mapping.start + src_mapping.length + prompt += content[start:end] + + use_tab = _use_tab(content[start - 1]) + if use_tab is None and src_mapping.starting_column > 1: + logger.info(f"Non standard space indentation found {content[start - 1:end]}") + if overwrite: + logger.info("Disable overwrite to avoid mistakes") + overwrite = False + + openai = codex.openai_module() # type: ignore + if openai is None: + raise ImportError + + if logging_file: + codex.log_codex(logging_file, "Q: " + prompt) + + tentative = 0 + answer_processed: Optional[str] = None + while tentative < retry: + tentative += 1 + + answer = openai.Completion.create( # type: ignore + prompt=prompt, + model=slither.codex_model, + temperature=min(slither.codex_temperature + tentative * 0.1, 1), + max_tokens=slither.codex_max_tokens, + ) + + if logging_file: + codex.log_codex(logging_file, "A: " + str(answer)) + + answer_processed = _handle_codex(answer, src_mapping.starting_column, use_tab, force) + if answer_processed: + break + + logger.info( + f"Codex could not generate a well formatted answer for {function.canonical_name}" + ) + logger.info(answer) + + if not answer_processed: + return overwrite + + create_patch(all_patches, src_mapping.filename.absolute, start, start, "", answer_processed) + + return overwrite + + def _handle_compilation_unit( slither: Slither, compilation_unit: SlitherCompilationUnit, @@ -130,8 +203,11 @@ def _handle_compilation_unit( force: bool, retry: int, ) -> None: - - logging_file = str(uuid.uuid4()) + logging_file: Optional[str] + if slither.codex_log: + logging_file = str(uuid.uuid4()) + else: + logging_file = None for scope in compilation_unit.scopes.values(): @@ -153,63 +229,8 @@ def _handle_compilation_unit( all_patches: Dict = {} for function in functions_target: - - if function.source_mapping.is_dependency or function.has_documentation or function.is_constructor_variables: - continue - prompt = ( - "Create a natpsec documentation for this solidity code with only notice and dev.\n" - ) - src_mapping = function.source_mapping - content = compilation_unit.core.source_code[src_mapping.filename.absolute] - start = src_mapping.start - end = src_mapping.start + src_mapping.length - prompt += content[start:end] - - use_tab = _use_tab(content[start - 1]) - if use_tab is None and src_mapping.starting_column > 1: - logger.info(f"Non standard space indentation found {content[start-1:end]}") - if overwrite: - logger.info("Disable overwrite to avoid mistakes") - overwrite = False - - openai = codex.openai_module() # type: ignore - if openai is None: - return - - if slither.codex_log: - codex.log_codex(logging_file, "Q: " + prompt) - - tentative = 0 - answer_processed: Optional[str] = None - while tentative < retry: - tentative += 1 - - answer = openai.Completion.create( # type: ignore - prompt=prompt, - model=slither.codex_model, - temperature=min(slither.codex_temperature + tentative*0.1, 1), - max_tokens=slither.codex_max_tokens, - ) - - if slither.codex_log: - codex.log_codex(logging_file, "A: " + str(answer)) - - answer_processed = _handle_codex( - answer, src_mapping.starting_column, use_tab, force - ) - if answer_processed: - break - - logger.info( - f"Codex could not generate a well formatted answer for {function.canonical_name}" - ) - logger.info(answer) - - if not answer_processed: - continue - - create_patch( - all_patches, src_mapping.filename.absolute, start, start, "", answer_processed + overwrite = _handle_function( + function, overwrite, all_patches, logging_file, slither, retry, force ) # all_patches["patches"] should have only 1 file @@ -242,10 +263,17 @@ def main() -> None: logger.info("Be aware of OpenAI ToS: https://openai.com/api/policies/terms/") slither = Slither(args.project, **vars(args)) - for compilation_unit in slither.compilation_units: - _handle_compilation_unit( - slither, compilation_unit, args.overwrite, args.force_answer_parsing, int(args.retry) - ) + try: + for compilation_unit in slither.compilation_units: + _handle_compilation_unit( + slither, + compilation_unit, + args.overwrite, + args.force_answer_parsing, + int(args.retry), + ) + except ImportError: + pass if __name__ == "__main__": From 04949548e9b05535a76f740e0099d4667fee2dec Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Tue, 3 Jan 2023 16:02:54 +0100 Subject: [PATCH 17/61] Minor --- slither/tools/documentation/README.md | 6 +++--- slither/tools/documentation/__main__.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/slither/tools/documentation/README.md b/slither/tools/documentation/README.md index 2ed90692c..5e70b3a49 100644 --- a/slither/tools/documentation/README.md +++ b/slither/tools/documentation/README.md @@ -1,6 +1,6 @@ -# Demo +# slither-documentation -This directory contains an example of Slither utility. +`slither-documentation` uses [codex](https://beta.openai.com) to generate natspec documenation. -See the [utility documentation](https://github.com/crytic/slither/wiki/Adding-a-new-utility) +This tool is experimental. See https://github.com/montyly/solmate/pull/1 for an example of usage. diff --git a/slither/tools/documentation/__main__.py b/slither/tools/documentation/__main__.py index 1f2280de7..8e545fb09 100644 --- a/slither/tools/documentation/__main__.py +++ b/slither/tools/documentation/__main__.py @@ -211,7 +211,7 @@ def _handle_compilation_unit( for scope in compilation_unit.scopes.values(): - # TODO remove hardcoded filtering + # Dont send tests file if ( ".t.sol" in scope.filename.absolute or "mock" in scope.filename.absolute.lower() From 656f2145ae7fc268a54da5098bbed0179cab5aff Mon Sep 17 00:00:00 2001 From: pavan-nambi Date: Tue, 3 Jan 2023 21:02:49 +0530 Subject: [PATCH 18/61] chore(CI):removing solc-select install all lines --- .github/workflows/IR.yml | 1 - .github/workflows/ci.yml | 1 - .github/workflows/detectors.yml | 1 - .github/workflows/features.yml | 1 - 4 files changed, 4 deletions(-) diff --git a/.github/workflows/IR.yml b/.github/workflows/IR.yml index 434cef75b..b1d11478f 100644 --- a/.github/workflows/IR.yml +++ b/.github/workflows/IR.yml @@ -34,7 +34,6 @@ jobs: - name: Install dependencies run: | pip install ".[dev]" - solc-select install all solc-select use 0.8.11 - name: Test with pytest diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ae5326a8..7338d248c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,6 @@ jobs: - name: Install dependencies run: | pip install ".[dev]" - solc-select install all solc-select use 0.5.1 pip install typing_extensions==4.1.1 pip install importlib_metadata==4.8.3 diff --git a/.github/workflows/detectors.yml b/.github/workflows/detectors.yml index 8f3b45d15..c85e8d26b 100644 --- a/.github/workflows/detectors.yml +++ b/.github/workflows/detectors.yml @@ -35,7 +35,6 @@ jobs: run: | pip install ".[dev]" - solc-select install all solc-select use 0.7.3 - name: Test with pytest run: | diff --git a/.github/workflows/features.yml b/.github/workflows/features.yml index 49db14793..14150388a 100644 --- a/.github/workflows/features.yml +++ b/.github/workflows/features.yml @@ -35,7 +35,6 @@ jobs: run: | pip install ".[dev]" - solc-select install all solc-select use 0.8.0 cd tests/test_node_modules/ From df896e80f2814befab085a34072374dc6ebe9ebf Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Tue, 3 Jan 2023 09:40:26 -0600 Subject: [PATCH 19/61] better error handling of malformed symbol alias AST node for solc <0.6.0 --- .../slither_compilation_unit_solc.py | 27 +++++++++++-------- .../import_aliases_issue_1319/import.sol | 1 + .../import_aliases_issue_1319/test.sol | 9 +++++++ .../import_aliases_issue_1319/test_fail.sol | 9 +++++++ 4 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 tests/ast-parsing/complex_imports/import_aliases_issue_1319/import.sol create mode 100644 tests/ast-parsing/complex_imports/import_aliases_issue_1319/test.sol create mode 100644 tests/ast-parsing/complex_imports/import_aliases_issue_1319/test_fail.sol diff --git a/slither/solc_parsing/slither_compilation_unit_solc.py b/slither/solc_parsing/slither_compilation_unit_solc.py index d12bda1b4..5c93d5f1d 100644 --- a/slither/solc_parsing/slither_compilation_unit_solc.py +++ b/slither/solc_parsing/slither_compilation_unit_solc.py @@ -45,16 +45,22 @@ def _handle_import_aliases( """ for symbol_alias in symbol_aliases: - if ( - "foreign" in symbol_alias - and "name" in symbol_alias["foreign"] - and "local" in symbol_alias - ): - original_name = symbol_alias["foreign"]["name"] - local_name = symbol_alias["local"] - import_directive.renaming[local_name] = original_name - # Assuming that two imports cannot collide in renaming - scope.renaming[local_name] = original_name + if "foreign" in symbol_alias and "local" in symbol_alias: + if isinstance(symbol_alias["foreign"], dict) and "name" in symbol_alias["foreign"]: + + original_name = symbol_alias["foreign"]["name"] + local_name = symbol_alias["local"] + import_directive.renaming[local_name] = original_name + # Assuming that two imports cannot collide in renaming + scope.renaming[local_name] = original_name + + # This path should only be hit for the malformed AST of solc 0.5.12 where + # the foreign identifier cannot be found but is required to resolve the alias. + # see https://github.com/crytic/slither/issues/1319 + if symbol_alias["local"]: + raise SlitherException( + "Cannot resolve local alias for import directive due to malformed AST. Please upgrade to solc 0.6.0 or higher." + ) class SlitherCompilationUnitSolc: @@ -389,7 +395,6 @@ Please rename it, this name is reserved for Slither's internals""" ) self._contracts_by_id[contract.id] = contract self._compilation_unit.contracts.append(contract) - # Update of the inheritance for contract_parser in self._underlying_contract_to_parser.values(): # remove the first elem in linearizedBaseContracts as it is the contract itself diff --git a/tests/ast-parsing/complex_imports/import_aliases_issue_1319/import.sol b/tests/ast-parsing/complex_imports/import_aliases_issue_1319/import.sol new file mode 100644 index 000000000..7cfff4bfa --- /dev/null +++ b/tests/ast-parsing/complex_imports/import_aliases_issue_1319/import.sol @@ -0,0 +1 @@ +contract A {} \ No newline at end of file diff --git a/tests/ast-parsing/complex_imports/import_aliases_issue_1319/test.sol b/tests/ast-parsing/complex_imports/import_aliases_issue_1319/test.sol new file mode 100644 index 000000000..7c5bf1eee --- /dev/null +++ b/tests/ast-parsing/complex_imports/import_aliases_issue_1319/test.sol @@ -0,0 +1,9 @@ +pragma solidity 0.5.12; + +import {A} from "./import.sol"; + +contract Z is A { + function test() public pure returns (uint) { + return 1; + } +} \ No newline at end of file diff --git a/tests/ast-parsing/complex_imports/import_aliases_issue_1319/test_fail.sol b/tests/ast-parsing/complex_imports/import_aliases_issue_1319/test_fail.sol new file mode 100644 index 000000000..eb2ab8af0 --- /dev/null +++ b/tests/ast-parsing/complex_imports/import_aliases_issue_1319/test_fail.sol @@ -0,0 +1,9 @@ +pragma solidity 0.5.12; + +import {A as X, A as Y} from "./import.sol"; + +contract Z is X { + function test() public pure returns (uint) { + return 1; + } +} \ No newline at end of file From f92cb37a400f9ddf72f4d48ebfc5a786de5236fc Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Tue, 3 Jan 2023 09:49:50 -0600 Subject: [PATCH 20/61] only check for local alias if foreign isn't dict --- slither/solc_parsing/slither_compilation_unit_solc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slither/solc_parsing/slither_compilation_unit_solc.py b/slither/solc_parsing/slither_compilation_unit_solc.py index 5c93d5f1d..05dc4113b 100644 --- a/slither/solc_parsing/slither_compilation_unit_solc.py +++ b/slither/solc_parsing/slither_compilation_unit_solc.py @@ -57,7 +57,7 @@ def _handle_import_aliases( # This path should only be hit for the malformed AST of solc 0.5.12 where # the foreign identifier cannot be found but is required to resolve the alias. # see https://github.com/crytic/slither/issues/1319 - if symbol_alias["local"]: + elif symbol_alias["local"]: raise SlitherException( "Cannot resolve local alias for import directive due to malformed AST. Please upgrade to solc 0.6.0 or higher." ) @@ -395,6 +395,7 @@ Please rename it, this name is reserved for Slither's internals""" ) self._contracts_by_id[contract.id] = contract self._compilation_unit.contracts.append(contract) + # Update of the inheritance for contract_parser in self._underlying_contract_to_parser.values(): # remove the first elem in linearizedBaseContracts as it is the contract itself From 1b6acfa9a40f712d6d2cda44496c13c858968370 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Tue, 3 Jan 2023 09:50:30 -0600 Subject: [PATCH 21/61] format --- slither/solc_parsing/slither_compilation_unit_solc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slither/solc_parsing/slither_compilation_unit_solc.py b/slither/solc_parsing/slither_compilation_unit_solc.py index 05dc4113b..930f60ff9 100644 --- a/slither/solc_parsing/slither_compilation_unit_solc.py +++ b/slither/solc_parsing/slither_compilation_unit_solc.py @@ -395,7 +395,7 @@ Please rename it, this name is reserved for Slither's internals""" ) self._contracts_by_id[contract.id] = contract self._compilation_unit.contracts.append(contract) - + # Update of the inheritance for contract_parser in self._underlying_contract_to_parser.values(): # remove the first elem in linearizedBaseContracts as it is the contract itself From 3e67fff11768e6c39f8f82cc65ef1c0f883723ff Mon Sep 17 00:00:00 2001 From: pavan-nambi Date: Tue, 3 Jan 2023 21:21:03 +0530 Subject: [PATCH 22/61] update(#1546) --- .github/workflows/IR.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/detectors.yml | 2 +- .github/workflows/features.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/IR.yml b/.github/workflows/IR.yml index b1d11478f..29e6ba2a0 100644 --- a/.github/workflows/IR.yml +++ b/.github/workflows/IR.yml @@ -34,7 +34,7 @@ jobs: - name: Install dependencies run: | pip install ".[dev]" - solc-select use 0.8.11 + solc-select use 0.8.11--always-install - name: Test with pytest run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7338d248c..ff038574a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install dependencies run: | pip install ".[dev]" - solc-select use 0.5.1 + solc-select use 0.5.1--always-install pip install typing_extensions==4.1.1 pip install importlib_metadata==4.8.3 diff --git a/.github/workflows/detectors.yml b/.github/workflows/detectors.yml index c85e8d26b..ff568a046 100644 --- a/.github/workflows/detectors.yml +++ b/.github/workflows/detectors.yml @@ -35,7 +35,7 @@ jobs: run: | pip install ".[dev]" - solc-select use 0.7.3 + solc-select use 0.7.3--always-install - name: Test with pytest run: | pytest tests/test_detectors.py diff --git a/.github/workflows/features.yml b/.github/workflows/features.yml index 14150388a..dada1e141 100644 --- a/.github/workflows/features.yml +++ b/.github/workflows/features.yml @@ -35,7 +35,7 @@ jobs: run: | pip install ".[dev]" - solc-select use 0.8.0 + solc-select use 0.8.0--always-install cd tests/test_node_modules/ npm install hardhat From 41806075a6d258fdfedae91f8263bf27c6231aa7 Mon Sep 17 00:00:00 2001 From: pavan-nambi Date: Tue, 3 Jan 2023 21:42:30 +0530 Subject: [PATCH 23/61] update2(#1546) --- .github/workflows/IR.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/detectors.yml | 2 +- .github/workflows/features.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/IR.yml b/.github/workflows/IR.yml index 29e6ba2a0..c5187da65 100644 --- a/.github/workflows/IR.yml +++ b/.github/workflows/IR.yml @@ -34,7 +34,7 @@ jobs: - name: Install dependencies run: | pip install ".[dev]" - solc-select use 0.8.11--always-install + solc-select use 0.8.11 --always-install - name: Test with pytest run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff038574a..3378cd420 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install dependencies run: | pip install ".[dev]" - solc-select use 0.5.1--always-install + solc-select use 0.5.1 --always-install pip install typing_extensions==4.1.1 pip install importlib_metadata==4.8.3 diff --git a/.github/workflows/detectors.yml b/.github/workflows/detectors.yml index ff568a046..15aa8a5dd 100644 --- a/.github/workflows/detectors.yml +++ b/.github/workflows/detectors.yml @@ -35,7 +35,7 @@ jobs: run: | pip install ".[dev]" - solc-select use 0.7.3--always-install + solc-select use 0.7.3 --always-install - name: Test with pytest run: | pytest tests/test_detectors.py diff --git a/.github/workflows/features.yml b/.github/workflows/features.yml index dada1e141..5007fd7bf 100644 --- a/.github/workflows/features.yml +++ b/.github/workflows/features.yml @@ -35,7 +35,7 @@ jobs: run: | pip install ".[dev]" - solc-select use 0.8.0--always-install + solc-select use 0.8.0 --always-install cd tests/test_node_modules/ npm install hardhat From bd3e4504b8233bf2cfda0e3daca07d71a445b1e9 Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Wed, 4 Jan 2023 12:13:33 +0100 Subject: [PATCH 24/61] Fix markdown@ --- slither/tools/documentation/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/slither/tools/documentation/README.md b/slither/tools/documentation/README.md index 5e70b3a49..b4b3e6a76 100644 --- a/slither/tools/documentation/README.md +++ b/slither/tools/documentation/README.md @@ -2,5 +2,4 @@ `slither-documentation` uses [codex](https://beta.openai.com) to generate natspec documenation. -This tool is experimental. See https://github.com/montyly/solmate/pull/1 for an example of usage. - +This tool is experimental. See [solmate documentation](https://github.com/montyly/solmate/pull/1) for an example of usage. From 23d77e23fd0b7d89504d0b6ff291a0b50f370101 Mon Sep 17 00:00:00 2001 From: pavan-nambi Date: Wed, 4 Jan 2023 19:07:55 +0530 Subject: [PATCH 25/61] refractor(ver-in-path_filterin) --- scripts/ci_test_path_filtering.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci_test_path_filtering.sh b/scripts/ci_test_path_filtering.sh index fb2a18842..838ecfa1d 100644 --- a/scripts/ci_test_path_filtering.sh +++ b/scripts/ci_test_path_filtering.sh @@ -2,7 +2,7 @@ ### Test path filtering across POSIX and Windows -solc-select use 0.8.0 +solc-select use 0.5.0 slither "tests/test_path_filtering/test_path_filtering.sol" --config "tests/test_path_filtering/slither.config.json" > "output.txt" 2>&1 if ! grep -q "0 result(s) found" "output.txt" From 8388597e77708e200ba3916db6feb668ad823212 Mon Sep 17 00:00:00 2001 From: pavan-nambi Date: Wed, 4 Jan 2023 19:30:26 +0530 Subject: [PATCH 26/61] Revert "refractor(ver-in-path_filterin)" This reverts commit 23d77e23fd0b7d89504d0b6ff291a0b50f370101. --- scripts/ci_test_path_filtering.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci_test_path_filtering.sh b/scripts/ci_test_path_filtering.sh index 838ecfa1d..fb2a18842 100644 --- a/scripts/ci_test_path_filtering.sh +++ b/scripts/ci_test_path_filtering.sh @@ -2,7 +2,7 @@ ### Test path filtering across POSIX and Windows -solc-select use 0.5.0 +solc-select use 0.8.0 slither "tests/test_path_filtering/test_path_filtering.sol" --config "tests/test_path_filtering/slither.config.json" > "output.txt" 2>&1 if ! grep -q "0 result(s) found" "output.txt" From 9015e739c2e60b5c4df8889b7fb13970ff77e2c1 Mon Sep 17 00:00:00 2001 From: pavan-nambi Date: Wed, 4 Jan 2023 20:05:16 +0530 Subject: [PATCH 27/61] update(adding-more-installations) --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3378cd420..73cba44b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,6 +55,8 @@ jobs: - name: Install dependencies run: | pip install ".[dev]" + solc-select use 0.4.25 --always-install + solc-select use 0.8.0 --always-install solc-select use 0.5.1 --always-install pip install typing_extensions==4.1.1 pip install importlib_metadata==4.8.3 From 020d8638dab92b6fd952e988296e4d6b2478fdd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 17:08:49 -0300 Subject: [PATCH 28/61] slither-doctor: remove LegacyVersion import, add `packaging` dependency This was used just for typing, and it was removed in a recent `packaging` version, so remove the LegacyVersion import. Also declare the missing `packaging` dependency in setup.py --- setup.py | 1 + slither/tools/doctor/checks/versions.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 86db4fa9a..9cfbb29e4 100644 --- a/setup.py +++ b/setup.py @@ -12,6 +12,7 @@ setup( packages=find_packages(), python_requires=">=3.8", install_requires=[ + "packaging", "prettytable>=0.7.2", "pycryptodome>=3.4.6", # "crytic-compile>=0.2.4", diff --git a/slither/tools/doctor/checks/versions.py b/slither/tools/doctor/checks/versions.py index 909bccf55..90a478a1e 100644 --- a/slither/tools/doctor/checks/versions.py +++ b/slither/tools/doctor/checks/versions.py @@ -3,19 +3,19 @@ import json from typing import Optional import urllib -from packaging.version import parse, LegacyVersion, Version +from packaging.version import parse, Version from slither.utils.colors import yellow, green -def get_installed_version(name: str) -> Optional[LegacyVersion | Version]: +def get_installed_version(name: str) -> Optional[Version]: try: return parse(metadata.version(name)) except metadata.PackageNotFoundError: return None -def get_github_version(name: str) -> Optional[LegacyVersion | Version]: +def get_github_version(name: str) -> Optional[Version]: try: with urllib.request.urlopen( f"https://api.github.com/repos/crytic/{name}/releases/latest" From 4c759ca6a4d0c0b6577a0a8e23ad80f948447865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 17:29:24 -0300 Subject: [PATCH 29/61] slither-doctor: add new PATH checks This ensures PATH is correctly configured, and hints the user about what they might need to do to configure it correctly. --- slither/tools/doctor/checks/__init__.py | 2 + slither/tools/doctor/checks/paths.py | 56 +++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 slither/tools/doctor/checks/paths.py diff --git a/slither/tools/doctor/checks/__init__.py b/slither/tools/doctor/checks/__init__.py index 762c60b5d..8a0741940 100644 --- a/slither/tools/doctor/checks/__init__.py +++ b/slither/tools/doctor/checks/__init__.py @@ -1,6 +1,7 @@ from typing import Callable, List from dataclasses import dataclass +from slither.tools.doctor.checks.paths import check_slither_path from slither.tools.doctor.checks.platform import compile_project, detect_platform from slither.tools.doctor.checks.versions import show_versions @@ -12,6 +13,7 @@ class Check: ALL_CHECKS: List[Check] = [ + Check("PATH configuration", check_slither_path), Check("Software versions", show_versions), Check("Project platform", detect_platform), Check("Project compilation", compile_project), diff --git a/slither/tools/doctor/checks/paths.py b/slither/tools/doctor/checks/paths.py new file mode 100644 index 000000000..53fae78ad --- /dev/null +++ b/slither/tools/doctor/checks/paths.py @@ -0,0 +1,56 @@ +from pathlib import Path +from typing import List, Optional, Tuple +import shutil +import sysconfig + +from slither.utils.colors import yellow, green, red + + +def check_path_config(name: str) -> Tuple[bool, Optional[Path], List[Path]]: + binary_path = shutil.which(name) + possible_paths = [] + + for scheme in sysconfig.get_scheme_names(): + script_path = Path(sysconfig.get_path("scripts", scheme)) + purelib_path = Path(sysconfig.get_path("purelib", scheme)) + script_binary_path = shutil.which(name, path=script_path) + if script_binary_path is not None: + possible_paths.append((script_path, purelib_path)) + + binary_here = False + if binary_path is not None: + binary_path = Path(binary_path) + this_code = Path(__file__) + this_binary = list(filter(lambda x: this_code.is_relative_to(x[1]), possible_paths)) + binary_here = len(this_binary) > 0 and all( + binary_path.is_relative_to(script) for script, _ in this_binary + ) + + return binary_here, binary_path, list(set(script for script, _ in possible_paths)) + + +def check_slither_path(**_kwargs) -> None: + binary_here, binary_path, possible_paths = check_path_config("slither") + show_paths = False + + if binary_path: + print(green(f"`slither` found in PATH at `{binary_path}`.")) + if binary_here: + print(green("Its location matches this slither-doctor installation.")) + else: + print( + yellow( + f"This path does not correspond to this slither-doctor installation.\n" + + "Double-check the order of directories in PATH if you have several slither installations." + ) + ) + show_paths = True + else: + print(red("`slither` was not found in PATH.")) + show_paths = True + + if show_paths: + print() + print("Consider adding one of the following directories to PATH:") + for path in possible_paths: + print(f" * {path}") From c531681a8a7ec52e4b724336929d9d7377b21927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 17:31:01 -0300 Subject: [PATCH 30/61] ci: slither-doctor: add workflow --- .github/workflows/doctor.yml | 74 ++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 .github/workflows/doctor.yml diff --git a/.github/workflows/doctor.yml b/.github/workflows/doctor.yml new file mode 100644 index 000000000..3d1150eef --- /dev/null +++ b/.github/workflows/doctor.yml @@ -0,0 +1,74 @@ +--- +name: CI (slither-doctor) + +defaults: + run: + shell: bash + +on: + push: + branches: + - master + - dev + pull_request: + paths: + - 'slither/tools/doctor/**' + - '.github/workflows/doctor.yml' + +jobs: + doctor: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: ["ubuntu-latest", "windows-2022"] + python: ["3.8", "3.9", "3.10", "3.11"] + steps: + - uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python }} + + - name: Try system-wide Slither + run: | + pip3 install . + + # escape cwd so python doesn't pick up local module + cd / + + echo "Via module" + python3 -m slither.tools.doctor . + + echo "Via binary" + slither-doctor . + + - name: Try user Slither + run: | + pip3 install --user . + + # escape cwd so python doesn't pick up local module + cd / + + echo "Via module" + python3 -m slither.tools.doctor . + + echo "Via binary" + slither-doctor . + + - name: Try venv Slither + run: | + python3 -m venv venv + source venv/bin/activate + hash -r + pip3 install . + + # escape cwd so python doesn't pick up local module + cd / + + echo "Via module" + python3 -m slither.tools.doctor . + + echo "Via binary" + slither-doctor . From b2ce73108adb4ef50e65c079f51305d9dd20d917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 17:53:48 -0300 Subject: [PATCH 31/61] slither-doctor: fix "unsupported format string passed to Version.__format__" --- slither/tools/doctor/checks/versions.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slither/tools/doctor/checks/versions.py b/slither/tools/doctor/checks/versions.py index 90a478a1e..ec7ef1d1f 100644 --- a/slither/tools/doctor/checks/versions.py +++ b/slither/tools/doctor/checks/versions.py @@ -45,7 +45,9 @@ def show_versions(**_kwargs) -> None: for name, (installed, latest) in versions.items(): color = yellow if name in outdated else green - print(f"{name + ':':<16}{color(installed or 'N/A'):<16} (latest is {latest or 'Unknown'})") + print( + f"{name + ':':<16}{color(str(installed) or 'N/A'):<16} (latest is {str(latest) or 'Unknown'})" + ) if len(outdated) > 0: print() From 21daf7348997273424d8445998aab93c105e083f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 17:55:27 -0300 Subject: [PATCH 32/61] slither-doctor: log on stdout This avoids mixed output in e.g. CI outputs --- slither/tools/doctor/__main__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/slither/tools/doctor/__main__.py b/slither/tools/doctor/__main__.py index 94ae865ec..b9b4c5497 100644 --- a/slither/tools/doctor/__main__.py +++ b/slither/tools/doctor/__main__.py @@ -1,4 +1,6 @@ import argparse +import logging +import sys from crytic_compile import cryticparser @@ -25,6 +27,9 @@ def parse_args() -> argparse.Namespace: def main(): + # log on stdout to keep output in order + logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True) + args = parse_args() kwargs = vars(args) From 20198b9618d21e394d0b1599adefe46ec1c03102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 17:57:28 -0300 Subject: [PATCH 33/61] slither-doctor: fix `is_relative_to` on Python 3.8 --- slither/tools/doctor/checks/paths.py | 33 ++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/slither/tools/doctor/checks/paths.py b/slither/tools/doctor/checks/paths.py index 53fae78ad..4adf3b159 100644 --- a/slither/tools/doctor/checks/paths.py +++ b/slither/tools/doctor/checks/paths.py @@ -1,12 +1,41 @@ from pathlib import Path from typing import List, Optional, Tuple import shutil +import sys import sysconfig from slither.utils.colors import yellow, green, red +def path_is_relative_to(path: Path, relative_to: Path) -> bool: + """ + Check if a path is relative to another one. + + Compatibility wrapper for Path.is_relative_to + """ + if sys.version_info >= (3, 9, 0): + return path.is_relative_to(relative_to) + + path_parts = path.resolve().parts + relative_to_parts = relative_to.resolve().parts + + if len(path_parts) < len(relative_to_parts): + return False + + for (a, b) in zip(path_parts, relative_to_parts): + if a != b: + return False + + return True + + def check_path_config(name: str) -> Tuple[bool, Optional[Path], List[Path]]: + """ + Check if a given Python binary/script is in PATH. + :return: Returns if the binary on PATH corresponds to this installation, + its path (if present), and a list of possible paths where this + binary might be found. + """ binary_path = shutil.which(name) possible_paths = [] @@ -21,9 +50,9 @@ def check_path_config(name: str) -> Tuple[bool, Optional[Path], List[Path]]: if binary_path is not None: binary_path = Path(binary_path) this_code = Path(__file__) - this_binary = list(filter(lambda x: this_code.is_relative_to(x[1]), possible_paths)) + this_binary = list(filter(lambda x: path_is_relative_to(this_code, x[1]), possible_paths)) binary_here = len(this_binary) > 0 and all( - binary_path.is_relative_to(script) for script, _ in this_binary + path_is_relative_to(binary_path, script) for script, _ in this_binary ) return binary_here, binary_path, list(set(script for script, _ in possible_paths)) From e65031ebd55e08da23f97919a3f7ecc49981177d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 17:59:03 -0300 Subject: [PATCH 34/61] ci: slither-doctor: fix Windows venv execution --- .github/workflows/doctor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doctor.yml b/.github/workflows/doctor.yml index 3d1150eef..612374bc2 100644 --- a/.github/workflows/doctor.yml +++ b/.github/workflows/doctor.yml @@ -60,7 +60,7 @@ jobs: - name: Try venv Slither run: | python3 -m venv venv - source venv/bin/activate + source venv/bin/activate || source venv/Scripts/activate hash -r pip3 install . From 21967c2525c4dcf6bc40aa487e1eb08e46c4156f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 19:18:45 -0300 Subject: [PATCH 35/61] ci: slither-doctor: group output --- .github/workflows/doctor.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/doctor.yml b/.github/workflows/doctor.yml index 612374bc2..582e0dc87 100644 --- a/.github/workflows/doctor.yml +++ b/.github/workflows/doctor.yml @@ -33,42 +33,54 @@ jobs: - name: Try system-wide Slither run: | + echo "::group::Install slither" pip3 install . + echo "::endgroup::" # escape cwd so python doesn't pick up local module cd / - echo "Via module" + echo "::group::Via module" python3 -m slither.tools.doctor . + echo "::endgroup::" - echo "Via binary" + echo "::group::Via binary" slither-doctor . + echo "::endgroup::" - name: Try user Slither run: | + echo "::group::Install slither" pip3 install --user . + echo "::endgroup::" # escape cwd so python doesn't pick up local module cd / - echo "Via module" + echo "::group::Via module" python3 -m slither.tools.doctor . + echo "::endgroup::" - echo "Via binary" + echo "::group::Via binary" slither-doctor . + echo "::endgroup::" - name: Try venv Slither run: | + echo "::group::Install slither" python3 -m venv venv source venv/bin/activate || source venv/Scripts/activate hash -r pip3 install . + echo "::endgroup::" # escape cwd so python doesn't pick up local module cd / - echo "Via module" + echo "::group::Via module" python3 -m slither.tools.doctor . + echo "::endgroup::" - echo "Via binary" + echo "::group::Via binary" slither-doctor . + echo "::endgroup::" From d7538795a50eea61633daf54c86ae25ce2109e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 20:06:47 -0300 Subject: [PATCH 36/61] ci: slither-doctor: disable on branches, add dispatch --- .github/workflows/doctor.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/doctor.yml b/.github/workflows/doctor.yml index 582e0dc87..811680db4 100644 --- a/.github/workflows/doctor.yml +++ b/.github/workflows/doctor.yml @@ -1,22 +1,19 @@ --- -name: CI (slither-doctor) +name: CI defaults: run: shell: bash on: - push: - branches: - - master - - dev + workflow_dispatch: pull_request: paths: - 'slither/tools/doctor/**' - '.github/workflows/doctor.yml' jobs: - doctor: + slither-doctor: runs-on: ${{ matrix.os }} strategy: fail-fast: false From b01ba03fa8da270f51151926b789448928301afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 20:08:14 -0300 Subject: [PATCH 37/61] ci: slither-doctor: disable Windows with Python 3.8 --- .github/workflows/doctor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/doctor.yml b/.github/workflows/doctor.yml index 811680db4..b6124216a 100644 --- a/.github/workflows/doctor.yml +++ b/.github/workflows/doctor.yml @@ -20,6 +20,10 @@ jobs: matrix: os: ["ubuntu-latest", "windows-2022"] python: ["3.8", "3.9", "3.10", "3.11"] + exclude: + # strange failure + - os: windows-2022 + python: 3.8 steps: - uses: actions/checkout@v3 From 407d35cbd8bb21c34e9731ddaf77751ff496a840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 20:31:09 -0300 Subject: [PATCH 38/61] slither-doctor: fix lint error --- slither/tools/doctor/checks/paths.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slither/tools/doctor/checks/paths.py b/slither/tools/doctor/checks/paths.py index 4adf3b159..d388847ef 100644 --- a/slither/tools/doctor/checks/paths.py +++ b/slither/tools/doctor/checks/paths.py @@ -69,8 +69,8 @@ def check_slither_path(**_kwargs) -> None: else: print( yellow( - f"This path does not correspond to this slither-doctor installation.\n" - + "Double-check the order of directories in PATH if you have several slither installations." + "This path does not correspond to this slither-doctor installation.\n" + + "Double-check the order of directories in PATH if you have several Slither installations." ) ) show_paths = True From 10085c1c1228e4eefc22b2a8c3f1df4194131ca4 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 5 Jan 2023 07:21:54 -0600 Subject: [PATCH 39/61] add tests --- .../test.sol-0.5.12-compact.zip | Bin 0 -> 1931 bytes .../test.sol-0.5.12-legacy.zip | Bin 0 -> 1857 bytes .../test.sol-0.5.12-compact.json | 6 ++++++ .../test.sol-0.5.12-legacy.json | 6 ++++++ tests/test_ast_parsing.py | 1 + 5 files changed, 13 insertions(+) create mode 100644 tests/ast-parsing/compile/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-compact.zip create mode 100644 tests/ast-parsing/compile/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-legacy.zip create mode 100644 tests/ast-parsing/expected/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-compact.json create mode 100644 tests/ast-parsing/expected/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-legacy.json diff --git a/tests/ast-parsing/compile/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-compact.zip b/tests/ast-parsing/compile/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..f1b13305654d3104c79b9fbcebc2e89f2ae02147 GIT binary patch literal 1931 zcmaLY`#;l*0|xMqWpc}9xh1z^O=YaZv@vpRB6C+%7NQL`GY7Rqt!X$eaY~yc8cSIv z)IyOMri;w2%fw2}Wi%l~PUrjk_dL%J&+GXM-o9SzpL0`Ql9ASl3~^96_>*f3{n9N@{G2mSmSxcm=n#0K4DPOeh%vv z22*~ojmUakw`-rr#Fie-O0$aZ5@jOEzELZVZn^q)baS>53#lIT6^}4<$bKsKiLnI`5Nc`#iN{~y^uP|`(Cy6Y1H*! zLa`z{oLS}EV_AmDJodUZ>gD9hrIc`l20U&QeMPvW+ENw_R|!*aqPcEpQgW$!o^>rB zI?+-MXa~2_ILCHh3^pFUqZG75m-;x^=-h|KXb7zt2@-~SKvGE_e<~L8JAceO??>We zOxoKtauX`;+c%Ooy$xN!cp@fS@uA%9eUIJigOUyYDh=h<*P{e6yTb&y$B!h5pQb9W z8_SCHGUiNpN79XMus&`=MbP|$B(uH&h!y(Zt7+77YZ(LpMVg+yoR> zlaY|aLzS1IL6O9HpUT7W;#ld8t0tN4IAM*lDr9>UQ*P z@Ro}O%tb~@!}7_2Sx}EO0>y+HHnYx$rul+EVZw1HbWz^XBzXDoSaT-U?gIby zEzn9rLl0V@RTJ>XYU1*Z3nVhZpo>dc-;FpiKWng57c|GY@@4qmyAnZMHwjtt>v?x? zy)5O%UicjRd1=2@t&`s$(GB0Y-v>WWHo*EiRV-0JG>#YG2E(|2XI>JT3fk0GYa?y) z!Ed0W_-9jU%m|)IM!L5(n#V-yVZpa^MZBg?H)+dF$qRGc_aXcoxit{iXTX79ei7yA z;lDVgvoRbxI~Mq1z+vf!NS4=-(%FPj@u%)&Io0?v1og(#p`i!+UbL zliOLKg}kem`S0aoN8nG^dlf{u1~ehky>>qKLIwrm=5CIZF67SdAAn|h3lHBOPK zeS=CH1|p;{S6)d#{M*va)mFvxaf{LQ-z&7$k*cVJYXqBHb|H_nWMFfFonl9OEXK6N z{!MrBX~J^&!1&YJhs$x#*6j1f#pUNjky#FT9wBpNJ^GfQLq_nJB~Yq`^X!fM)R-)} z@f_>5sBSis8XaI+IC{ZG527|HI+WJ-(;l(oTEEkB9uDy$^piQyyZ@;7;PN~EA(~yhJpy~ z*#%8O@^iG1Rkfe0N6|Vbq{N8_euk~S*qAoWi?33Y`rTMYB^DTJPt<4Ln5M4Nwp6Or z)IjpSw3R>AiR#t!)aFHh6m3$(I0r?$`Q9fg#tNO5BA!Iv2aO44b=z z+1wnSJz9&(o8`jGd$OBXE>W&0$iF^3HvdK^^~`js zx2VTe6<{r@kL%3cX$@~CXX$UuI{vojPw^!y_a;Pw?a=l_t3`KjSmVqqU2=;;X@Nu3 zuX7dBKzFt$Fvi)1yd56@QQZHfRbxI^A5^D1QxO{Ov_!a@>W+2Ydb{5){`^ojt*F>E zZI;j&T3TZ2>aNE^h@do*ktj_sp`@kHTcp$%+?5RFa}lXH#|3;u+HT%ZG`Sy=aFWvfj5-$9?OfY}vU+rkal5c!m@ED0GAhq9B8s2vvD^M)!E) zt+MR2(yB}_N&;0#B+6lIk=wFy=*3>rjBuEfzoX(q>k_~>hY{UWXezmkJ0o7PY$@ai z%*Hy~<*W#NilbWCb3&Eb6CwWmi&f;{>m>);v+n<6`P<9?C0*{{`7b(sy}-Yb1pv9< M_58g%*Z=$e0jWoo0ssI2 literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/compile/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-legacy.zip b/tests/ast-parsing/compile/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-legacy.zip new file mode 100644 index 0000000000000000000000000000000000000000..3f457a34d429fcb217e4c6f8d6d4fe219e25014d GIT binary patch literal 1857 zcmaLY_dnYS0|)T0*gI{xRt2#VL}OG-#U|7$>a5x{_6}+m7c17GCqmRyYWEWJ;jw~H zT6I<(S5c!zt=Otnj1t2jh88vuxi0RRL5 zfN%^p9ElAMaK%K01c!yYx`%oC_(o!oe%Rn3P8L?c82}OiKr=nv`}W!G(6Y(VRupf^ z>mXn09?_KShc~svX0Y8qDeW8ar&JcW*v-TO;Lu&cbrQJ0a#aVXlClYT{yNFXzy;1l z7gWp`Yf&=3zbQU`rAn&uaGlFH7}Y5dkb*q_ur$9rv>_i^JEhrtGRx0Zjw0LIp|XfuZMJD4 ze(lItVaJM1=9T!j9kYw8`n_q&JCtXH{Ipyr+FXNfgPOvj=)6|D_@c4Ht0KlVOr4>P zW-?wtdBUq4{hDPtuQKyJGD_&Ot#=uLa>YsZq#8gv1xl^DJ&N9JJtCMlK64|gU}-K1 z6NlztYxj(-j)9IK)*z0xZw*tNpIm)4?sW!U!TgS4tCae;t`4uzF~0k{T0?KJ;`E8J z9*4g99+Ol!PeU#W%n|i&ZK@BZ>PsfNo8)!HwezmI&xEL&I+S+J5xk1+m4ksZl@-!9 zPKV9bSu*ujP_u(&wGwhNhO|3o=1oU>T_DyYY-s&2l;oxc%nrU}Z|M%wHmi=n(ds$v zn&b^HP@o=uO*8WbP{vUs4~Un(G_whb#>JM@i}>0feCYQU#O%GCJ^leQ#(V~53^lcQaDjM4{DY*xnDD1o{=5vgLZ`LZ)WSpjWTNI! zsp@gwHw`~7&K*j#ESJpsp;{dfwla~;t}$X|9o`>K^<^s8EI-ItlIR1TF z$uz3<`(s_*$t4>EsCVsNQP$=Mkp z91DG{;@;O2ns+r1ZS5E>ZD~*;dzwsc(g~qLBU)Z`bjmN8D29;eI&a_6Us*f773beu zdjxYzbj1w1HuIZBLp};ze!g2_5DlF4Sk|2LoR36?WbM^&i28lGRR1)t@arjI9brz| zfZOIa%}4o4c`1K~7=*~C@4 z1UM}CXw~7C491Iczk`UYX1xV01XtLYdA0;a!+Xo{W()Rf=pDPix&o1UXezzz%QeOY zL!kOUYG!BE8$+9y9{0T%Ym&rF|AepSWuSaG(oE^?bLzQdK5WuNlg%Rd>*(5I7lfpw{o$_9 zEu&6Xas-&1`1HK%FUMVG5_t!$;mWi-%-=Y-DaP7#sR26m0OrF{%t%fgKiRyse)}06 zO5Tqsv%WzxTg|WabRnsSVReepQZc#jk0tEdQ|!ahhPC4Ix?%2Ox-%8u+=ZhI{To%@XjhMJq$OmL2Qc~6g3b?{qef#ZZD?~?k_wFY zMilEaY$1`Z_h1XX@A24&;)3uCXc}tjJioFibH>QGI9*^p2uo#D?HKnCr9dGdN4t`u z2rbgRwU6o7tGFlXII0IhJW=9 zg4jD8-tB(YJ?&jV literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/expected/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-compact.json b/tests/ast-parsing/expected/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-compact.json new file mode 100644 index 000000000..4132f73d9 --- /dev/null +++ b/tests/ast-parsing/expected/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-compact.json @@ -0,0 +1,6 @@ +{ + "A": {}, + "Z": { + "test()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-legacy.json b/tests/ast-parsing/expected/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-legacy.json new file mode 100644 index 000000000..4132f73d9 --- /dev/null +++ b/tests/ast-parsing/expected/complex_imports/import_aliases_issue_1319/test.sol-0.5.12-legacy.json @@ -0,0 +1,6 @@ +{ + "A": {}, + "Z": { + "test()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/test_ast_parsing.py b/tests/test_ast_parsing.py index e96a129b8..5f1f6f58c 100644 --- a/tests/test_ast_parsing.py +++ b/tests/test_ast_parsing.py @@ -425,6 +425,7 @@ ALL_TESTS = [ Test("free_functions/library_constant_function_collision.sol", ["0.8.12"]), Test("ternary-with-max.sol", ["0.8.15"]), Test("library_event-0.8.16.sol", ["0.8.16"]), + Test("complex_imports/import_aliases_issue_1319/test.sol", ["0.5.12"]), ] # create the output folder if needed try: From c7154637d64de45b9be849b60003c016189f4da1 Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Thu, 5 Jan 2023 19:33:14 +0100 Subject: [PATCH 40/61] WIP fix yul parsing --- slither/core/children/child_function.py | 4 +- slither/core/expressions/identifier.py | 4 +- slither/core/variables/local_variable.py | 4 +- slither/slithir/convert.py | 1 + slither/solc_parsing/declarations/function.py | 1 - slither/solc_parsing/yul/evm_functions.py | 4 +- slither/solc_parsing/yul/parse_yul.py | 86 +++++++++++-------- slither/tools/documentation/__main__.py | 0 tests/ast-parsing/yul-top-level-0.8.0.sol | 16 ++++ tests/test_ast_parsing.py | 1 + 10 files changed, 76 insertions(+), 45 deletions(-) create mode 100644 slither/tools/documentation/__main__.py create mode 100644 tests/ast-parsing/yul-top-level-0.8.0.sol diff --git a/slither/core/children/child_function.py b/slither/core/children/child_function.py index cb4f0109f..5367320ca 100644 --- a/slither/core/children/child_function.py +++ b/slither/core/children/child_function.py @@ -5,11 +5,11 @@ if TYPE_CHECKING: class ChildFunction: - def __init__(self): + def __init__(self) -> None: super().__init__() self._function = None - def set_function(self, function: "Function"): + def set_function(self, function: "Function") -> None: self._function = function @property diff --git a/slither/core/expressions/identifier.py b/slither/core/expressions/identifier.py index ab40472a4..0b10c5615 100644 --- a/slither/core/expressions/identifier.py +++ b/slither/core/expressions/identifier.py @@ -7,7 +7,7 @@ if TYPE_CHECKING: class Identifier(ExpressionTyped): - def __init__(self, value): + def __init__(self, value) -> None: super().__init__() self._value: "Variable" = value @@ -15,5 +15,5 @@ class Identifier(ExpressionTyped): def value(self) -> "Variable": return self._value - def __str__(self): + def __str__(self) -> str: return str(self._value) diff --git a/slither/core/variables/local_variable.py b/slither/core/variables/local_variable.py index 5eb641fb4..7b7b4f8bc 100644 --- a/slither/core/variables/local_variable.py +++ b/slither/core/variables/local_variable.py @@ -11,11 +11,11 @@ from slither.core.declarations.structure import Structure class LocalVariable(ChildFunction, Variable): - def __init__(self): + def __init__(self) -> None: super().__init__() self._location: Optional[str] = None - def set_location(self, loc: str): + def set_location(self, loc: str) -> None: self._location = loc @property diff --git a/slither/slithir/convert.py b/slither/slithir/convert.py index 0d2ef1b74..a93f42136 100644 --- a/slither/slithir/convert.py +++ b/slither/slithir/convert.py @@ -1630,6 +1630,7 @@ def find_references_origin(irs): """ for ir in irs: if isinstance(ir, (Index, Member)): + print(ir.node.source_mapping) ir.lvalue.points_to = ir.variable_left diff --git a/slither/solc_parsing/declarations/function.py b/slither/solc_parsing/declarations/function.py index 269ca580f..150840b49 100644 --- a/slither/solc_parsing/declarations/function.py +++ b/slither/solc_parsing/declarations/function.py @@ -340,7 +340,6 @@ class FunctionSolc(CallerContextExpression): node, [self._function.name, f"asm_{len(self._node_to_yulobject)}"], scope, - parent_func=self._function, ) self._node_to_yulobject[node] = yul_object return yul_object diff --git a/slither/solc_parsing/yul/evm_functions.py b/slither/solc_parsing/yul/evm_functions.py index 0276d4bf7..41c150765 100644 --- a/slither/solc_parsing/yul/evm_functions.py +++ b/slither/solc_parsing/yul/evm_functions.py @@ -264,9 +264,9 @@ binary_ops = { class YulBuiltin: # pylint: disable=too-few-public-methods - def __init__(self, name): + def __init__(self, name: str) -> None: self._name = name @property - def name(self): + def name(self) -> str: return self._name diff --git a/slither/solc_parsing/yul/parse_yul.py b/slither/solc_parsing/yul/parse_yul.py index 8c9ee427e..f7c9938fc 100644 --- a/slither/solc_parsing/yul/parse_yul.py +++ b/slither/solc_parsing/yul/parse_yul.py @@ -24,6 +24,7 @@ from slither.core.expressions import ( UnaryOperation, ) from slither.core.expressions.expression import Expression +from slither.core.scope.scope import FileScope from slither.core.solidity_types import ElementaryType from slither.core.source_mapping.source_mapping import SourceMapping from slither.core.variables.local_variable import LocalVariable @@ -51,30 +52,35 @@ class YulNode: def underlying_node(self) -> Node: return self._node - def add_unparsed_expression(self, expression: Dict): + def add_unparsed_expression(self, expression: Dict) -> None: assert self._unparsed_expression is None self._unparsed_expression = expression - def analyze_expressions(self): + def analyze_expressions(self) -> None: if self._node.type == NodeType.VARIABLE and not self._node.expression: - self._node.add_expression(self._node.variable_declaration.expression) + expression = self._node.variable_declaration.expression + if expression: + self._node.add_expression(expression) if self._unparsed_expression: expression = parse_yul(self._scope, self, self._unparsed_expression) - self._node.add_expression(expression) + if expression: + self._node.add_expression(expression) if self._node.expression: if self._node.type == NodeType.VARIABLE: # Update the expression to be an assignement to the variable - _expression = AssignmentOperation( - Identifier(self._node.variable_declaration), - self._node.expression, - AssignmentOperationType.ASSIGN, - self._node.variable_declaration.type, - ) - _expression.set_offset( - self._node.expression.source_mapping, self._node.compilation_unit - ) - self._node.add_expression(_expression, bypass_verif_empty=True) + variable_declaration = self._node.variable_declaration + if variable_declaration: + _expression = AssignmentOperation( + Identifier(self._node.variable_declaration), + self._node.expression, + AssignmentOperationType.ASSIGN, + variable_declaration.type, + ) + _expression.set_offset( + self._node.expression.source_mapping, self._node.compilation_unit + ) + self._node.add_expression(_expression, bypass_verif_empty=True) expression = self._node.expression read_var = ReadVar(expression) @@ -122,13 +128,13 @@ class YulScope(metaclass=abc.ABCMeta): ] def __init__( - self, contract: Optional[Contract], yul_id: List[str], parent_func: Function = None - ): + self, contract: Optional[Contract], yul_id: List[str], parent_func: Function + ) -> None: self._contract = contract self._id: List[str] = yul_id self._yul_local_variables: List[YulLocalVariable] = [] self._yul_local_functions: List[YulFunction] = [] - self._parent_func = parent_func + self._parent_func: Function = parent_func @property def id(self) -> List[str]: @@ -155,10 +161,14 @@ class YulScope(metaclass=abc.ABCMeta): def new_node(self, node_type: NodeType, src: Union[str, Dict]) -> YulNode: pass - def add_yul_local_variable(self, var): + @property + def file_scope(self) -> FileScope: + return self._parent_func.file_scope + + def add_yul_local_variable(self, var: "YulLocalVariable") -> None: self._yul_local_variables.append(var) - def get_yul_local_variable_from_name(self, variable_name): + def get_yul_local_variable_from_name(self, variable_name: str) -> Optional["YulLocalVariable"]: return next( ( v @@ -168,10 +178,10 @@ class YulScope(metaclass=abc.ABCMeta): None, ) - def add_yul_local_function(self, func): + def add_yul_local_function(self, func: "YulFunction") -> None: self._yul_local_functions.append(func) - def get_yul_local_function_from_name(self, func_name): + def get_yul_local_function_from_name(self, func_name: str) -> Optional["YulLocalVariable"]: return next( (v for v in self._yul_local_functions if v.underlying.name == func_name), None, @@ -242,7 +252,7 @@ class YulFunction(YulScope): def function(self) -> Function: return self._function - def convert_body(self): + def convert_body(self) -> None: node = self.new_node(NodeType.ENTRYPOINT, self._ast["src"]) link_underlying_nodes(self._entrypoint, node) @@ -258,7 +268,7 @@ class YulFunction(YulScope): convert_yul(self, node, self._ast["body"], self.node_scope) - def parse_body(self): + def parse_body(self) -> None: for node in self._nodes: node.analyze_expressions() @@ -289,9 +299,8 @@ class YulBlock(YulScope): entrypoint: Node, yul_id: List[str], node_scope: Union[Scope, Function], - **kwargs, ): - super().__init__(contract, yul_id, **kwargs) + super().__init__(contract, yul_id, entrypoint.function) self._entrypoint: YulNode = YulNode(entrypoint, self) self._nodes: List[YulNode] = [] @@ -318,7 +327,7 @@ class YulBlock(YulScope): def convert(self, ast: Dict) -> YulNode: return convert_yul(self, self._entrypoint, ast, self.node_scope) - def analyze_expressions(self): + def analyze_expressions(self) -> None: for node in self._nodes: node.analyze_expressions() @@ -361,18 +370,22 @@ def convert_yul_function_definition( while not isinstance(top_node_scope, Function): top_node_scope = top_node_scope.father + func: Union[FunctionTopLevel, FunctionContract] if isinstance(top_node_scope, FunctionTopLevel): - scope = root.contract.file_scope + scope = root.file_scope func = FunctionTopLevel(root.compilation_unit, scope) # Note: we do not add the function in the scope # While its a top level function, it is not accessible outside of the function definition # In practice we should probably have a specific function type for function defined within a function else: func = FunctionContract(root.compilation_unit) + func.function_language = FunctionLanguage.Yul yul_function = YulFunction(func, root, ast, node_scope) - root.contract.add_function(func) + if root.contract: + root.contract.add_function(func) + root.compilation_unit.add_function(func) root.add_yul_local_function(yul_function) @@ -774,14 +787,15 @@ def parse_yul_identifier(root: YulScope, _node: YulNode, ast: Dict) -> Optional[ # check function-scoped variables parent_func = root.parent_func if parent_func: - variable = parent_func.get_local_variable_from_name(name) - if variable: - return Identifier(variable) + local_variable = parent_func.get_local_variable_from_name(name) + if local_variable: + return Identifier(local_variable) if isinstance(parent_func, FunctionContract): - variable = parent_func.contract.get_state_variable_from_name(name) - if variable: - return Identifier(variable) + assert parent_func.contract + state_variable = parent_func.contract.get_state_variable_from_name(name) + if state_variable: + return Identifier(state_variable) # check yul-scoped variable variable = root.get_yul_local_variable_from_name(name) @@ -798,7 +812,7 @@ def parse_yul_identifier(root: YulScope, _node: YulNode, ast: Dict) -> Optional[ if magic_suffix: return magic_suffix - ret, _ = find_top_level(name, root.contract.file_scope) + ret, _ = find_top_level(name, root.file_scope) if ret: return Identifier(ret) @@ -840,7 +854,7 @@ def parse_yul_unsupported(_root: YulScope, _node: YulNode, ast: Dict) -> Optiona def parse_yul(root: YulScope, node: YulNode, ast: Dict) -> Optional[Expression]: - op = parsers.get(ast["nodeType"], parse_yul_unsupported)(root, node, ast) + op: Expression = parsers.get(ast["nodeType"], parse_yul_unsupported)(root, node, ast) if op: op.set_offset(ast["src"], root.compilation_unit) return op diff --git a/slither/tools/documentation/__main__.py b/slither/tools/documentation/__main__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/ast-parsing/yul-top-level-0.8.0.sol b/tests/ast-parsing/yul-top-level-0.8.0.sol new file mode 100644 index 000000000..214db9cb4 --- /dev/null +++ b/tests/ast-parsing/yul-top-level-0.8.0.sol @@ -0,0 +1,16 @@ +function top_level_yul(int256 c) pure returns (uint result) { + assembly { + function internal_yul(a) -> b { + b := a + } + + result := internal_yul(c) + } +} + + +contract Test { + function test() public{ + top_level_yul(10); + } +} \ No newline at end of file diff --git a/tests/test_ast_parsing.py b/tests/test_ast_parsing.py index 96aad1a63..e6764ba0c 100644 --- a/tests/test_ast_parsing.py +++ b/tests/test_ast_parsing.py @@ -435,6 +435,7 @@ ALL_TESTS = [ Test("using-for-global-0.8.0.sol", ["0.8.15"]), Test("library_event-0.8.16.sol", ["0.8.16"]), Test("top-level-struct-0.8.0.sol", ["0.8.0"]), + Test("yul-top-level-0.8.0.sol", ["0.8.0"]), ] # create the output folder if needed try: From 0b99b348fb8ccc702a6b0c18ba92bd623e8725a5 Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Thu, 5 Jan 2023 19:42:19 +0100 Subject: [PATCH 41/61] minor --- slither/slithir/convert.py | 1 - 1 file changed, 1 deletion(-) diff --git a/slither/slithir/convert.py b/slither/slithir/convert.py index a93f42136..0d2ef1b74 100644 --- a/slither/slithir/convert.py +++ b/slither/slithir/convert.py @@ -1630,7 +1630,6 @@ def find_references_origin(irs): """ for ir in irs: if isinstance(ir, (Index, Member)): - print(ir.node.source_mapping) ir.lvalue.points_to = ir.variable_left From d1b875d85e7e3660bd5fcc2d90ed68c6f1c8f479 Mon Sep 17 00:00:00 2001 From: pavan-nambi Date: Fri, 6 Jan 2023 02:25:17 +0530 Subject: [PATCH 42/61] update --- .github/workflows/IR.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/IR.yml b/.github/workflows/IR.yml index c5187da65..891de2bfb 100644 --- a/.github/workflows/IR.yml +++ b/.github/workflows/IR.yml @@ -34,8 +34,14 @@ jobs: - name: Install dependencies run: | pip install ".[dev]" + solc-select install 0.5.0 solc-select use 0.8.11 --always-install + - name: Install old solc + if: matrix.os == 'ubuntu-latest' + run: solc-select install 0.4.0 + + - name: Test with pytest run: | - pytest tests/test_ssa_generation.py + pytest tests/test_ssa_generation.py \ No newline at end of file From 53eea1d21640e19bd703d2a7e7e7db68f76b4a2a Mon Sep 17 00:00:00 2001 From: Josselin Feist Date: Fri, 6 Jan 2023 13:40:32 +0100 Subject: [PATCH 43/61] Add missing file --- .../yul-top-level-0.8.0.sol-0.8.0-compact.zip | Bin 0 -> 2061 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/ast-parsing/compile/yul-top-level-0.8.0.sol-0.8.0-compact.zip diff --git a/tests/ast-parsing/compile/yul-top-level-0.8.0.sol-0.8.0-compact.zip b/tests/ast-parsing/compile/yul-top-level-0.8.0.sol-0.8.0-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..ce81a5c37e9972e41c7cc13f57469de6b38aa11c GIT binary patch literal 2061 zcmb8wX&}>$0|)TmWTJme%JDen4zam&A2}lybL4T(nIn@q=bi~I_c7$0Bv+TH5QefW z&sgQoy(mZK>dF1|{NMjy{J-B9-&fz)ADe5ZSPcLcfD33Um3Ca1o3V8`4FG;303Z(l z05;+lEIi~k?3Qn&?=6@TTobMY4-2{F;TwHB1QYJziShOii1dXAhJ~OxSiyiB03-o` zUV8dX)kD=#(ns1$9nP|M=m6<%=$%ZYpuXr>SSO$I_Da7w*{SFq@Mmkr2C8{Gpj5}W!Ye#Dg=n*{o1cP+%1xr zlUhqkz9t03i~Ixs>{El?+IEE)-@ZM6cU_FcHe?cmgN zLS3DqnryzYnKO+xAVq1YOo@tG2eH4eN7zgh?kRZDIGP`tttzJEdxV;xM&{)Fd&Gu% z?+spc=H_@KSH92CC|S7JoGTQ!t+{Y8Fu8Va2)9`5mMa^s#$ebPNbKK1y7o%j$yGDb z3U>1}cU%JICm)Uv8#rDB`^xwe+>|4r>fcy%^ktr!CjV&A%AzrU2H=qqYP#`>E^X&L z>loIT1Vf(r#VfS%-Jj}cRX(4PHtcRJ7BnoCDvxuD^i&YCa)vzW35z- zm@*&Lj&?0~%dnhds%-K@+j<6C;E+g(q%Y$O5c;L0N|hgf&s42}doz@a_sv|CPa?R4T(r)JULDI^)d+4p zAD*JQr3e~fI$?9yA|eXo>WPcw?Tq53cN}luHxkMZbqY?N4_mYeuKm2| zb-$#}{*>&tJi1lp?&?py(8_kKThPesb%K zhx%iNsz)CNMSwOi_VYV ziY3P`CO99dog#PE6-{Z3R2yGuZSOEabI3dN$m(vCwKU76qt^H!W7bl!Jkc?;Jr1Z7 zyme{|zJa{lPg9RWInl4Y?|WHPsw=FL)w=?pb(YuL>s;k24E3}0JFu>d>S(z0(Mb*k z)k`)2a}P(jP42}u0*Ya-h-|Y8-V16@_!fTtt!fDgy+O)iQ@>%P9TP(%>~d8~3^laW zOw?qM_h_Ku>0vZ!1=g=$PO^N2V|7BS>PwaruMThyN^xh4CGwi;I(vfY^n$NTD?(6* zE(lq)QsnZT^oZ5tx0?n&Qa)XVNqS_$>faJ9XrUa;QhBwA_XLR|u3p46K|ln=wZl#r zHAaMb1p#a?X<+CrwhTRkrE5G8A3`j!If)|iHd1|sSFBN7Hdf3CE@ z>+PS-1;t7eA-QrcQ|E9Ile-8j3*i|SrP7MP=U*CXn`9iD2~+g_>#JKA<_CCjKnLmR zbkZCfZX?E`=Oa}4KysB3tyP2YF{+t2PmHh-$!t0N4*cS2qX5o=Psi>t1&^4UZc`!! z#|Pu-NWU?3LSSVYv`-eLunceaUZi^-K4?M6ENOo#y?R8bFkLo14quV|AWH(VPVbp@81k+qzu!EgQEH8=*?e#pCC#)zrpns# z`x7W!seD?=jIhJqv~Ip?%Y7KlG1$*PvI!LT%jY6)U0d>u&ci_rHM?`z*VybB^_Zy3 zM8|xc{c4+a6s;=yr{3nv8*fwlZ9phaoSg!v>Ju_+3cho^RY<*|wEqqG(I%$pGlXGv zsn^&i$W%7(vKdrlJWn5vHj=aIbWh-HAhB(~SGhbo9i7VSIPOyt)uA0AS|;0>zUw}q zF=4TBWJwb!n|;~dx@)V90DpylUetS1t(e6PM5n0PdC7 Date: Fri, 6 Jan 2023 14:03:33 +0100 Subject: [PATCH 44/61] Add --no-fail mode --- slither/__main__.py | 7 ++++ slither/core/slither_core.py | 4 +++ slither/printers/guidance/echidna.py | 47 +++++++++++++++------------ slither/slither.py | 48 +++++++++++----------------- slither/utils/command_line.py | 1 + 5 files changed, 56 insertions(+), 51 deletions(-) diff --git a/slither/__main__.py b/slither/__main__.py index 75707af06..dddf973c0 100644 --- a/slither/__main__.py +++ b/slither/__main__.py @@ -555,6 +555,13 @@ def parse_args( default=False, ) + group_misc.add_argument( + "--no-fail", + help="Do not fail in case of parsing (echidna mode only)", + action="store_true", + default=defaults_flag_in_config["no_fail"], + ) + group_codex.add_argument( "--codex", help="Enable codex (require an OpenAI API Key)", diff --git a/slither/core/slither_core.py b/slither/core/slither_core.py index 691699067..66b8fc430 100644 --- a/slither/core/slither_core.py +++ b/slither/core/slither_core.py @@ -92,6 +92,10 @@ class SlitherCore(Context): # But we allow to alter this (ex: file.sol:1) for vscode integration self.line_prefix: str = "#" + # Use by the echidna printer + # If true, partial analysis is allowed + self.no_fail = False + @property def compilation_units(self) -> List[SlitherCompilationUnit]: return list(self._compilation_units) diff --git a/slither/printers/guidance/echidna.py b/slither/printers/guidance/echidna.py index dbfa54121..ec200d5e1 100644 --- a/slither/printers/guidance/echidna.py +++ b/slither/printers/guidance/echidna.py @@ -323,27 +323,32 @@ def _call_a_parameter(slither: SlitherCore) -> Dict[str, List[Dict]]: ret: Dict[str, List[Dict]] = defaultdict(list) for contract in slither.contracts: # pylint: disable=too-many-nested-blocks for function in contract.functions_entry_points: - for ir in function.all_slithir_operations(): - if isinstance(ir, HighLevelCall): - for idx, parameter in enumerate(function.parameters): - if is_dependent(ir.destination, parameter, function): - ret[contract.name].append( - { - "function": _get_name(function), - "parameter_idx": idx, - "signature": _get_name(ir.function), - } - ) - if isinstance(ir, LowLevelCall): - for idx, parameter in enumerate(function.parameters): - if is_dependent(ir.destination, parameter, function): - ret[contract.name].append( - { - "function": _get_name(function), - "parameter_idx": idx, - "signature": None, - } - ) + try: + for ir in function.all_slithir_operations(): + if isinstance(ir, HighLevelCall): + for idx, parameter in enumerate(function.parameters): + if is_dependent(ir.destination, parameter, function): + ret[contract.name].append( + { + "function": _get_name(function), + "parameter_idx": idx, + "signature": _get_name(ir.function), + } + ) + if isinstance(ir, LowLevelCall): + for idx, parameter in enumerate(function.parameters): + if is_dependent(ir.destination, parameter, function): + ret[contract.name].append( + { + "function": _get_name(function), + "parameter_idx": idx, + "signature": None, + } + ) + except Exception as e: + if slither.no_fail: + continue + raise e return ret diff --git a/slither/slither.py b/slither/slither.py index 81e920d01..45d99906f 100644 --- a/slither/slither.py +++ b/slither/slither.py @@ -91,6 +91,8 @@ class Slither(SlitherCore): # pylint: disable=too-many-instance-attributes self.codex_max_tokens = kwargs.get("codex_max_tokens", 300) self.codex_log = kwargs.get("codex_log", False) + self.no_fail = kwargs.get("no_fail", False) + self._parsers: List[SlitherCompilationUnitSolc] = [] try: if isinstance(target, CryticCompile): @@ -128,41 +130,27 @@ class Slither(SlitherCore): # pylint: disable=too-many-instance-attributes triage_mode = kwargs.get("triage_mode", False) self._triage_mode = triage_mode + self._init_parsing_and_analyses(kwargs.get("skip_analyze", False)) + + def _init_parsing_and_analyses(self, skip_analyze: bool) -> None: for parser in self._parsers: - parser.parse_contracts() + try: + parser.parse_contracts() + except Exception as e: + if self.no_fail: + continue + raise e # skip_analyze is only used for testing - if not kwargs.get("skip_analyze", False): + if not skip_analyze: for parser in self._parsers: - parser.analyze_contracts() - - # def _init_from_raw_json(self, filename): - # if not os.path.isfile(filename): - # raise SlitherError( - # "{} does not exist (are you in the correct directory?)".format(filename) - # ) - # assert filename.endswith("json") - # with open(filename, encoding="utf8") as astFile: - # stdout = astFile.read() - # if not stdout: - # to_log = f"Empty AST file: {filename}" - # raise SlitherError(to_log) - # contracts_json = stdout.split("\n=") - # - # self._parser = SlitherCompilationUnitSolc(filename, self) - # - # for c in contracts_json: - # self._parser.parse_top_level_from_json(c) - - # def _init_from_list(self, contract): - # self._parser = SlitherCompilationUnitSolc("", self) - # for c in contract: - # if "absolutePath" in c: - # path = c["absolutePath"] - # else: - # path = c["attributes"]["absolutePath"] - # self._parser.parse_top_level_from_loaded_json(c, path) + try: + parser.analyze_contracts() + except Exception as e: + if self.no_fail: + continue + raise e @property def detectors(self): diff --git a/slither/utils/command_line.py b/slither/utils/command_line.py index 71305c56e..174c2a4b6 100644 --- a/slither/utils/command_line.py +++ b/slither/utils/command_line.py @@ -60,6 +60,7 @@ defaults_flag_in_config = { "zip": None, "zip_type": "lzma", "show_ignored_findings": False, + "no_fail": False, **DEFAULTS_FLAG_IN_CONFIG_CRYTIC_COMPILE, } From 1c12f2a7fcf9bf809b4be7a3b60917ee422730af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Fri, 6 Jan 2023 11:08:24 -0300 Subject: [PATCH 45/61] tests: source_unit: add missing foundry submodule --- .gitmodules | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100755 index 000000000..f2ce479c6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "tests/source_unit/lib/forge-std"] + path = tests/source_unit/lib/forge-std + url = https://github.com/foundry-rs/forge-std + branch = v1.2.0 From d875eff4153d6249189f4e31ee46af3f5ff23bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Fri, 6 Jan 2023 12:34:15 -0300 Subject: [PATCH 46/61] Revert "tests: source_unit: add missing foundry submodule" This reverts commit 1c12f2a7fcf9bf809b4be7a3b60917ee422730af. --- .gitmodules | 4 ---- 1 file changed, 4 deletions(-) delete mode 100755 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100755 index f2ce479c6..000000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "tests/source_unit/lib/forge-std"] - path = tests/source_unit/lib/forge-std - url = https://github.com/foundry-rs/forge-std - branch = v1.2.0 From afb73426194840e78af83a8b00bbb7befe04f912 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 6 Jan 2023 10:11:43 -0600 Subject: [PATCH 47/61] fix constructor var not detected as candidate, separate detectors --- slither/detectors/all_detectors.py | 3 +- .../detectors/variables/could_be_constant.py | 45 ++ .../detectors/variables/could_be_immutable.py | 44 ++ .../possible_const_state_variables.py | 141 ------ .../variables/unchanged_state_variables.py | 123 ++++++ ...iables.py => unchanged_state_variables.py} | 6 +- .../tools/slither_format/slither_format.py | 6 +- .../0.4.25/const_state_variables.sol | 5 + ...variables.sol.0.4.25.CouldBeConstant.json} | 18 +- .../0.5.16/const_state_variables.sol | 5 + ...variables.sol.0.5.16.CouldBeConstant.json} | 27 +- .../0.6.11/const_state_variables.sol | 37 +- ...variables.sol.0.6.11.CouldBeConstant.json} | 169 ++++---- .../0.7.6/const_state_variables.sol | 28 +- ..._variables.sol.0.7.6.CouldBeConstant.json} | 406 ++++-------------- .../0.8.0/const_state_variables.sol | 30 +- ..._variables.sol.0.8.0.CouldBeConstant.json} | 406 ++++-------------- .../0.4.25/immut_state_variables.sol | 57 +++ ...variables.sol.0.4.25.CouldBeImmutable.json | 3 + .../0.5.16/immut_state_variables.sol | 58 +++ ...variables.sol.0.5.16.CouldBeImmutable.json | 3 + .../0.6.11/immut_state_variables.sol | 79 ++++ ...variables.sol.0.6.11.CouldBeImmutable.json | 3 + .../0.7.6/immut_state_variables.sol | 78 ++++ ..._variables.sol.0.7.6.CouldBeImmutable.json | 334 ++++++++++++++ .../0.8.0/immut_state_variables.sol | 78 ++++ ..._variables.sol.0.8.0.CouldBeImmutable.json | 268 ++++++++++++ tests/test_detectors.py | 35 +- 28 files changed, 1606 insertions(+), 889 deletions(-) create mode 100644 slither/detectors/variables/could_be_constant.py create mode 100644 slither/detectors/variables/could_be_immutable.py delete mode 100644 slither/detectors/variables/possible_const_state_variables.py create mode 100644 slither/detectors/variables/unchanged_state_variables.py rename slither/formatters/variables/{possible_const_state_variables.py => unchanged_state_variables.py} (94%) rename tests/detectors/constable-states/0.4.25/{const_state_variables.sol.0.4.25.ConstCandidateStateVars.json => const_state_variables.sol.0.4.25.CouldBeConstant.json} (96%) rename tests/detectors/constable-states/0.5.16/{const_state_variables.sol.0.5.16.ConstCandidateStateVars.json => const_state_variables.sol.0.5.16.CouldBeConstant.json} (96%) rename tests/detectors/constable-states/0.6.11/{const_state_variables.sol.0.6.11.ConstCandidateStateVars.json => const_state_variables.sol.0.6.11.CouldBeConstant.json} (89%) rename tests/detectors/constable-states/0.7.6/{const_state_variables.sol.0.7.6.ConstCandidateStateVars.json => const_state_variables.sol.0.7.6.CouldBeConstant.json} (58%) rename tests/detectors/constable-states/0.8.0/{const_state_variables.sol.0.8.0.ConstCandidateStateVars.json => const_state_variables.sol.0.8.0.CouldBeConstant.json} (58%) create mode 100644 tests/detectors/immutable-states/0.4.25/immut_state_variables.sol create mode 100644 tests/detectors/immutable-states/0.4.25/immut_state_variables.sol.0.4.25.CouldBeImmutable.json create mode 100644 tests/detectors/immutable-states/0.5.16/immut_state_variables.sol create mode 100644 tests/detectors/immutable-states/0.5.16/immut_state_variables.sol.0.5.16.CouldBeImmutable.json create mode 100644 tests/detectors/immutable-states/0.6.11/immut_state_variables.sol create mode 100644 tests/detectors/immutable-states/0.6.11/immut_state_variables.sol.0.6.11.CouldBeImmutable.json create mode 100644 tests/detectors/immutable-states/0.7.6/immut_state_variables.sol create mode 100644 tests/detectors/immutable-states/0.7.6/immut_state_variables.sol.0.7.6.CouldBeImmutable.json create mode 100644 tests/detectors/immutable-states/0.8.0/immut_state_variables.sol create mode 100644 tests/detectors/immutable-states/0.8.0/immut_state_variables.sol.0.8.0.CouldBeImmutable.json diff --git a/slither/detectors/all_detectors.py b/slither/detectors/all_detectors.py index fb2e3c731..1cab317ad 100644 --- a/slither/detectors/all_detectors.py +++ b/slither/detectors/all_detectors.py @@ -19,7 +19,8 @@ from .reentrancy.reentrancy_eth import ReentrancyEth from .reentrancy.reentrancy_no_gas import ReentrancyNoGas from .reentrancy.reentrancy_events import ReentrancyEvent from .variables.unused_state_variables import UnusedStateVars -from .variables.possible_const_state_variables import ConstCandidateStateVars +from .variables.could_be_constant import CouldBeConstant +from .variables.could_be_immutable import CouldBeImmutable from .statements.tx_origin import TxOrigin from .statements.assembly import Assembly from .operations.low_level_calls import LowLevelCalls diff --git a/slither/detectors/variables/could_be_constant.py b/slither/detectors/variables/could_be_constant.py new file mode 100644 index 000000000..0a294dd8d --- /dev/null +++ b/slither/detectors/variables/could_be_constant.py @@ -0,0 +1,45 @@ +from typing import List, Dict +from slither.utils.output import Output +from slither.core.compilation_unit import SlitherCompilationUnit +from slither.formatters.variables.unchanged_state_variables import custom_format +from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification +from .unchanged_state_variables import UnchangedStateVariables + + +class CouldBeConstant(AbstractDetector): + """ + State variables that could be declared as constant. + Not all types for constants are implemented in Solidity as of 0.4.25. + The only supported types are value types and strings (ElementaryType). + Reference: https://solidity.readthedocs.io/en/latest/contracts.html#constant-state-variables + """ + + ARGUMENT = "constable-states" + HELP = "State variables that could be declared constant" + IMPACT = DetectorClassification.OPTIMIZATION + CONFIDENCE = DetectorClassification.HIGH + + WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-constant" + + WIKI_TITLE = "State variables that could be declared constant" + WIKI_DESCRIPTION = "State variables that are not updated following deployment should be declared constant to save gas." + WIKI_RECOMMENDATION = "Add the `constant` attribute to state variables that never change." + + def _detect(self) -> List[Output]: + """Detect state variables that could be constant""" + results = {} + + unchanged_state_variables = UnchangedStateVariables(self.compilation_unit) + unchanged_state_variables.detect() + + for variable in unchanged_state_variables.constant_candidates: + results[variable.canonical_name] = self.generate_result( + [variable, " should be constant \n"] + ) + + # Order by canonical name for deterministic results + return [results[k] for k in sorted(results)] + + @staticmethod + def _format(compilation_unit: SlitherCompilationUnit, result: Dict) -> None: + custom_format(compilation_unit, result, "constant") diff --git a/slither/detectors/variables/could_be_immutable.py b/slither/detectors/variables/could_be_immutable.py new file mode 100644 index 000000000..a9ecb60cd --- /dev/null +++ b/slither/detectors/variables/could_be_immutable.py @@ -0,0 +1,44 @@ +from typing import List, Dict +from slither.utils.output import Output +from slither.core.compilation_unit import SlitherCompilationUnit +from slither.formatters.variables.unchanged_state_variables import custom_format +from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification +from .unchanged_state_variables import UnchangedStateVariables + + +class CouldBeImmutable(AbstractDetector): + """ + State variables that could be declared immutable. + # Immutable attribute available in Solidity 0.6.5 and above + # https://blog.soliditylang.org/2020/04/06/solidity-0.6.5-release-announcement/ + """ + + # VULNERABLE_SOLC_VERSIONS = + ARGUMENT = "immutable-states" + HELP = "State variables that could be declared immutable" + IMPACT = DetectorClassification.OPTIMIZATION + CONFIDENCE = DetectorClassification.HIGH + + WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-immutable" + + WIKI_TITLE = "State variables that could be declared immutable" + WIKI_DESCRIPTION = "State variables that are not updated following deployment should be declared immutable to save gas." + WIKI_RECOMMENDATION = "Add the `immutable` attribute to state variables that never change or are set only in the constructor." + + def _detect(self) -> List[Output]: + """Detect state variables that could be immutable""" + results = {} + unchanged_state_variables = UnchangedStateVariables(self.compilation_unit) + unchanged_state_variables.detect() + + for variable in unchanged_state_variables.immutable_candidates: + results[variable.canonical_name] = self.generate_result( + [variable, " should be immutable \n"] + ) + + # Order by canonical name for deterministic results + return [results[k] for k in sorted(results)] + + @staticmethod + def _format(compilation_unit: SlitherCompilationUnit, result: Dict) -> None: + custom_format(compilation_unit, result, "immutable") diff --git a/slither/detectors/variables/possible_const_state_variables.py b/slither/detectors/variables/possible_const_state_variables.py deleted file mode 100644 index 60a45dfac..000000000 --- a/slither/detectors/variables/possible_const_state_variables.py +++ /dev/null @@ -1,141 +0,0 @@ -""" -Module detecting state variables that could be declared as constant -""" -from typing import Set, List, Dict - -from slither.core.compilation_unit import SlitherCompilationUnit -from slither.core.solidity_types.elementary_type import ElementaryType -from slither.core.solidity_types.user_defined_type import UserDefinedType -from slither.core.variables.variable import Variable -from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification -from slither.utils.output import Output -from slither.visitors.expression.export_values import ExportValues -from slither.core.declarations import Contract, Function -from slither.core.declarations.solidity_variables import SolidityFunction -from slither.core.variables.state_variable import StateVariable -from slither.formatters.variables.possible_const_state_variables import custom_format -from slither.core.expressions import CallExpression, NewContract -from slither.utils.standard_libraries import is_openzeppelin - - -def _is_valid_type(v: StateVariable) -> bool: - t = v.type - if isinstance(t, ElementaryType): - return True - if isinstance(t, UserDefinedType) and isinstance(t.type, Contract): - return True - return False - - -def _valid_candidate(v: StateVariable) -> bool: - return _is_valid_type(v) and not (v.is_constant or v.is_immutable) - - -def _is_constant_var(v: Variable) -> bool: - if isinstance(v, StateVariable): - return v.is_constant - return False - - -class ConstCandidateStateVars(AbstractDetector): - """ - State variables that could be declared as constant detector. - Not all types for constants are implemented in Solidity as of 0.4.25. - The only supported types are value types and strings (ElementaryType). - Reference: https://solidity.readthedocs.io/en/latest/contracts.html#constant-state-variables - """ - - ARGUMENT = "constable-states" - HELP = "State variables that could be declared constant or immutable" - IMPACT = DetectorClassification.OPTIMIZATION - CONFIDENCE = DetectorClassification.HIGH - - WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-constant-or-immutable" - - WIKI_TITLE = "State variables that could be declared constant or immutable" - WIKI_DESCRIPTION = "State variables that are not updated following deployment should be declared constant or immutable to save gas." - WIKI_RECOMMENDATION = ( - "Add the `constant` or `immutable` attribute to state variables that never change." - ) - - # https://solidity.readthedocs.io/en/v0.5.2/contracts.html#constant-state-variables - valid_solidity_function = [ - SolidityFunction("keccak256()"), - SolidityFunction("keccak256(bytes)"), - SolidityFunction("sha256()"), - SolidityFunction("sha256(bytes)"), - SolidityFunction("ripemd160()"), - SolidityFunction("ripemd160(bytes)"), - SolidityFunction("ecrecover(bytes32,uint8,bytes32,bytes32)"), - SolidityFunction("addmod(uint256,uint256,uint256)"), - SolidityFunction("mulmod(uint256,uint256,uint256)"), - ] - - def _constant_initial_expression(self, v: Variable) -> bool: - if not v.expression: - return True - - # B b = new B(); b cannot be constant, so filter out and recommend it be immutable - if isinstance(v.expression, CallExpression) and isinstance( - v.expression.called, NewContract - ): - return False - - export = ExportValues(v.expression) - values = export.result() - if not values: - return True - - return all((val in self.valid_solidity_function or _is_constant_var(val) for val in values)) - - def _detect(self) -> List[Output]: - """Detect state variables that could be constant or immutable""" - results = {} - - variables = [] - functions = [] - for c in self.compilation_unit.contracts: - if is_openzeppelin(c): - continue - variables.append(c.state_variables) - functions.append(c.all_functions_called) - - valid_candidates: Set[StateVariable] = { - item for sublist in variables for item in sublist if _valid_candidate(item) - } - - all_functions: List[Function] = list( - {item1 for sublist in functions for item1 in sublist if isinstance(item1, Function)} - ) - - variables_written = [] - constructor_variables_written = [] - for f in all_functions: - if f.is_constructor_variables: - constructor_variables_written.append(f.state_variables_written) - else: - variables_written.append(f.state_variables_written) - - variables_written = {item for sublist in variables_written for item in sublist} - constructor_variables_written = { - item for sublist in constructor_variables_written for item in sublist - } - for v in valid_candidates: - if v not in variables_written: - if self._constant_initial_expression(v): - results[v.canonical_name] = self.generate_result([v, " should be constant \n"]) - - # immutable attribute available in Solidity 0.6.5 and above - # https://blog.soliditylang.org/2020/04/06/solidity-0.6.5-release-announcement/ - elif ( - v in constructor_variables_written - and self.compilation_unit.solc_version > "0.6.4" - ): - results[v.canonical_name] = self.generate_result([v, " should be immutable \n"]) - - # Order by canonical name for deterministic results - return [results[k] for k in sorted(results)] - - @staticmethod - def _format(compilation_unit: SlitherCompilationUnit, result: Dict) -> None: - custom_format(compilation_unit, result) diff --git a/slither/detectors/variables/unchanged_state_variables.py b/slither/detectors/variables/unchanged_state_variables.py new file mode 100644 index 000000000..62fc61f43 --- /dev/null +++ b/slither/detectors/variables/unchanged_state_variables.py @@ -0,0 +1,123 @@ +""" +Module detecting state variables that could be declared as constant +""" +from typing import Set, List + +from slither.core.compilation_unit import SlitherCompilationUnit +from slither.core.solidity_types.elementary_type import ElementaryType +from slither.core.solidity_types.user_defined_type import UserDefinedType +from slither.core.variables.variable import Variable + +from slither.visitors.expression.export_values import ExportValues +from slither.core.declarations import Contract, Function +from slither.core.declarations.solidity_variables import SolidityFunction +from slither.core.variables.state_variable import StateVariable +from slither.core.expressions import CallExpression, NewContract + + +def _is_valid_type(v: StateVariable) -> bool: + t = v.type + if isinstance(t, ElementaryType): + return True + if isinstance(t, UserDefinedType) and isinstance(t.type, Contract): + return True + return False + + +def _valid_candidate(v: StateVariable) -> bool: + return _is_valid_type(v) and not (v.is_constant or v.is_immutable) + + +def _is_constant_var(v: Variable) -> bool: + if isinstance(v, StateVariable): + return v.is_constant + return False + + +# https://solidity.readthedocs.io/en/v0.5.2/contracts.html#constant-state-variables +valid_solidity_function = [ + SolidityFunction("keccak256()"), + SolidityFunction("keccak256(bytes)"), + SolidityFunction("sha256()"), + SolidityFunction("sha256(bytes)"), + SolidityFunction("ripemd160()"), + SolidityFunction("ripemd160(bytes)"), + SolidityFunction("ecrecover(bytes32,uint8,bytes32,bytes32)"), + SolidityFunction("addmod(uint256,uint256,uint256)"), + SolidityFunction("mulmod(uint256,uint256,uint256)"), +] + + +def _constant_initial_expression(v: Variable) -> bool: + if not v.expression: + return True + + # B b = new B(); b cannot be constant, so filter out and recommend it be immutable + if isinstance(v.expression, CallExpression) and isinstance(v.expression.called, NewContract): + return False + + export = ExportValues(v.expression) + values = export.result() + if not values: + return True + + return all((val in valid_solidity_function or _is_constant_var(val) for val in values)) + + +class UnchangedStateVariables: + """ + Find state variables that could be declared as constant or immutable (not written after deployment). + """ + + def __init__(self, compilation_unit: SlitherCompilationUnit): + self.compilation_unit = compilation_unit + self._constant_candidates: List[StateVariable] = [] + self._immutable_candidates: List[StateVariable] = [] + + @property + def immutable_candidates(self) -> List[StateVariable]: + """Return the immutable candidates""" + return self._immutable_candidates + + @property + def constant_candidates(self) -> List[StateVariable]: + """Return the constant candidates""" + return self._constant_candidates + + def detect(self): + """Detect state variables that could be constant or immutable""" + for c in self.compilation_unit.contracts_derived: + variables = [] + functions = [] + + variables.append(c.state_variables) + functions.append(c.all_functions_called) + + valid_candidates: Set[StateVariable] = { + item for sublist in variables for item in sublist if _valid_candidate(item) + } + + all_functions: List[Function] = list( + {item1 for sublist in functions for item1 in sublist if isinstance(item1, Function)} + ) + + variables_written = [] + constructor_variables_written = [] + variables_initialized = [] + for f in all_functions: + if f.is_constructor_variables: + variables_initialized.extend(f.state_variables_written) + elif f.is_constructor: + constructor_variables_written.extend(f.state_variables_written) + else: + variables_written.extend(f.state_variables_written) + + for v in valid_candidates: + if v not in variables_written: + if _constant_initial_expression(v) and v not in constructor_variables_written: + self.constant_candidates.append(v) + + elif ( + v in constructor_variables_written or v in variables_initialized + ) and self.compilation_unit.solc_version >= "0.6.5": + self.immutable_candidates.append(v) diff --git a/slither/formatters/variables/possible_const_state_variables.py b/slither/formatters/variables/unchanged_state_variables.py similarity index 94% rename from slither/formatters/variables/possible_const_state_variables.py rename to slither/formatters/variables/unchanged_state_variables.py index 88f92b841..c7c8bf003 100644 --- a/slither/formatters/variables/possible_const_state_variables.py +++ b/slither/formatters/variables/unchanged_state_variables.py @@ -5,7 +5,7 @@ from slither.formatters.exceptions import FormatError, FormatImpossible from slither.formatters.utils.patches import create_patch -def custom_format(compilation_unit: SlitherCompilationUnit, result): +def custom_format(compilation_unit: SlitherCompilationUnit, result, attribute: str) -> None: elements = result["elements"] for element in elements: @@ -15,14 +15,14 @@ def custom_format(compilation_unit: SlitherCompilationUnit, result): contract = scope.get_contract_from_name(contract_name) var = contract.get_state_variable_from_name(element["name"]) if not var.expression: - raise FormatImpossible(f"{var.name} is uninitialized and cannot become constant.") + raise FormatImpossible(f"{var.name} is uninitialized and cannot become {attribute}.") _patch( compilation_unit, result, element["source_mapping"]["filename_absolute"], element["name"], - "constant " + element["name"], + f"{attribute} " + element["name"], element["source_mapping"]["start"], element["source_mapping"]["start"] + element["source_mapping"]["length"], ) diff --git a/slither/tools/slither_format/slither_format.py b/slither/tools/slither_format/slither_format.py index c165b3fbb..3c37313fd 100644 --- a/slither/tools/slither_format/slither_format.py +++ b/slither/tools/slither_format/slither_format.py @@ -9,7 +9,8 @@ from slither.detectors.attributes.incorrect_solc import IncorrectSolc from slither.detectors.attributes.constant_pragma import ConstantPragma from slither.detectors.naming_convention.naming_convention import NamingConvention from slither.detectors.functions.external_function import ExternalFunction -from slither.detectors.variables.possible_const_state_variables import ConstCandidateStateVars +from slither.detectors.variables.could_be_constant import CouldBeConstant +from slither.detectors.variables.could_be_immutable import CouldBeImmutable from slither.detectors.attributes.const_functions_asm import ConstantFunctionsAsm from slither.detectors.attributes.const_functions_state import ConstantFunctionsState from slither.utils.colors import yellow @@ -23,7 +24,8 @@ all_detectors: Dict[str, Type[AbstractDetector]] = { "pragma": ConstantPragma, "naming-convention": NamingConvention, "external-function": ExternalFunction, - "constable-states": ConstCandidateStateVars, + "constable-states": CouldBeConstant, + "immutable-states": CouldBeImmutable, "constant-function-asm": ConstantFunctionsAsm, "constant-functions-state": ConstantFunctionsState, } diff --git a/tests/detectors/constable-states/0.4.25/const_state_variables.sol b/tests/detectors/constable-states/0.4.25/const_state_variables.sol index aed05d97f..45f8cc87a 100644 --- a/tests/detectors/constable-states/0.4.25/const_state_variables.sol +++ b/tests/detectors/constable-states/0.4.25/const_state_variables.sol @@ -44,7 +44,12 @@ contract MyConc{ address not_constant = msg.sender; uint not_constant_2 = getNumber(); uint not_constant_3 = 10 + block.number; + uint not_constant_5; + constructor(uint b) public { + not_constant_5 = b; + } + function getNumber() public returns(uint){ return block.number; } diff --git a/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.CouldBeConstant.json similarity index 96% rename from tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.ConstCandidateStateVars.json rename to tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.CouldBeConstant.json index a46384f06..c7e1f5b43 100644 --- a/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.ConstCandidateStateVars.json +++ b/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.CouldBeConstant.json @@ -212,7 +212,7 @@ "name": "MyConc", "source_mapping": { "start": 746, - "length": 342, + "length": 416, "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", @@ -231,7 +231,12 @@ 49, 50, 51, - 52 + 52, + 53, + 54, + 55, + 56, + 57 ], "starting_column": 1, "ending_column": 2 @@ -272,7 +277,7 @@ "name": "MyConc", "source_mapping": { "start": 746, - "length": 342, + "length": 416, "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", @@ -291,7 +296,12 @@ 49, 50, 51, - 52 + 52, + 53, + 54, + 55, + 56, + 57 ], "starting_column": 1, "ending_column": 2 diff --git a/tests/detectors/constable-states/0.5.16/const_state_variables.sol b/tests/detectors/constable-states/0.5.16/const_state_variables.sol index 7d018ca2d..8fd1ca808 100644 --- a/tests/detectors/constable-states/0.5.16/const_state_variables.sol +++ b/tests/detectors/constable-states/0.5.16/const_state_variables.sol @@ -45,7 +45,12 @@ contract MyConc{ address not_constant = msg.sender; uint not_constant_2 = getNumber(); uint not_constant_3 = 10 + block.number; + uint not_constant_5; + constructor(uint b) public { + not_constant_5 = b; + } + function getNumber() public returns(uint){ return block.number; } diff --git a/tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.CouldBeConstant.json similarity index 96% rename from tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.ConstCandidateStateVars.json rename to tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.CouldBeConstant.json index 36de0ff0b..f9ed17eb1 100644 --- a/tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.ConstCandidateStateVars.json +++ b/tests/detectors/constable-states/0.5.16/const_state_variables.sol.0.5.16.CouldBeConstant.json @@ -24,7 +24,7 @@ "name": "MyConc", "source_mapping": { "start": 746, - "length": 386, + "length": 467, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", @@ -44,7 +44,12 @@ 50, 51, 52, - 53 + 53, + 54, + 55, + 56, + 57, + 58 ], "starting_column": 1, "ending_column": 2 @@ -273,7 +278,7 @@ "name": "MyConc", "source_mapping": { "start": 746, - "length": 386, + "length": 467, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", @@ -293,7 +298,12 @@ 50, 51, 52, - 53 + 53, + 54, + 55, + 56, + 57, + 58 ], "starting_column": 1, "ending_column": 2 @@ -334,7 +344,7 @@ "name": "MyConc", "source_mapping": { "start": 746, - "length": 386, + "length": 467, "filename_relative": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.5.16/const_state_variables.sol", @@ -354,7 +364,12 @@ 50, 51, 52, - 53 + 53, + 54, + 55, + 56, + 57, + 58 ], "starting_column": 1, "ending_column": 2 diff --git a/tests/detectors/constable-states/0.6.11/const_state_variables.sol b/tests/detectors/constable-states/0.6.11/const_state_variables.sol index 66415fd9d..17548f46f 100644 --- a/tests/detectors/constable-states/0.6.11/const_state_variables.sol +++ b/tests/detectors/constable-states/0.6.11/const_state_variables.sol @@ -34,19 +34,46 @@ contract B is A { } } -contract MyConc { +contract Bad { uint constant A = 1; bytes32 should_be_constant = sha256('abc'); uint should_be_constant_2 = A + 1; B should_be_constant_3 = B(address(0)); - address not_constant = msg.sender; - uint not_constant_2 = getNumber(); - uint not_constant_3 = 10 + block.number; - B not_constant_4 = new B(); + address should_be_immutable = msg.sender; + uint should_be_immutable_2 = getNumber(); + uint should_be_immutable_3 = 10 + block.number; + B should_be_immutable_4 = new B(); + uint should_be_immutable_5; + + constructor(uint b) public { + should_be_immutable_5 = b; + } function getNumber() public returns(uint){ return block.number; } } + +contract Good { + + uint constant A = 1; + bytes32 constant should_be_constant = sha256('abc'); + uint constant should_be_constant_2 = A + 1; + B constant should_be_constant_3 = B(address(0)); + address immutable should_be_immutable = msg.sender; + uint immutable should_be_immutable_2 = getNumber(); + uint immutable should_be_immutable_3 = 10 + block.number; + B immutable should_be_immutable_4 = new B(); + uint immutable should_be_immutable_5; + + constructor(uint b) public { + should_be_immutable_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } + +} \ No newline at end of file diff --git a/tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.CouldBeConstant.json similarity index 89% rename from tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.ConstCandidateStateVars.json rename to tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.CouldBeConstant.json index cbb8ecbc1..ac3608f81 100644 --- a/tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.ConstCandidateStateVars.json +++ b/tests/detectors/constable-states/0.6.11/const_state_variables.sol.0.6.11.CouldBeConstant.json @@ -4,48 +4,50 @@ "elements": [ { "type": "variable", - "name": "should_be_constant_3", + "name": "text2", "source_mapping": { - "start": 853, - "length": 38, + "start": 305, + "length": 20, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 42 + 12 ], "starting_column": 5, - "ending_column": 43 + "ending_column": 25 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "A", "source_mapping": { - "start": 718, - "length": 415, + "start": 1, + "length": 441, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19 ], "starting_column": 1, "ending_column": 2 @@ -54,10 +56,10 @@ } } ], - "description": "MyConc.should_be_constant_3 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#42) should be constant \n", - "markdown": "[MyConc.should_be_constant_3](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L42) should be constant \n", - "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L42", - "id": "29247b0a9939e854ad51bf3b2f58705156aa8b7e446e646b1832467d362b5b3e", + "description": "A.text2 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#12) should be constant \n", + "markdown": "[A.text2](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L12) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L12", + "id": "2f06e04545cea7e7a8998c65d5419f335bf2579a6ce6a832eac9c87392fd5c1a", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -66,50 +68,53 @@ "elements": [ { "type": "variable", - "name": "text2", + "name": "should_be_constant_2", "source_mapping": { - "start": 305, - "length": 20, + "start": 811, + "length": 33, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 12 + 41 ], "starting_column": 5, - "ending_column": 25 + "ending_column": 38 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "A", + "name": "Bad", "source_mapping": { - "start": 1, - "length": 441, + "start": 718, + "length": 539, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19 + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57 ], "starting_column": 1, "ending_column": 2 @@ -118,10 +123,10 @@ } } ], - "description": "A.text2 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#12) should be constant \n", - "markdown": "[A.text2](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L12) should be constant \n", - "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L12", - "id": "2f06e04545cea7e7a8998c65d5419f335bf2579a6ce6a832eac9c87392fd5c1a", + "description": "Bad.should_be_constant_2 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#41) should be constant \n", + "markdown": "[Bad.should_be_constant_2](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L41) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L41", + "id": "3a8b682f7960750cd8228d6cd3d0bb5d7d6f9faaf1a044de2fa7069d8e475af2", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -256,7 +261,7 @@ "type": "variable", "name": "should_be_constant", "source_mapping": { - "start": 766, + "start": 763, "length": 42, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", @@ -271,10 +276,10 @@ "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "Bad", "source_mapping": { "start": 718, - "length": 415, + "length": 539, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", @@ -295,7 +300,12 @@ 49, 50, 51, - 52 + 52, + 53, + 54, + 55, + 56, + 57 ], "starting_column": 1, "ending_column": 2 @@ -304,10 +314,10 @@ } } ], - "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.6.11/const_state_variables.sol#40) should be constant \n", - "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L40) should be constant \n", + "description": "Bad.should_be_constant (tests/detectors/constable-states/0.6.11/const_state_variables.sol#40) should be constant \n", + "markdown": "[Bad.should_be_constant](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L40) should be constant \n", "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L40", - "id": "8d08797efc8230b480ec669c7e2bf53c3b3d16bc59bf7770934b34fd892934f8", + "id": "87097c03d57b72ad7c15336eb44e5a30054c50f8daff32e08bc4fbd97852961c", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -316,27 +326,27 @@ "elements": [ { "type": "variable", - "name": "should_be_constant_2", + "name": "should_be_constant_3", "source_mapping": { - "start": 814, - "length": 33, + "start": 850, + "length": 38, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "is_dependency": false, "lines": [ - 41 + 42 ], "starting_column": 5, - "ending_column": 38 + "ending_column": 43 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "Bad", "source_mapping": { "start": 718, - "length": 415, + "length": 539, "filename_relative": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.6.11/const_state_variables.sol", @@ -357,7 +367,12 @@ 49, 50, 51, - 52 + 52, + 53, + 54, + 55, + 56, + 57 ], "starting_column": 1, "ending_column": 2 @@ -366,10 +381,10 @@ } } ], - "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#41) should be constant \n", - "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L41) should be constant \n", - "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L41", - "id": "d08c6d1e331083b42c45c222691dd1e6d880814c66d114971875337ca61ba9c9", + "description": "Bad.should_be_constant_3 (tests/detectors/constable-states/0.6.11/const_state_variables.sol#42) should be constant \n", + "markdown": "[Bad.should_be_constant_3](tests/detectors/constable-states/0.6.11/const_state_variables.sol#L42) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.6.11/const_state_variables.sol#L42", + "id": "8e991c1370b1adb10f01f2d7e48f341dee92a98b91b56ccb291d9149d2da97d0", "check": "constable-states", "impact": "Optimization", "confidence": "High" diff --git a/tests/detectors/constable-states/0.7.6/const_state_variables.sol b/tests/detectors/constable-states/0.7.6/const_state_variables.sol index 93292dc47..297dd6294 100644 --- a/tests/detectors/constable-states/0.7.6/const_state_variables.sol +++ b/tests/detectors/constable-states/0.7.6/const_state_variables.sol @@ -34,7 +34,7 @@ contract B is A { } } -contract MyConc { +contract Bad { uint constant A = 1; bytes32 should_be_constant = sha256('abc'); @@ -44,6 +44,32 @@ contract MyConc { uint should_be_immutable_2 = getNumber(); uint should_be_immutable_3 = 10 + block.number; B should_be_immutable_4 = new B(); + uint should_be_immutable_5; + + constructor(uint b) { + should_be_immutable_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } +} + +contract Good { + + uint constant A = 1; + bytes32 constant should_be_constant = sha256('abc'); + uint constant should_be_constant_2 = A + 1; + B constant should_be_constant_3 = B(address(0)); + address immutable should_be_immutable = msg.sender; + uint immutable should_be_immutable_2 = getNumber(); + uint immutable should_be_immutable_3 = 10 + block.number; + B immutable should_be_immutable_4 = new B(); + uint immutable should_be_immutable_5; + + constructor(uint b) { + should_be_immutable_5 = b; + } function getNumber() public returns(uint){ return block.number; diff --git a/tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.CouldBeConstant.json similarity index 58% rename from tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.ConstCandidateStateVars.json rename to tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.CouldBeConstant.json index 18c869d56..d54beb405 100644 --- a/tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.ConstCandidateStateVars.json +++ b/tests/detectors/constable-states/0.7.6/const_state_variables.sol.0.7.6.CouldBeConstant.json @@ -1,67 +1,5 @@ [ [ - { - "elements": [ - { - "type": "variable", - "name": "should_be_constant_3", - "source_mapping": { - "start": 853, - "length": 38, - "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 42 - ], - "starting_column": 5, - "ending_column": 43 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "MyConc", - "source_mapping": { - "start": 718, - "length": 443, - "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 - ], - "starting_column": 1, - "ending_column": 2 - } - } - } - } - ], - "description": "MyConc.should_be_constant_3 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#42) should be constant \n", - "markdown": "[MyConc.should_be_constant_3](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L42) should be constant \n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L42", - "id": "29247b0a9939e854ad51bf3b2f58705156aa8b7e446e646b1832467d362b5b3e", - "check": "constable-states", - "impact": "Optimization", - "confidence": "High" - }, { "elements": [ { @@ -130,46 +68,52 @@ "elements": [ { "type": "variable", - "name": "mySistersAddress", + "name": "should_be_constant_2", "source_mapping": { - "start": 468, - "length": 76, + "start": 811, + "length": 33, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 24 + 41 ], "starting_column": 5, - "ending_column": 81 + "ending_column": 38 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "B", + "name": "Bad", "source_mapping": { - "start": 445, - "length": 271, + "start": 718, + "length": 531, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35 + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 ], "starting_column": 1, "ending_column": 2 @@ -178,10 +122,10 @@ } } ], - "description": "B.mySistersAddress (tests/detectors/constable-states/0.7.6/const_state_variables.sol#24) should be constant \n", - "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L24) should be constant \n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L24", - "id": "3b5bff93954a48a79387e7981e8c45d78edc575a0988a10f1c7f439b9f930539", + "description": "Bad.should_be_constant_2 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#41) should be constant \n", + "markdown": "[Bad.should_be_constant_2](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L41) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L41", + "id": "3a8b682f7960750cd8228d6cd3d0bb5d7d6f9faaf1a044de2fa7069d8e475af2", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -190,48 +134,46 @@ "elements": [ { "type": "variable", - "name": "should_be_immutable", + "name": "mySistersAddress", "source_mapping": { - "start": 897, - "length": 40, + "start": 468, + "length": 76, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 43 + 24 ], "starting_column": 5, - "ending_column": 45 + "ending_column": 81 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "B", "source_mapping": { - "start": 718, - "length": 443, + "start": 445, + "length": 271, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35 ], "starting_column": 1, "ending_column": 2 @@ -240,10 +182,10 @@ } } ], - "description": "MyConc.should_be_immutable (tests/detectors/constable-states/0.7.6/const_state_variables.sol#43) should be immutable \n", - "markdown": "[MyConc.should_be_immutable](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L43) should be immutable \n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L43", - "id": "3cabd54a4d3fa32f960965a41bb09b62052286195b47b2b7db670f87e8df21bf", + "description": "B.mySistersAddress (tests/detectors/constable-states/0.7.6/const_state_variables.sol#24) should be constant \n", + "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L24) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L24", + "id": "3b5bff93954a48a79387e7981e8c45d78edc575a0988a10f1c7f439b9f930539", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -318,7 +260,7 @@ "type": "variable", "name": "should_be_constant", "source_mapping": { - "start": 766, + "start": 763, "length": 42, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", @@ -333,10 +275,10 @@ "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "Bad", "source_mapping": { "start": 718, - "length": 443, + "length": 531, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", @@ -357,7 +299,11 @@ 49, 50, 51, - 52 + 52, + 53, + 54, + 55, + 56 ], "starting_column": 1, "ending_column": 2 @@ -366,72 +312,10 @@ } } ], - "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.7.6/const_state_variables.sol#40) should be constant \n", - "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L40) should be constant \n", + "description": "Bad.should_be_constant (tests/detectors/constable-states/0.7.6/const_state_variables.sol#40) should be constant \n", + "markdown": "[Bad.should_be_constant](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L40) should be constant \n", "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L40", - "id": "8d08797efc8230b480ec669c7e2bf53c3b3d16bc59bf7770934b34fd892934f8", - "check": "constable-states", - "impact": "Optimization", - "confidence": "High" - }, - { - "elements": [ - { - "type": "variable", - "name": "should_be_immutable_4", - "source_mapping": { - "start": 1041, - "length": 33, - "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 46 - ], - "starting_column": 5, - "ending_column": 38 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "MyConc", - "source_mapping": { - "start": 718, - "length": 443, - "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 - ], - "starting_column": 1, - "ending_column": 2 - } - } - } - } - ], - "description": "MyConc.should_be_immutable_4 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#46) should be immutable \n", - "markdown": "[MyConc.should_be_immutable_4](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L46) should be immutable \n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L46", - "id": "a15e34bd516e604d7ba3e0746ad0234d0baea38da2e747648316d5d15ee9b3bc", + "id": "87097c03d57b72ad7c15336eb44e5a30054c50f8daff32e08bc4fbd97852961c", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -440,151 +324,27 @@ "elements": [ { "type": "variable", - "name": "should_be_immutable_2", - "source_mapping": { - "start": 943, - "length": 40, - "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 44 - ], - "starting_column": 5, - "ending_column": 45 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "MyConc", - "source_mapping": { - "start": 718, - "length": 443, - "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 - ], - "starting_column": 1, - "ending_column": 2 - } - } - } - } - ], - "description": "MyConc.should_be_immutable_2 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#44) should be immutable \n", - "markdown": "[MyConc.should_be_immutable_2](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L44) should be immutable \n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L44", - "id": "cb6df1f1ce2f32505c81f257863ceef6d5145ee5a2835af1c6719ad695d145e2", - "check": "constable-states", - "impact": "Optimization", - "confidence": "High" - }, - { - "elements": [ - { - "type": "variable", - "name": "should_be_constant_2", - "source_mapping": { - "start": 814, - "length": 33, - "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 41 - ], - "starting_column": 5, - "ending_column": 38 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "MyConc", - "source_mapping": { - "start": 718, - "length": 443, - "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 - ], - "starting_column": 1, - "ending_column": 2 - } - } - } - } - ], - "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#41) should be constant \n", - "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L41) should be constant \n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L41", - "id": "d08c6d1e331083b42c45c222691dd1e6d880814c66d114971875337ca61ba9c9", - "check": "constable-states", - "impact": "Optimization", - "confidence": "High" - }, - { - "elements": [ - { - "type": "variable", - "name": "should_be_immutable_3", + "name": "should_be_constant_3", "source_mapping": { - "start": 989, - "length": 46, + "start": 850, + "length": 38, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "is_dependency": false, "lines": [ - 45 + 42 ], "starting_column": 5, - "ending_column": 51 + "ending_column": 43 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "Bad", "source_mapping": { "start": 718, - "length": 443, + "length": 531, "filename_relative": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.7.6/const_state_variables.sol", @@ -605,7 +365,11 @@ 49, 50, 51, - 52 + 52, + 53, + 54, + 55, + 56 ], "starting_column": 1, "ending_column": 2 @@ -614,10 +378,10 @@ } } ], - "description": "MyConc.should_be_immutable_3 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#45) should be immutable \n", - "markdown": "[MyConc.should_be_immutable_3](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L45) should be immutable \n", - "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L45", - "id": "dc5903ef8f6ec62f53df486fa768a0d817643efe30c90c1308079eee99c316d4", + "description": "Bad.should_be_constant_3 (tests/detectors/constable-states/0.7.6/const_state_variables.sol#42) should be constant \n", + "markdown": "[Bad.should_be_constant_3](tests/detectors/constable-states/0.7.6/const_state_variables.sol#L42) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.7.6/const_state_variables.sol#L42", + "id": "8e991c1370b1adb10f01f2d7e48f341dee92a98b91b56ccb291d9149d2da97d0", "check": "constable-states", "impact": "Optimization", "confidence": "High" diff --git a/tests/detectors/constable-states/0.8.0/const_state_variables.sol b/tests/detectors/constable-states/0.8.0/const_state_variables.sol index 93292dc47..f405a1587 100644 --- a/tests/detectors/constable-states/0.8.0/const_state_variables.sol +++ b/tests/detectors/constable-states/0.8.0/const_state_variables.sol @@ -34,7 +34,7 @@ contract B is A { } } -contract MyConc { +contract Bad { uint constant A = 1; bytes32 should_be_constant = sha256('abc'); @@ -43,10 +43,36 @@ contract MyConc { address should_be_immutable = msg.sender; uint should_be_immutable_2 = getNumber(); uint should_be_immutable_3 = 10 + block.number; - B should_be_immutable_4 = new B(); + uint should_be_immutable_5; + + constructor(uint b) { + should_be_immutable_5 = b; + } function getNumber() public returns(uint){ return block.number; } } + +contract Good { + + uint constant A = 1; + bytes32 constant should_be_constant = sha256('abc'); + uint constant should_be_constant_2 = A + 1; + B constant should_be_constant_3 = B(address(0)); + address immutable should_be_immutable = msg.sender; + uint immutable should_be_immutable_2 = getNumber(); + uint immutable should_be_immutable_3 = 10 + block.number; + B immutable should_be_immutable_4 = new B(); + uint immutable should_be_immutable_5; + + constructor(uint b) { + should_be_immutable_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } + +} \ No newline at end of file diff --git a/tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.ConstCandidateStateVars.json b/tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.CouldBeConstant.json similarity index 58% rename from tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.ConstCandidateStateVars.json rename to tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.CouldBeConstant.json index e36a2988d..7febfd637 100644 --- a/tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.ConstCandidateStateVars.json +++ b/tests/detectors/constable-states/0.8.0/const_state_variables.sol.0.8.0.CouldBeConstant.json @@ -1,67 +1,5 @@ [ [ - { - "elements": [ - { - "type": "variable", - "name": "should_be_constant_3", - "source_mapping": { - "start": 853, - "length": 38, - "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 42 - ], - "starting_column": 5, - "ending_column": 43 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "MyConc", - "source_mapping": { - "start": 718, - "length": 443, - "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 - ], - "starting_column": 1, - "ending_column": 2 - } - } - } - } - ], - "description": "MyConc.should_be_constant_3 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#42) should be constant \n", - "markdown": "[MyConc.should_be_constant_3](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L42) should be constant \n", - "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L42", - "id": "29247b0a9939e854ad51bf3b2f58705156aa8b7e446e646b1832467d362b5b3e", - "check": "constable-states", - "impact": "Optimization", - "confidence": "High" - }, { "elements": [ { @@ -130,46 +68,52 @@ "elements": [ { "type": "variable", - "name": "mySistersAddress", + "name": "should_be_constant_2", "source_mapping": { - "start": 468, - "length": 76, + "start": 811, + "length": 33, "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "is_dependency": false, "lines": [ - 24 + 41 ], "starting_column": 5, - "ending_column": 81 + "ending_column": 38 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "B", + "name": "Bad", "source_mapping": { - "start": 445, - "length": 271, + "start": 718, + "length": 493, "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "is_dependency": false, "lines": [ - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35 + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 ], "starting_column": 1, "ending_column": 2 @@ -178,10 +122,10 @@ } } ], - "description": "B.mySistersAddress (tests/detectors/constable-states/0.8.0/const_state_variables.sol#24) should be constant \n", - "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L24) should be constant \n", - "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L24", - "id": "3b5bff93954a48a79387e7981e8c45d78edc575a0988a10f1c7f439b9f930539", + "description": "Bad.should_be_constant_2 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#41) should be constant \n", + "markdown": "[Bad.should_be_constant_2](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L41) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L41", + "id": "3a8b682f7960750cd8228d6cd3d0bb5d7d6f9faaf1a044de2fa7069d8e475af2", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -190,48 +134,46 @@ "elements": [ { "type": "variable", - "name": "should_be_immutable", + "name": "mySistersAddress", "source_mapping": { - "start": 897, - "length": 40, + "start": 468, + "length": 76, "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "is_dependency": false, "lines": [ - 43 + 24 ], "starting_column": 5, - "ending_column": 45 + "ending_column": 81 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "B", "source_mapping": { - "start": 718, - "length": 443, + "start": 445, + "length": 271, "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "is_dependency": false, "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35 ], "starting_column": 1, "ending_column": 2 @@ -240,10 +182,10 @@ } } ], - "description": "MyConc.should_be_immutable (tests/detectors/constable-states/0.8.0/const_state_variables.sol#43) should be immutable \n", - "markdown": "[MyConc.should_be_immutable](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L43) should be immutable \n", - "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L43", - "id": "3cabd54a4d3fa32f960965a41bb09b62052286195b47b2b7db670f87e8df21bf", + "description": "B.mySistersAddress (tests/detectors/constable-states/0.8.0/const_state_variables.sol#24) should be constant \n", + "markdown": "[B.mySistersAddress](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L24) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L24", + "id": "3b5bff93954a48a79387e7981e8c45d78edc575a0988a10f1c7f439b9f930539", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -318,7 +260,7 @@ "type": "variable", "name": "should_be_constant", "source_mapping": { - "start": 766, + "start": 763, "length": 42, "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", @@ -333,10 +275,10 @@ "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "Bad", "source_mapping": { "start": 718, - "length": 443, + "length": 493, "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", @@ -357,7 +299,11 @@ 49, 50, 51, - 52 + 52, + 53, + 54, + 55, + 56 ], "starting_column": 1, "ending_column": 2 @@ -366,72 +312,10 @@ } } ], - "description": "MyConc.should_be_constant (tests/detectors/constable-states/0.8.0/const_state_variables.sol#40) should be constant \n", - "markdown": "[MyConc.should_be_constant](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L40) should be constant \n", + "description": "Bad.should_be_constant (tests/detectors/constable-states/0.8.0/const_state_variables.sol#40) should be constant \n", + "markdown": "[Bad.should_be_constant](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L40) should be constant \n", "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L40", - "id": "8d08797efc8230b480ec669c7e2bf53c3b3d16bc59bf7770934b34fd892934f8", - "check": "constable-states", - "impact": "Optimization", - "confidence": "High" - }, - { - "elements": [ - { - "type": "variable", - "name": "should_be_immutable_4", - "source_mapping": { - "start": 1041, - "length": 33, - "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 46 - ], - "starting_column": 5, - "ending_column": 38 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "MyConc", - "source_mapping": { - "start": 718, - "length": 443, - "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 - ], - "starting_column": 1, - "ending_column": 2 - } - } - } - } - ], - "description": "MyConc.should_be_immutable_4 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#46) should be immutable \n", - "markdown": "[MyConc.should_be_immutable_4](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L46) should be immutable \n", - "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L46", - "id": "a15e34bd516e604d7ba3e0746ad0234d0baea38da2e747648316d5d15ee9b3bc", + "id": "87097c03d57b72ad7c15336eb44e5a30054c50f8daff32e08bc4fbd97852961c", "check": "constable-states", "impact": "Optimization", "confidence": "High" @@ -440,151 +324,27 @@ "elements": [ { "type": "variable", - "name": "should_be_immutable_2", - "source_mapping": { - "start": 943, - "length": 40, - "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 44 - ], - "starting_column": 5, - "ending_column": 45 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "MyConc", - "source_mapping": { - "start": 718, - "length": 443, - "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 - ], - "starting_column": 1, - "ending_column": 2 - } - } - } - } - ], - "description": "MyConc.should_be_immutable_2 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#44) should be immutable \n", - "markdown": "[MyConc.should_be_immutable_2](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L44) should be immutable \n", - "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L44", - "id": "cb6df1f1ce2f32505c81f257863ceef6d5145ee5a2835af1c6719ad695d145e2", - "check": "constable-states", - "impact": "Optimization", - "confidence": "High" - }, - { - "elements": [ - { - "type": "variable", - "name": "should_be_constant_2", - "source_mapping": { - "start": 814, - "length": 33, - "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 41 - ], - "starting_column": 5, - "ending_column": 38 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "MyConc", - "source_mapping": { - "start": 718, - "length": 443, - "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "filename_absolute": "/GENERIC_PATH", - "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", - "is_dependency": false, - "lines": [ - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52 - ], - "starting_column": 1, - "ending_column": 2 - } - } - } - } - ], - "description": "MyConc.should_be_constant_2 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#41) should be constant \n", - "markdown": "[MyConc.should_be_constant_2](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L41) should be constant \n", - "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L41", - "id": "d08c6d1e331083b42c45c222691dd1e6d880814c66d114971875337ca61ba9c9", - "check": "constable-states", - "impact": "Optimization", - "confidence": "High" - }, - { - "elements": [ - { - "type": "variable", - "name": "should_be_immutable_3", + "name": "should_be_constant_3", "source_mapping": { - "start": 989, - "length": 46, + "start": 850, + "length": 38, "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "is_dependency": false, "lines": [ - 45 + 42 ], "starting_column": 5, - "ending_column": 51 + "ending_column": 43 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "MyConc", + "name": "Bad", "source_mapping": { "start": 718, - "length": 443, + "length": 493, "filename_relative": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.8.0/const_state_variables.sol", @@ -605,7 +365,11 @@ 49, 50, 51, - 52 + 52, + 53, + 54, + 55, + 56 ], "starting_column": 1, "ending_column": 2 @@ -614,10 +378,10 @@ } } ], - "description": "MyConc.should_be_immutable_3 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#45) should be immutable \n", - "markdown": "[MyConc.should_be_immutable_3](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L45) should be immutable \n", - "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L45", - "id": "dc5903ef8f6ec62f53df486fa768a0d817643efe30c90c1308079eee99c316d4", + "description": "Bad.should_be_constant_3 (tests/detectors/constable-states/0.8.0/const_state_variables.sol#42) should be constant \n", + "markdown": "[Bad.should_be_constant_3](tests/detectors/constable-states/0.8.0/const_state_variables.sol#L42) should be constant \n", + "first_markdown_element": "tests/detectors/constable-states/0.8.0/const_state_variables.sol#L42", + "id": "8e991c1370b1adb10f01f2d7e48f341dee92a98b91b56ccb291d9149d2da97d0", "check": "constable-states", "impact": "Optimization", "confidence": "High" diff --git a/tests/detectors/immutable-states/0.4.25/immut_state_variables.sol b/tests/detectors/immutable-states/0.4.25/immut_state_variables.sol new file mode 100644 index 000000000..45f8cc87a --- /dev/null +++ b/tests/detectors/immutable-states/0.4.25/immut_state_variables.sol @@ -0,0 +1,57 @@ +//pragma solidity ^0.4.24; + + +contract A { + + address constant public MY_ADDRESS = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9; + address public myFriendsAddress = 0xc0ffee254729296a45a3885639AC7E10F9d54979; + + uint public used; + uint public test = 5; + + uint constant X = 32**22 + 8; + string constant TEXT1 = "abc"; + string text2 = "xyz"; + + function setUsed() public { + if (msg.sender == MY_ADDRESS) { + used = test; + } + } +} + + +contract B is A { + + address public mySistersAddress = 0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E; + + function () external { + used = 0; + } + + function setUsed(uint a) public { + if (msg.sender == MY_ADDRESS) { + used = a; + } + } +} + +contract MyConc{ + + uint constant A = 1; + bytes32 should_be_constant = sha256('abc'); + uint should_be_constant_2 = A + 1; + address not_constant = msg.sender; + uint not_constant_2 = getNumber(); + uint not_constant_3 = 10 + block.number; + uint not_constant_5; + + constructor(uint b) public { + not_constant_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } + +} diff --git a/tests/detectors/immutable-states/0.4.25/immut_state_variables.sol.0.4.25.CouldBeImmutable.json b/tests/detectors/immutable-states/0.4.25/immut_state_variables.sol.0.4.25.CouldBeImmutable.json new file mode 100644 index 000000000..5825bcacc --- /dev/null +++ b/tests/detectors/immutable-states/0.4.25/immut_state_variables.sol.0.4.25.CouldBeImmutable.json @@ -0,0 +1,3 @@ +[ + [] +] \ No newline at end of file diff --git a/tests/detectors/immutable-states/0.5.16/immut_state_variables.sol b/tests/detectors/immutable-states/0.5.16/immut_state_variables.sol new file mode 100644 index 000000000..8fd1ca808 --- /dev/null +++ b/tests/detectors/immutable-states/0.5.16/immut_state_variables.sol @@ -0,0 +1,58 @@ +//pragma solidity ^0.4.24; + + +contract A { + + address constant public MY_ADDRESS = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9; + address public myFriendsAddress = 0xc0ffee254729296a45a3885639AC7E10F9d54979; + + uint public used; + uint public test = 5; + + uint constant X = 32**22 + 8; + string constant TEXT1 = "abc"; + string text2 = "xyz"; + + function setUsed() public { + if (msg.sender == MY_ADDRESS) { + used = test; + } + } +} + + +contract B is A { + + address public mySistersAddress = 0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E; + + function () external { + used = 0; + } + + function setUsed(uint a) public { + if (msg.sender == MY_ADDRESS) { + used = a; + } + } +} + +contract MyConc{ + + uint constant A = 1; + bytes32 should_be_constant = sha256('abc'); + uint should_be_constant_2 = A + 1; + B should_be_constant_3 = B(address(0)); + address not_constant = msg.sender; + uint not_constant_2 = getNumber(); + uint not_constant_3 = 10 + block.number; + uint not_constant_5; + + constructor(uint b) public { + not_constant_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } + +} diff --git a/tests/detectors/immutable-states/0.5.16/immut_state_variables.sol.0.5.16.CouldBeImmutable.json b/tests/detectors/immutable-states/0.5.16/immut_state_variables.sol.0.5.16.CouldBeImmutable.json new file mode 100644 index 000000000..5825bcacc --- /dev/null +++ b/tests/detectors/immutable-states/0.5.16/immut_state_variables.sol.0.5.16.CouldBeImmutable.json @@ -0,0 +1,3 @@ +[ + [] +] \ No newline at end of file diff --git a/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol b/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol new file mode 100644 index 000000000..17548f46f --- /dev/null +++ b/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol @@ -0,0 +1,79 @@ + +contract A { + + address constant public MY_ADDRESS = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9; + address public myFriendsAddress = 0xc0ffee254729296a45a3885639AC7E10F9d54979; + + uint public used; + uint public test = 5; + + uint constant X = 32**22 + 8; + string constant TEXT1 = "abc"; + string text2 = "xyz"; + + function setUsed() public { + if (msg.sender == MY_ADDRESS) { + used = test; + } + } +} + + +contract B is A { + + address public mySistersAddress = 0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E; + + fallback () external { + used = 0; + } + + function setUsed(uint a) public { + if (msg.sender == MY_ADDRESS) { + used = a; + } + } +} + +contract Bad { + + uint constant A = 1; + bytes32 should_be_constant = sha256('abc'); + uint should_be_constant_2 = A + 1; + B should_be_constant_3 = B(address(0)); + address should_be_immutable = msg.sender; + uint should_be_immutable_2 = getNumber(); + uint should_be_immutable_3 = 10 + block.number; + B should_be_immutable_4 = new B(); + uint should_be_immutable_5; + + constructor(uint b) public { + should_be_immutable_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } + +} + +contract Good { + + uint constant A = 1; + bytes32 constant should_be_constant = sha256('abc'); + uint constant should_be_constant_2 = A + 1; + B constant should_be_constant_3 = B(address(0)); + address immutable should_be_immutable = msg.sender; + uint immutable should_be_immutable_2 = getNumber(); + uint immutable should_be_immutable_3 = 10 + block.number; + B immutable should_be_immutable_4 = new B(); + uint immutable should_be_immutable_5; + + constructor(uint b) public { + should_be_immutable_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } + +} \ No newline at end of file diff --git a/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol.0.6.11.CouldBeImmutable.json b/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol.0.6.11.CouldBeImmutable.json new file mode 100644 index 000000000..5825bcacc --- /dev/null +++ b/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol.0.6.11.CouldBeImmutable.json @@ -0,0 +1,3 @@ +[ + [] +] \ No newline at end of file diff --git a/tests/detectors/immutable-states/0.7.6/immut_state_variables.sol b/tests/detectors/immutable-states/0.7.6/immut_state_variables.sol new file mode 100644 index 000000000..297dd6294 --- /dev/null +++ b/tests/detectors/immutable-states/0.7.6/immut_state_variables.sol @@ -0,0 +1,78 @@ + +contract A { + + address constant public MY_ADDRESS = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9; + address public myFriendsAddress = 0xc0ffee254729296a45a3885639AC7E10F9d54979; + + uint public used; + uint public test = 5; + + uint constant X = 32**22 + 8; + string constant TEXT1 = "abc"; + string text2 = "xyz"; + + function setUsed() public { + if (msg.sender == MY_ADDRESS) { + used = test; + } + } +} + + +contract B is A { + + address public mySistersAddress = 0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E; + + fallback () external { + used = 0; + } + + function setUsed(uint a) public { + if (msg.sender == MY_ADDRESS) { + used = a; + } + } +} + +contract Bad { + + uint constant A = 1; + bytes32 should_be_constant = sha256('abc'); + uint should_be_constant_2 = A + 1; + B should_be_constant_3 = B(address(0)); + address should_be_immutable = msg.sender; + uint should_be_immutable_2 = getNumber(); + uint should_be_immutable_3 = 10 + block.number; + B should_be_immutable_4 = new B(); + uint should_be_immutable_5; + + constructor(uint b) { + should_be_immutable_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } +} + +contract Good { + + uint constant A = 1; + bytes32 constant should_be_constant = sha256('abc'); + uint constant should_be_constant_2 = A + 1; + B constant should_be_constant_3 = B(address(0)); + address immutable should_be_immutable = msg.sender; + uint immutable should_be_immutable_2 = getNumber(); + uint immutable should_be_immutable_3 = 10 + block.number; + B immutable should_be_immutable_4 = new B(); + uint immutable should_be_immutable_5; + + constructor(uint b) { + should_be_immutable_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } + +} diff --git a/tests/detectors/immutable-states/0.7.6/immut_state_variables.sol.0.7.6.CouldBeImmutable.json b/tests/detectors/immutable-states/0.7.6/immut_state_variables.sol.0.7.6.CouldBeImmutable.json new file mode 100644 index 000000000..40c8b1368 --- /dev/null +++ b/tests/detectors/immutable-states/0.7.6/immut_state_variables.sol.0.7.6.CouldBeImmutable.json @@ -0,0 +1,334 @@ +[ + [ + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_5", + "source_mapping": { + "start": 1077, + "length": 26, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 47 + ], + "starting_column": 5, + "ending_column": 31 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 531, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_5 (tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#47) should be immutable \n", + "markdown": "[Bad.should_be_immutable_5](tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L47) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L47", + "id": "42d50245236163ceca90dea732165e65c2155934b149a5a1a5c51bddc0b5b02a", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_2", + "source_mapping": { + "start": 940, + "length": 40, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 44 + ], + "starting_column": 5, + "ending_column": 45 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 531, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_2 (tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#44) should be immutable \n", + "markdown": "[Bad.should_be_immutable_2](tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L44) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L44", + "id": "70d57aa51dda92c28444a466db8567fa783c85d484259aa5eee2ebc63f97a200", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_4", + "source_mapping": { + "start": 1038, + "length": 33, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 46 + ], + "starting_column": 5, + "ending_column": 38 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 531, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_4 (tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#46) should be immutable \n", + "markdown": "[Bad.should_be_immutable_4](tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L46) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L46", + "id": "a26d6df4087ac010928bc4bd18aa70ac58a28e584b1288e348d9c255473c300d", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable", + "source_mapping": { + "start": 894, + "length": 40, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 43 + ], + "starting_column": 5, + "ending_column": 45 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 531, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable (tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#43) should be immutable \n", + "markdown": "[Bad.should_be_immutable](tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L43) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L43", + "id": "b163d277f544f7f05ed4bcddda61e444be893e65ba0469688abd7b401a1db222", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_3", + "source_mapping": { + "start": 986, + "length": 46, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 45 + ], + "starting_column": 5, + "ending_column": 51 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 531, + "filename_relative": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_3 (tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#45) should be immutable \n", + "markdown": "[Bad.should_be_immutable_3](tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L45) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.7.6/immut_state_variables.sol#L45", + "id": "f19f7a22a6f17ffd8b5c29021226388aab7548f996b686a8e0b2bc861f72d447", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + } + ] +] \ No newline at end of file diff --git a/tests/detectors/immutable-states/0.8.0/immut_state_variables.sol b/tests/detectors/immutable-states/0.8.0/immut_state_variables.sol new file mode 100644 index 000000000..f405a1587 --- /dev/null +++ b/tests/detectors/immutable-states/0.8.0/immut_state_variables.sol @@ -0,0 +1,78 @@ + +contract A { + + address constant public MY_ADDRESS = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9; + address public myFriendsAddress = 0xc0ffee254729296a45a3885639AC7E10F9d54979; + + uint public used; + uint public test = 5; + + uint constant X = 32**22 + 8; + string constant TEXT1 = "abc"; + string text2 = "xyz"; + + function setUsed() public { + if (msg.sender == MY_ADDRESS) { + used = test; + } + } +} + + +contract B is A { + + address public mySistersAddress = 0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E; + + fallback () external { + used = 0; + } + + function setUsed(uint a) public { + if (msg.sender == MY_ADDRESS) { + used = a; + } + } +} + +contract Bad { + + uint constant A = 1; + bytes32 should_be_constant = sha256('abc'); + uint should_be_constant_2 = A + 1; + B should_be_constant_3 = B(address(0)); + address should_be_immutable = msg.sender; + uint should_be_immutable_2 = getNumber(); + uint should_be_immutable_3 = 10 + block.number; + uint should_be_immutable_5; + + constructor(uint b) { + should_be_immutable_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } + +} + +contract Good { + + uint constant A = 1; + bytes32 constant should_be_constant = sha256('abc'); + uint constant should_be_constant_2 = A + 1; + B constant should_be_constant_3 = B(address(0)); + address immutable should_be_immutable = msg.sender; + uint immutable should_be_immutable_2 = getNumber(); + uint immutable should_be_immutable_3 = 10 + block.number; + B immutable should_be_immutable_4 = new B(); + uint immutable should_be_immutable_5; + + constructor(uint b) { + should_be_immutable_5 = b; + } + + function getNumber() public returns(uint){ + return block.number; + } + +} \ No newline at end of file diff --git a/tests/detectors/immutable-states/0.8.0/immut_state_variables.sol.0.8.0.CouldBeImmutable.json b/tests/detectors/immutable-states/0.8.0/immut_state_variables.sol.0.8.0.CouldBeImmutable.json new file mode 100644 index 000000000..afa2e3bb2 --- /dev/null +++ b/tests/detectors/immutable-states/0.8.0/immut_state_variables.sol.0.8.0.CouldBeImmutable.json @@ -0,0 +1,268 @@ +[ + [ + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_5", + "source_mapping": { + "start": 1038, + "length": 26, + "filename_relative": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 46 + ], + "starting_column": 5, + "ending_column": 31 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 493, + "filename_relative": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_5 (tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#46) should be immutable \n", + "markdown": "[Bad.should_be_immutable_5](tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#L46) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#L46", + "id": "42d50245236163ceca90dea732165e65c2155934b149a5a1a5c51bddc0b5b02a", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_2", + "source_mapping": { + "start": 940, + "length": 40, + "filename_relative": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 44 + ], + "starting_column": 5, + "ending_column": 45 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 493, + "filename_relative": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_2 (tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#44) should be immutable \n", + "markdown": "[Bad.should_be_immutable_2](tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#L44) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#L44", + "id": "70d57aa51dda92c28444a466db8567fa783c85d484259aa5eee2ebc63f97a200", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable", + "source_mapping": { + "start": 894, + "length": 40, + "filename_relative": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 43 + ], + "starting_column": 5, + "ending_column": 45 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 493, + "filename_relative": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable (tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#43) should be immutable \n", + "markdown": "[Bad.should_be_immutable](tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#L43) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#L43", + "id": "b163d277f544f7f05ed4bcddda61e444be893e65ba0469688abd7b401a1db222", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_3", + "source_mapping": { + "start": 986, + "length": 46, + "filename_relative": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 45 + ], + "starting_column": 5, + "ending_column": 51 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 493, + "filename_relative": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_3 (tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#45) should be immutable \n", + "markdown": "[Bad.should_be_immutable_3](tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#L45) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.8.0/immut_state_variables.sol#L45", + "id": "f19f7a22a6f17ffd8b5c29021226388aab7548f996b686a8e0b2bc861f72d447", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + } + ] +] \ No newline at end of file diff --git a/tests/test_detectors.py b/tests/test_detectors.py index 744f75b6c..18f406bf4 100644 --- a/tests/test_detectors.py +++ b/tests/test_detectors.py @@ -480,30 +480,55 @@ ALL_TEST_OBJECTS = [ "0.7.6", ), Test( - all_detectors.ConstCandidateStateVars, + all_detectors.CouldBeConstant, "const_state_variables.sol", "0.4.25", ), Test( - all_detectors.ConstCandidateStateVars, + all_detectors.CouldBeConstant, "const_state_variables.sol", "0.5.16", ), Test( - all_detectors.ConstCandidateStateVars, + all_detectors.CouldBeConstant, "const_state_variables.sol", "0.6.11", ), Test( - all_detectors.ConstCandidateStateVars, + all_detectors.CouldBeConstant, "const_state_variables.sol", "0.7.6", ), Test( - all_detectors.ConstCandidateStateVars, + all_detectors.CouldBeConstant, "const_state_variables.sol", "0.8.0", ), + Test( + all_detectors.CouldBeImmutable, + "immut_state_variables.sol", + "0.4.25", + ), + Test( + all_detectors.CouldBeImmutable, + "immut_state_variables.sol", + "0.5.16", + ), + Test( + all_detectors.CouldBeImmutable, + "immut_state_variables.sol", + "0.6.11", + ), + Test( + all_detectors.CouldBeImmutable, + "immut_state_variables.sol", + "0.7.6", + ), + Test( + all_detectors.CouldBeImmutable, + "immut_state_variables.sol", + "0.8.0", + ), Test( all_detectors.ExternalFunction, "external_function.sol", From 4685eac44f4105ff4d06a42a008dea8548e24704 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 6 Jan 2023 10:32:21 -0600 Subject: [PATCH 48/61] parse semver --- setup.py | 1 + .../variables/unchanged_state_variables.py | 6 +- ...variables.sol.0.6.11.CouldBeImmutable.json | 338 +++++++++++++++++- 3 files changed, 342 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 86db4fa9a..9cfbb29e4 100644 --- a/setup.py +++ b/setup.py @@ -12,6 +12,7 @@ setup( packages=find_packages(), python_requires=">=3.8", install_requires=[ + "packaging", "prettytable>=0.7.2", "pycryptodome>=3.4.6", # "crytic-compile>=0.2.4", diff --git a/slither/detectors/variables/unchanged_state_variables.py b/slither/detectors/variables/unchanged_state_variables.py index 62fc61f43..0dccb6d1c 100644 --- a/slither/detectors/variables/unchanged_state_variables.py +++ b/slither/detectors/variables/unchanged_state_variables.py @@ -2,7 +2,7 @@ Module detecting state variables that could be declared as constant """ from typing import Set, List - +from packaging import version from slither.core.compilation_unit import SlitherCompilationUnit from slither.core.solidity_types.elementary_type import ElementaryType from slither.core.solidity_types.user_defined_type import UserDefinedType @@ -119,5 +119,7 @@ class UnchangedStateVariables: elif ( v in constructor_variables_written or v in variables_initialized - ) and self.compilation_unit.solc_version >= "0.6.5": + ) and version.parse(self.compilation_unit.solc_version) >= version.parse( + "0.6.5" + ): self.immutable_candidates.append(v) diff --git a/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol.0.6.11.CouldBeImmutable.json b/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol.0.6.11.CouldBeImmutable.json index 5825bcacc..15064ca99 100644 --- a/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol.0.6.11.CouldBeImmutable.json +++ b/tests/detectors/immutable-states/0.6.11/immut_state_variables.sol.0.6.11.CouldBeImmutable.json @@ -1,3 +1,339 @@ [ - [] + [ + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_5", + "source_mapping": { + "start": 1077, + "length": 26, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 47 + ], + "starting_column": 5, + "ending_column": 31 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 539, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_5 (tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#47) should be immutable \n", + "markdown": "[Bad.should_be_immutable_5](tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L47) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L47", + "id": "42d50245236163ceca90dea732165e65c2155934b149a5a1a5c51bddc0b5b02a", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_2", + "source_mapping": { + "start": 940, + "length": 40, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 44 + ], + "starting_column": 5, + "ending_column": 45 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 539, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_2 (tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#44) should be immutable \n", + "markdown": "[Bad.should_be_immutable_2](tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L44) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L44", + "id": "70d57aa51dda92c28444a466db8567fa783c85d484259aa5eee2ebc63f97a200", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_4", + "source_mapping": { + "start": 1038, + "length": 33, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 46 + ], + "starting_column": 5, + "ending_column": 38 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 539, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_4 (tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#46) should be immutable \n", + "markdown": "[Bad.should_be_immutable_4](tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L46) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L46", + "id": "a26d6df4087ac010928bc4bd18aa70ac58a28e584b1288e348d9c255473c300d", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable", + "source_mapping": { + "start": 894, + "length": 40, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 43 + ], + "starting_column": 5, + "ending_column": 45 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 539, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable (tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#43) should be immutable \n", + "markdown": "[Bad.should_be_immutable](tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L43) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L43", + "id": "b163d277f544f7f05ed4bcddda61e444be893e65ba0469688abd7b401a1db222", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "should_be_immutable_3", + "source_mapping": { + "start": 986, + "length": 46, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 45 + ], + "starting_column": 5, + "ending_column": 51 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Bad", + "source_mapping": { + "start": 718, + "length": 539, + "filename_relative": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "filename_absolute": "/GENERIC_PATH", + "filename_short": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol", + "is_dependency": false, + "lines": [ + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Bad.should_be_immutable_3 (tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#45) should be immutable \n", + "markdown": "[Bad.should_be_immutable_3](tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L45) should be immutable \n", + "first_markdown_element": "tests/detectors/immutable-states/0.6.11/immut_state_variables.sol#L45", + "id": "f19f7a22a6f17ffd8b5c29021226388aab7548f996b686a8e0b2bc861f72d447", + "check": "immutable-states", + "impact": "Optimization", + "confidence": "High" + } + ] ] \ No newline at end of file From cfb5c4eedb6c452625507e383ede3d1c315a889a Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Fri, 6 Jan 2023 10:41:29 -0600 Subject: [PATCH 49/61] fix artifact --- .../const_state_variables.sol.0.4.25.CouldBeConstant.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.CouldBeConstant.json b/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.CouldBeConstant.json index c7e1f5b43..51a485f5b 100644 --- a/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.CouldBeConstant.json +++ b/tests/detectors/constable-states/0.4.25/const_state_variables.sol.0.4.25.CouldBeConstant.json @@ -212,7 +212,7 @@ "name": "MyConc", "source_mapping": { "start": 746, - "length": 416, + "length": 423, "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", @@ -277,7 +277,7 @@ "name": "MyConc", "source_mapping": { "start": 746, - "length": 416, + "length": 423, "filename_relative": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", "filename_absolute": "/GENERIC_PATH", "filename_short": "tests/detectors/constable-states/0.4.25/const_state_variables.sol", From 55c24280cf6ee2c881dbeb06a726e3a8dfa772ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Fri, 6 Jan 2023 12:36:57 -0300 Subject: [PATCH 50/61] tests: source_unit: remove submodule --- tests/source_unit/README.md | 3 +++ tests/source_unit/lib/forge-std | 1 - tests/test_source_unit.py | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 tests/source_unit/README.md delete mode 160000 tests/source_unit/lib/forge-std diff --git a/tests/source_unit/README.md b/tests/source_unit/README.md new file mode 100644 index 000000000..9cf3657e0 --- /dev/null +++ b/tests/source_unit/README.md @@ -0,0 +1,3 @@ +# README + +Before using this project, run `forge init --no-git --no-commit --force` to initialize submodules diff --git a/tests/source_unit/lib/forge-std b/tests/source_unit/lib/forge-std deleted file mode 160000 index eb980e1d4..000000000 --- a/tests/source_unit/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -Subproject commit eb980e1d4f0e8173ec27da77297ae411840c8ccb diff --git a/tests/test_source_unit.py b/tests/test_source_unit.py index 7b653599e..f979a41ec 100644 --- a/tests/test_source_unit.py +++ b/tests/test_source_unit.py @@ -1,5 +1,7 @@ from slither import Slither +# NB: read tests/source_unit/README.md before using this test + def test_contract_info() -> None: slither = Slither("./tests/source_unit") From 024729aa2f54a12ea09b0ff8d1bb137da2de1646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Fri, 6 Jan 2023 15:20:21 -0300 Subject: [PATCH 51/61] ci: fix Docker build This fixes some issues with the Docker build process * missing `git` in wheel build process - pip requires Git to pull dependencies expressed as `foo @ git+https://...`. * pip upgrade before building - it was disabled with an extra `echo` Thanks to @ahpaleus for reporting this! * final image installation - pip insists on rebuilding git-referenced dependencies, so this installs the wheels directly with `--no-deps` to get the desired behavior. --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 71bb9f57f..d0a7d67be 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,7 @@ FROM ubuntu:jammy AS python-wheels RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ gcc \ + git \ python3-dev \ python3-pip \ && rm -rf /var/lib/apt/lists/* @@ -9,7 +10,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins COPY . /slither RUN cd /slither && \ - echo pip3 install --no-cache-dir --upgrade pip && \ + pip3 install --no-cache-dir --upgrade pip && \ pip3 wheel -w /wheels . solc-select pip setuptools wheel @@ -44,7 +45,7 @@ ENV PATH="/home/slither/.local/bin:${PATH}" # no-index ensures we install the freshly-built wheels RUN --mount=type=bind,target=/mnt,source=/wheels,from=python-wheels \ - pip3 install --user --no-cache-dir --upgrade --no-index --find-links /mnt pip slither-analyzer solc-select + pip3 install --user --no-cache-dir --upgrade --no-index --find-links /mnt --no-deps /mnt/*.whl RUN solc-select install 0.4.25 && solc-select use 0.4.25 From 48c75485dce51a84a319a9595129f77b2eeafb3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Fri, 6 Jan 2023 15:33:48 -0300 Subject: [PATCH 52/61] tests: source_unit: add skipif for requirements --- tests/test_source_unit.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test_source_unit.py b/tests/test_source_unit.py index f979a41ec..73c165016 100644 --- a/tests/test_source_unit.py +++ b/tests/test_source_unit.py @@ -1,8 +1,18 @@ +from pathlib import Path +import shutil + +import pytest from slither import Slither -# NB: read tests/source_unit/README.md before using this test +# NB: read tests/source_unit/README.md for setup before using this test + +foundry_available = shutil.which("forge") is not None +project_ready = Path("./tests/source_unit/lib/forge-std").exists() +@pytest.mark.skipif( + not foundry_available or not project_ready, reason="requires Foundry and project setup" +) def test_contract_info() -> None: slither = Slither("./tests/source_unit") From c548dfdcc78116dd879182c1aef99972d9d6c059 Mon Sep 17 00:00:00 2001 From: Simone Date: Sat, 7 Jan 2023 19:51:16 +0100 Subject: [PATCH 53/61] Fix analyze library using for directives --- .../slither_compilation_unit_solc.py | 7 +++++-- ...g-for-in-library-0.8.0.sol-0.8.15-compact.zip | Bin 0 -> 2831 bytes ...-for-in-library-0.8.0.sol-0.8.15-compact.json | 8 ++++++++ tests/ast-parsing/using-for-in-library-0.8.0.sol | 14 ++++++++++++++ tests/test_ast_parsing.py | 1 + tests/test_features.py | 11 +++++++++++ 6 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 tests/ast-parsing/compile/using-for-in-library-0.8.0.sol-0.8.15-compact.zip create mode 100644 tests/ast-parsing/expected/using-for-in-library-0.8.0.sol-0.8.15-compact.json create mode 100644 tests/ast-parsing/using-for-in-library-0.8.0.sol diff --git a/slither/solc_parsing/slither_compilation_unit_solc.py b/slither/solc_parsing/slither_compilation_unit_solc.py index 7bae88c5c..3d636d339 100644 --- a/slither/solc_parsing/slither_compilation_unit_solc.py +++ b/slither/solc_parsing/slither_compilation_unit_solc.py @@ -512,7 +512,7 @@ Please rename it, this name is reserved for Slither's internals""" self._analyze_third_part(contracts_to_be_analyzed, libraries) [c.set_is_analyzed(False) for c in self._underlying_contract_to_parser.values()] - self._analyze_using_for(contracts_to_be_analyzed) + self._analyze_using_for(contracts_to_be_analyzed, libraries) self._parsed = True @@ -624,9 +624,12 @@ Please rename it, this name is reserved for Slither's internals""" else: contracts_to_be_analyzed += [contract] - def _analyze_using_for(self, contracts_to_be_analyzed: List[ContractSolc]): + def _analyze_using_for(self, contracts_to_be_analyzed: List[ContractSolc], libraries: List[ContractSolc]): self._analyze_top_level_using_for() + for lib in libraries: + lib.analyze_using_for() + while contracts_to_be_analyzed: contract = contracts_to_be_analyzed[0] diff --git a/tests/ast-parsing/compile/using-for-in-library-0.8.0.sol-0.8.15-compact.zip b/tests/ast-parsing/compile/using-for-in-library-0.8.0.sol-0.8.15-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..ca32c7583bce8f8c3e6e94dd274a36cab9fdef09 GIT binary patch literal 2831 zcmb8xXCM@e0|xNR=B(@;Sy^XiyEEcABmVxpJoxoSY+^hC1`OYU1VO0q{JF3mYweh|qHOg%1w`^3V*OV@6etug$;mj253iwfZ|{R8009Sjjdby>p7Q&~Kpo zs^}8<`ed_7{dtAg(3lR!=kSd773E^Yh!RhdrMWje{35l_D`62b(*E>!rEbUWx3pcY ziY;CY9nhQY7!AMoQrB+}PdY^!{htib-ly zC)S?4xyFWwPb@hTy1`i%dF)%Vf{EBfdJ_R@^INKu2&92X(#>FzOlyl;ZuVwf0X`P` zrSW{?Kv>K!H2X@vg0kClSMgUK;Jt^85#x%y)~~XKwhbA;v?Q@k6ARoi1aL>oJZMGk zS=`J&hJlpach0lY4_ND~VX0{+dzPVP%@xjD@I!MC!KsWWx}=QTtW9@BqN?g8G>r${ zISYO#<3pIVr?YEj9+$*AD24Mh{o1V%;Et}r-zY?wdwmVjYD>AoPuu&e!OX3Q|6Gs6 zyNl1Ci36{k*Vu zIqM|ZR>oQg$1gb}-MHGmija}~5)+p8*$^5QM6S<;*YpWzU2k-)4Y-*pe!zr)rWo6|Iu5+Yx4bdN33=q=;?KS)33)gjwI z;S?oghuP(!P*r%fy1T$dJyRfWgwgl5d`B)*U<*ye9AOT=OdHb1W{d zuXwxd+0GfNh=VvtSOFGcTH4>|;9z!PVQ*5)q?Sd@C@3d5*MTgpV?Zv#Dtf%ahm`Iw zRmr{Lz3e0NIjnT{?0eQq3=O8ZYsef&Gd9JRs_}Uz`RfEiaVa^KCjxJ?HWx9Y#PWN3 zTj;LkTn78|)yWGpSOXDw`|c**1liZ-4C10vvt}yt6c4uazdc$7AY9$IfxhC zEs~5U{+bL=^w+chzQDBxkpDIO8Z{r>cYcOq47%6sb;NY|<8aOF%i4rV`^bo<^H|O^ z33wUAol^3ywgVcAO*5Cvo1W^+Evt{KilCX|>I}fi3>Hfg6-k1pq0 z9h0t9fOl0Mf2UyE(WkofDR2_m(3%Zz5@MOSztP3|NXRYN#m`VmkuvPTP|EMsJ#I7q zlfM?i;F!jZTY@p)$escR+?dm^oqiua{QQ}tOG ze&$|@a0#uw{cV~18kVFc+k-I;tpY3b{NXH~6p4(Ay-)xV50YXN1wpeti_3}oww^G9 zGSdQRp@fTeaJ>OZdQd<1sv7*s>!e(F3z>-M3itq+82HGlsL(mIz=l<@ncoPjDlCOD z(jOO#nvvr;`MRUr+*2GvX)fF72V#1SSM?mfJSyO`X;a9^%XVISJryNl@2A!@@LJet zVF~&VALcsYBO$;<%)}O;-Z~a?{ACoJk73=yd(RgM8kn+q98I) zgJ6|tj1ULGbvlAc1i5JdMTZ9r!rMK)RFbkvL7we}NNMq$IfWy+0Wv}C zzS|=v8T6U zdV*(Tvjb*ecF?d+%1sPvxv62&;u$=j78Kg^<}n;Twgs=;+CLHz;Q7&wU5_&pVRtEEo%W+PK1;k#6(KK zZ=v2jDSdb=P~)mBBwO0@DC?b|WIXKo`DzPz)byVeolxsbwUb#tHGVm#gYtAL;4ow8#1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + }, + "B": { + "b(uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/using-for-in-library-0.8.0.sol b/tests/ast-parsing/using-for-in-library-0.8.0.sol new file mode 100644 index 000000000..0e8f6a6b9 --- /dev/null +++ b/tests/ast-parsing/using-for-in-library-0.8.0.sol @@ -0,0 +1,14 @@ + +library A { + using B for uint256; + + function a(uint256 v) public view returns (uint) { + return v.b(); + } +} + +library B { + function b(uint256 v) public view returns (uint) { + return 1; + } +} diff --git a/tests/test_ast_parsing.py b/tests/test_ast_parsing.py index 0d6118601..7e22ea186 100644 --- a/tests/test_ast_parsing.py +++ b/tests/test_ast_parsing.py @@ -428,6 +428,7 @@ ALL_TESTS = [ Test("using-for-2-0.8.0.sol", ["0.8.15"]), Test("using-for-3-0.8.0.sol", ["0.8.15"]), Test("using-for-4-0.8.0.sol", ["0.8.15"]), + Test("using-for-in-library-0.8.0.sol", ["0.8.15"]), Test("using-for-alias-contract-0.8.0.sol", ["0.8.15"]), Test("using-for-alias-top-level-0.8.0.sol", ["0.8.15"]), Test("using-for-functions-list-1-0.8.0.sol", ["0.8.15"]), diff --git a/tests/test_features.py b/tests/test_features.py index a5541b589..924e0b154 100644 --- a/tests/test_features.py +++ b/tests/test_features.py @@ -128,3 +128,14 @@ def test_using_for_alias_contract() -> None: if isinstance(ir, InternalCall) and ir.function_name == "a": return assert False + + +def test_using_for_in_library() -> None: + solc_select.switch_global_version("0.8.15", always_install=True) + slither = Slither("./tests/ast-parsing/using-for-in-library-0.8.0.sol") + contract_c = slither.get_contract_from_name("A")[0] + libCall = contract_c.get_function_from_full_name("a(uint256)") + for ir in libCall.all_slithir_operations(): + if isinstance(ir, LibraryCall) and ir.destination == "B" and ir.function_name == "b": + return + assert False From f47f6820409822d8ccac2dd94f1e152ef466fa54 Mon Sep 17 00:00:00 2001 From: Simone Date: Sat, 7 Jan 2023 19:56:49 +0100 Subject: [PATCH 54/61] Run black --- slither/solc_parsing/slither_compilation_unit_solc.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slither/solc_parsing/slither_compilation_unit_solc.py b/slither/solc_parsing/slither_compilation_unit_solc.py index 3d636d339..c8b69d4b2 100644 --- a/slither/solc_parsing/slither_compilation_unit_solc.py +++ b/slither/solc_parsing/slither_compilation_unit_solc.py @@ -624,7 +624,9 @@ Please rename it, this name is reserved for Slither's internals""" else: contracts_to_be_analyzed += [contract] - def _analyze_using_for(self, contracts_to_be_analyzed: List[ContractSolc], libraries: List[ContractSolc]): + def _analyze_using_for( + self, contracts_to_be_analyzed: List[ContractSolc], libraries: List[ContractSolc] + ): self._analyze_top_level_using_for() for lib in libraries: From 22635452e362f5bd46acd04300e4a2f5c0b46952 Mon Sep 17 00:00:00 2001 From: Feist Josselin Date: Mon, 9 Jan 2023 14:23:04 +0100 Subject: [PATCH 55/61] Update CODEOWNERS --- CODEOWNERS | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index e76e5a2bb..41954591d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,4 +1,5 @@ -* @montyly @0xalpharush @smonicas -/slither/tools/read_storage @0xalpharush -/slither/slithir/ @montyly -/slither/analyses/ @montyly +* @montyly @0xalpharush @smonicas +/slither/tools/read_storage/ @0xalpharush +/slither/tools/doctor/ @elopez +/slither/slithir/ @montyly +/slither/analyses/ @montyly From c5299d6bc8808b67605f78039e8e795a2cd506dd Mon Sep 17 00:00:00 2001 From: Feist Josselin Date: Mon, 9 Jan 2023 14:30:13 +0100 Subject: [PATCH 56/61] Update CODEOWNERS --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index 41954591d..c92f0d79d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -3,3 +3,4 @@ /slither/tools/doctor/ @elopez /slither/slithir/ @montyly /slither/analyses/ @montyly +/.github/workflows/ @elopez From 811dd78b482d037e34044fa9d68a6ddb5202f962 Mon Sep 17 00:00:00 2001 From: Feist Josselin Date: Mon, 9 Jan 2023 14:40:44 +0100 Subject: [PATCH 57/61] Update literal.py --- slither/core/expressions/literal.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slither/core/expressions/literal.py b/slither/core/expressions/literal.py index 328ec9674..2eaeb715d 100644 --- a/slither/core/expressions/literal.py +++ b/slither/core/expressions/literal.py @@ -23,7 +23,7 @@ class Literal(Expression): return self._value @property - def converted_value(self) -> int: + def converted_value(self) -> Union[int, str]: """Return the value of the literal, accounting for subdenomination e.g. ether""" if self.subdenomination: return convert_subdenomination(self._value, self.subdenomination) @@ -37,7 +37,7 @@ class Literal(Expression): def subdenomination(self) -> Optional[str]: return self._subdenomination - def __str__(self): + def __str__(self) -> str: if self.subdenomination: return str(self.converted_value) @@ -47,7 +47,7 @@ class Literal(Expression): # be sure to handle any character return str(self._value) - def __eq__(self, other): + def __eq__(self, other) -> bool: if not isinstance(other, Literal): return False return (self.value, self.subdenomination) == (other.value, other.subdenomination) From 7569131faa6b5103b7a5d2c2c4e7b98a7b8daf1b Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Mon, 9 Jan 2023 14:23:37 -0600 Subject: [PATCH 58/61] fix type conversion of alias so library function can be found --- .../visitors/slithir/expression_to_slithir.py | 9 +++++-- .../using-for-0.8.8.sol-0.8.10-compact.zip | Bin 0 -> 3526 bytes .../using-for-0.8.8.sol-0.8.11-compact.zip | Bin 0 -> 3522 bytes .../using-for-0.8.8.sol-0.8.12-compact.zip | Bin 0 -> 3526 bytes .../using-for-0.8.8.sol-0.8.13-compact.zip | Bin 0 -> 3523 bytes .../using-for-0.8.8.sol-0.8.14-compact.zip | Bin 0 -> 3521 bytes .../using-for-0.8.8.sol-0.8.15-compact.zip | Bin 0 -> 3522 bytes .../using-for-0.8.8.sol-0.8.8-compact.zip | Bin 0 -> 3501 bytes .../using-for-0.8.8.sol-0.8.10-compact.json | 11 +++++++++ .../using-for-0.8.8.sol-0.8.11-compact.json | 11 +++++++++ .../using-for-0.8.8.sol-0.8.12-compact.json | 11 +++++++++ .../using-for-0.8.8.sol-0.8.13-compact.json | 11 +++++++++ .../using-for-0.8.8.sol-0.8.14-compact.json | 11 +++++++++ .../using-for-0.8.8.sol-0.8.15-compact.json | 11 +++++++++ .../using-for-0.8.8.sol-0.8.8-compact.json | 11 +++++++++ .../using-for-0.8.8.sol | 22 ++++++++++++++++++ tests/test_ast_parsing.py | 1 + 17 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.10-compact.zip create mode 100644 tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.11-compact.zip create mode 100644 tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.12-compact.zip create mode 100644 tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.13-compact.zip create mode 100644 tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.14-compact.zip create mode 100644 tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.15-compact.zip create mode 100644 tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.8-compact.zip create mode 100644 tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.10-compact.json create mode 100644 tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.11-compact.json create mode 100644 tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.12-compact.json create mode 100644 tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.13-compact.json create mode 100644 tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.14-compact.json create mode 100644 tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.15-compact.json create mode 100644 tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.8-compact.json create mode 100644 tests/ast-parsing/user_defined_value_type/using-for-0.8.8.sol diff --git a/slither/visitors/slithir/expression_to_slithir.py b/slither/visitors/slithir/expression_to_slithir.py index 3c4595b92..66aa43ee6 100644 --- a/slither/visitors/slithir/expression_to_slithir.py +++ b/slither/visitors/slithir/expression_to_slithir.py @@ -282,10 +282,15 @@ class ExpressionToSlithIR(ExpressionVisitor): and expression_called.member_name in ["wrap", "unwrap"] and len(args) == 1 ): + # wrap: underlying_type -> alias + # unwrap: alias -> underlying_type + dest_type = ( + called if expression_called.member_name == "wrap" else called.underlying_type + ) val = TemporaryVariable(self._node) - var = TypeConversion(val, args[0], called) + var = TypeConversion(val, args[0], dest_type) var.set_expression(expression) - val.set_type(called) + val.set_type(dest_type) self._result.append(var) set_val(expression, val) diff --git a/tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.10-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.10-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..2dedfd0a66c31fed984fda23bfe51fc62c5c0a4b GIT binary patch literal 3526 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 literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.12-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.12-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..573f4efc0c8f049284aecb80e7ad10cc286f81e3 GIT binary patch literal 3526 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 literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.14-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.14-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..db90bfcab2734551019cd1eab69f56c3a191db1c GIT binary patch literal 3521 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 literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.8-compact.zip b/tests/ast-parsing/compile/user_defined_value_type/using-for-0.8.8.sol-0.8.8-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..89d650f85e835f65ed927413f91318fb0066435a GIT binary patch literal 3501 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\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: RETURN 2\n\"];\n}\n" + }, + "A": { + "b(MyType)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + }, + "B": { + "c(uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.11-compact.json b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.11-compact.json new file mode 100644 index 000000000..58fb20ce1 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.11-compact.json @@ -0,0 +1,11 @@ +{ + "MyLib": { + "a()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: RETURN 2\n\"];\n}\n" + }, + "A": { + "b(MyType)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + }, + "B": { + "c(uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.12-compact.json b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.12-compact.json new file mode 100644 index 000000000..58fb20ce1 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.12-compact.json @@ -0,0 +1,11 @@ +{ + "MyLib": { + "a()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: RETURN 2\n\"];\n}\n" + }, + "A": { + "b(MyType)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + }, + "B": { + "c(uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.13-compact.json b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.13-compact.json new file mode 100644 index 000000000..58fb20ce1 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.13-compact.json @@ -0,0 +1,11 @@ +{ + "MyLib": { + "a()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: RETURN 2\n\"];\n}\n" + }, + "A": { + "b(MyType)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + }, + "B": { + "c(uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.14-compact.json b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.14-compact.json new file mode 100644 index 000000000..58fb20ce1 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.14-compact.json @@ -0,0 +1,11 @@ +{ + "MyLib": { + "a()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: RETURN 2\n\"];\n}\n" + }, + "A": { + "b(MyType)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + }, + "B": { + "c(uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.15-compact.json b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.15-compact.json new file mode 100644 index 000000000..58fb20ce1 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.15-compact.json @@ -0,0 +1,11 @@ +{ + "MyLib": { + "a()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: RETURN 2\n\"];\n}\n" + }, + "A": { + "b(MyType)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + }, + "B": { + "c(uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.8-compact.json b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.8-compact.json new file mode 100644 index 000000000..58fb20ce1 --- /dev/null +++ b/tests/ast-parsing/expected/user_defined_value_type/using-for-0.8.8.sol-0.8.8-compact.json @@ -0,0 +1,11 @@ +{ + "MyLib": { + "a()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: RETURN 2\n\"];\n}\n" + }, + "A": { + "b(MyType)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + }, + "B": { + "c(uint256)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: RETURN 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/user_defined_value_type/using-for-0.8.8.sol b/tests/ast-parsing/user_defined_value_type/using-for-0.8.8.sol new file mode 100644 index 000000000..bc65038ab --- /dev/null +++ b/tests/ast-parsing/user_defined_value_type/using-for-0.8.8.sol @@ -0,0 +1,22 @@ +type MyType is uint256; + +library MyLib { + using A for MyType; + using B for uint; + function a() internal returns(uint){ + MyType myvar = MyType.wrap(4); + return MyType.unwrap(myvar.b()).c(); + } +} + +library A { + function b(MyType e) public returns(MyType){ + return MyType.wrap(3); + } + +} +library B { + function c(uint e) public returns(uint){ + return 345; + } +} \ No newline at end of file diff --git a/tests/test_ast_parsing.py b/tests/test_ast_parsing.py index 2f0e9b12c..38c12e5d8 100644 --- a/tests/test_ast_parsing.py +++ b/tests/test_ast_parsing.py @@ -418,6 +418,7 @@ ALL_TESTS = [ 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/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), Test("free_functions/libraries_from_free.sol", ["0.8.12"]), From b1899516170987fbcf91d4b4d3f25edc02b49759 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Mon, 9 Jan 2023 15:22:51 -0600 Subject: [PATCH 59/61] resolve error referenced as member of contract --- .../custom-error-selector.sol-0.8.10-compact.zip | Bin 0 -> 2802 bytes .../custom-error-selector.sol-0.8.11-compact.zip | Bin 0 -> 2802 bytes .../custom-error-selector.sol-0.8.12-compact.zip | Bin 0 -> 2802 bytes .../custom-error-selector.sol-0.8.13-compact.zip | Bin 0 -> 2813 bytes .../custom-error-selector.sol-0.8.14-compact.zip | Bin 0 -> 2810 bytes .../custom-error-selector.sol-0.8.15-compact.zip | Bin 0 -> 2814 bytes .../custom-error-selector.sol-0.8.4-compact.zip | Bin 0 -> 2767 bytes .../custom-error-selector.sol-0.8.5-compact.zip | Bin 0 -> 2790 bytes .../custom-error-selector.sol-0.8.6-compact.zip | Bin 0 -> 2789 bytes .../custom-error-selector.sol-0.8.7-compact.zip | Bin 0 -> 2781 bytes .../custom-error-selector.sol-0.8.8-compact.zip | Bin 0 -> 2788 bytes .../custom-error-selector.sol-0.8.9-compact.zip | Bin 0 -> 2800 bytes tests/ast-parsing/custom-error-selector.sol | 13 +++++++++++++ ...custom-error-selector.sol-0.8.10-compact.json | 10 ++++++++++ ...custom-error-selector.sol-0.8.11-compact.json | 10 ++++++++++ ...custom-error-selector.sol-0.8.12-compact.json | 10 ++++++++++ ...custom-error-selector.sol-0.8.13-compact.json | 10 ++++++++++ ...custom-error-selector.sol-0.8.14-compact.json | 10 ++++++++++ ...custom-error-selector.sol-0.8.15-compact.json | 10 ++++++++++ .../custom-error-selector.sol-0.8.4-compact.json | 10 ++++++++++ .../custom-error-selector.sol-0.8.5-compact.json | 10 ++++++++++ .../custom-error-selector.sol-0.8.6-compact.json | 10 ++++++++++ .../custom-error-selector.sol-0.8.7-compact.json | 10 ++++++++++ .../custom-error-selector.sol-0.8.8-compact.json | 10 ++++++++++ .../custom-error-selector.sol-0.8.9-compact.json | 10 ++++++++++ 25 files changed, 133 insertions(+) create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.10-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.11-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.12-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.13-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.14-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.15-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.4-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.5-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.6-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.7-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.8-compact.zip create mode 100644 tests/ast-parsing/compile/custom-error-selector.sol-0.8.9-compact.zip create mode 100644 tests/ast-parsing/custom-error-selector.sol create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.10-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.11-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.12-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.13-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.14-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.15-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.4-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.5-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.6-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.7-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.8-compact.json create mode 100644 tests/ast-parsing/expected/custom-error-selector.sol-0.8.9-compact.json diff --git a/tests/ast-parsing/compile/custom-error-selector.sol-0.8.10-compact.zip b/tests/ast-parsing/compile/custom-error-selector.sol-0.8.10-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..0d7f3ac0f8b3788f226520e3db4ca8cc9725727d GIT binary patch literal 2802 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 literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/compile/custom-error-selector.sol-0.8.11-compact.zip b/tests/ast-parsing/compile/custom-error-selector.sol-0.8.11-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..193a3c93105974f4ac5511c47995ba117df9d22c GIT binary patch literal 2802 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 literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/compile/custom-error-selector.sol-0.8.13-compact.zip b/tests/ast-parsing/compile/custom-error-selector.sol-0.8.13-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..6225bd2c26d2e2632f5eb9d8acd19d72a3c31bcf GIT binary patch literal 2813 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 literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/compile/custom-error-selector.sol-0.8.14-compact.zip b/tests/ast-parsing/compile/custom-error-selector.sol-0.8.14-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..6c13dbacce34c35076051b2f475d40b383a280af GIT binary patch literal 2810 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 literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/compile/custom-error-selector.sol-0.8.5-compact.zip b/tests/ast-parsing/compile/custom-error-selector.sol-0.8.5-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..3c91ae99a593b982e81fe5764c99968b8e502df1 GIT binary patch literal 2790 zcmb8xX&@7f0|xLhcSdtx(IIk7IVWe!(ah@>851!=j7^RSLyj1WjCftK5ScT#$QjZc zAy>KYBfM_$@BM%OfA~Mohv(Dt{bye!i&>E(@#aEWVxzbwKKbo?oRM$I_SU08fQvp`yvu)IYNU~HIiWabo-V=hMx~{8zNACi>~KF?fqQ>eX_v%j z%`G97&k$Fdm{G&efEu#^>cJ zyB}N3w`+S2NDH#;&E(SYl&XYM-%2yzgub4wh)0P9n?ffXeu*Pq$xzmp+d?T2JCxtp z`{r2tckhqS!#Ph`7;D7ic0T{29Q00bA=hNVYj4^Xb-qeVCf;h9#?~dka zAeHaVg@ax;Q>`9Fw&vBWdm)v}M(d7V=PO%5{qXM)-XNl>K$@=j{+ zm<#TY7=3X?4Di%(p2&`khpXGXDvD2KBs9G8{P7QJmaEiPxUIn$XUnuzkW)TjQZ6#d z2wxYfkQz^vm`$@Q(hXQDl64YRDVkzSrs}N&b3Fg zp%h-<2_-JR)zxVov4sxWjPf|)*I+JOQ88pDr(VKhKy9y~Vl&sigpKzMzqh)C4(hmE=|c<@7i^I^Pb((t(ZUHRh@`gl?Q*Wq?+W{ zR#KWZ#5IsFf#>|#&0GnycytoddUSDqmO-n-p-nS+p7^z5nLKgZeOBpZu~Ay5cI#5_ zGE2lXVWP>&3++8V_4re~pWMyEk%!q*PWs;^jD_fO0~XZ{ zV)7`k3#IkS5zj?M_ntAokY!|csKDP|mn&Tj@EYpBEi5gR4}!ofTz-yx>woS4fckv~ z8b%a5o>TugHj&?76M5rGmj^4<(0cu#ChWw*S;b*4Kp#+W^OF38ade54BXF#C{;KAu zLeFli4$Ek*bNY9v&DH%Q2LI&043`jPcsOnEq-+9*MELo;_6cIig&rD8 zrgD=M2^@puQsZ5Vlk`TEWe)?In>JIbVZ!{=XA9o&pWQ8eEZE5f(X^Bwhb#OCipeST%M{jQMoec$&Wsp2ub+}PP^0eL z=>f&VK*LpsFf&JiW15x8hu4elLCCE5#C<7(>16XQkxBPsZA8=u$9Lw{EfLSmGiJCX zD*RtH7??CjVQ#M6D&xquMF;}Y5QTf*b<$}1r$kLcvmUcDiHnIHTMSokh#o1Ly3`WL zU(5bp{3tq1NR_XrgVdwJW)5Y@^TTNc6`SdlIJte>FjR8#>pn~<&_hU&N>?ibSKr^| zQZ~9D)u@oY`vS<2VcYFIwcdySARtK)bSA(OTEq1NZ9fwuj%YxUxBh%*)lDgrIln6Y zdb-dd!g>GeUW}j$fa1Q>0sI&4FAKE-DVq&Y?*!AhaItqyI3Vk9|2^+4y z)_3zTD6?!Rje+@_xXYU_4^VIeCunFnBGBYlmV>8Z^`#!H?608;zIMzBb)VTqpXXQb zqYy)3U%x6pEubjw{YR_W-;@BDNv_w3Mlx-MwB`+oKP=v29+VDI=BM0C8acZdz_8FF zD2u=79-Cg=N`0e>xxuC{!dOoHR8yjmRU%Su&zdNU5>@Joj%$hZ-%_y@Qn9);q#%zV zX4_n6^cz-~X$VH&x(W}VRtZi|fcUdN0_b(idN(y?3<|+H#?QbNj4|FY(0nn4l&g1n$n~tg(!s9|0S2h6Gqidg<5cLTj zZx;j!RNdHFx!I$}Q{2Xd-49WXNXcjgUX4FU-p|z?mCD;%i;Y1WgmxaYa~0CrTc2`C zIhT(O-#dA^I1_|4_0n2Ru-sY~(7w>b-84@fwNn#t#}}=P#e-_U4v(n8tFi)<`!XgF zRP}Inq@F|G+=eg#EMNVT>lRO6cAD_>a7Z0*I=*I`KE~5L!^7gMM5~w2>n4j5m4dwTWA+@+z|8GFhcFB0C5Z z_YZd(xEYKqP0?1J`Dz89avmdc2c&oRRL0Ak9}FT0riOI%+Q9$K&Oh?}ZwPe%&i{o_ VQ$t3ke@}FOYWruO{?RM|@E^?cGQb008gM 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 X7eO7YIe`D3Sbo?2_hNoq76AAUh4VBH literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/compile/custom-error-selector.sol-0.8.9-compact.zip b/tests/ast-parsing/compile/custom-error-selector.sol-0.8.9-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..eae6bf9c155f54636987c1dd5e18ae8387fb8b09 GIT binary patch literal 2800 zcmb8xXCM@e0|xNJS!b_vSCS%}LY%$MJ~=BhgqJ(nj=RIT%jU?+%uYmJ31#agiHvNr z_ohfjHvN15-~S)}&-3B=^nCxBplE;y05yOWfFr>yGtBpdWk3MHZ#V!T4gdhqes}`b zOWYZU!{Ws8&YsR_0v0EM$9g(A6Me8af`cOt?ds<5Ea8sFdNTrP0d@dDC;*@u6XOCu zhx--`_tz=24(6Uj*at{9gv;?{(T zcwHXEvRkI5DTP%UcBAv|)sI|GGeLSScLGRoH2!vY>5{7VYSqs7`z_8$Ln> zb0YyPKzi<#XE-0c4TBg7sH{SxferIJ1^*n##b3O9r6VRi5|AJJB6k&i_>=!No|@_I zaG5Ml&TcmU*M*)7jf{SObF2Y8r))Kq%bJbxr{f*dmNaWl>F$DLkD3(4ay=)MqS$(~ zpx$nuu|TK?brhtpg-3J5xb!JB{=>D99j$l_&*O5Zx^GEHhWsCIz-uQcX5PPoNd4Ov z-ne7GYXEUu*Wj5HozniVPs}ftqa-v?b+a7x4XJ^H!mqH(7$k1#_}kdjtM1M91a|9a z#Fda_*>%g~Aj&y>ImPt-X8sNj;X|wiU+E3YHYnYBJdnyLTdF?Bg(gz2d+Q%=WUt5} zHT=dxFGYrTIh-76t8lo_^Ui<^LBDgSEEMCrDR*UNdoK^s(3)v-dh5qf5E6{wZ9H6& zizD&PD$mER=2_tYBhE=HOZCWQnMkE z4BDa2V@dBd4T+qF?|LSKzwbZ)wLmr}2fELqQRvgOXC~801;Me z+1eZh6zXf;P{lA|N5~~>Q)bR_i*W#-a`LYm!}lIf8y0}XyZ2)F8|4OCs$el`GJz>( zR?gZW-xIH9me{H6F6v9ZrEPqT`ov7q8rK%(9f3B_KaH**0^E0wg_} z)vkaV8CM!#9ooa_khX%K2>_&EKsRIw6q`-Zvt4jc{;G;C$!XObV1-juIqoT0DZY*hE!PRZ31I5<2_+{ zyhKJc=aW+AoYv9BBv+3F_2S*leVxjq<;2Z|<$QlJvhGTW@{w+st%l`=>o8*ReMg*R ziIeoFr?!vGeEW012`L#QEL2#>*?s7{r!phmm&YKV`)G7RR$%Zq-0(NIL)0%z(;C`} zy`FH{8yruHTR^hV5U`?H09!i<>&-m6c+994rTG>#A`)eJth_ldy)*!kyy(%5m{R*F zcy|}c?RhX;xl$_56xMWG#Is7lV5+?iXl}>-mBN{uZe6?7qaX6CdoGxC6!T*82W{Pe z^U_6qz5#Q+hAT>?Ayc~YAZcy`ri6je$r#D3XfagXlUvPc?xLTpt*^$h30;FnICbFH zmd_4q28X~BusBX}`9~11P4m*bP4VX*7@t0}N2>3^toi}R>AQk)iy^MPUMi*YhXi9S zOxVmG7$9?+-ix4geYd>B~_mDHST$3)p>23+?K z6rFl2R;<{)>qF}jdev`h(Rre-qgICy`9e~3!cMkDSLz0_WZqU`SDU=~cBd9Mx(|Ea z>|Nq_Ha$cf?C6SQy456VbLB{BkK1vjtDI6MYT`qB!FN6}2C}gK`-TSp%}3Zp=k0Z! zvr_no{`U$aVslMWVxIZ(^GdL4qH(15rCXSq;my(eq!XqxxJ2iQucP9<0oC4Y34iwA zV_&r8d-s=IR>P}VkpDEf7<|{5^K_iI=59#zXuFdqPJgLhbq&Z}+H zPc)dyXA74Dx;R{3a+Y^WHf61iiWjkFsgymQrd**^eSXF8~fjUKlX|{>RGUG zX_e1+>vJqiVF|!BrE@)PDPJ^!;`w0D6>5(h^CdKk2Gb&(n2IygZ`vzy0cC|A)9gP2 zqt$wSt^KO6ky$4e!w9SV$V>2ewb#D(`Jyk?64ogaZ905+xIip96^HJQ(CC&*n zP9Jz8X&($ydrRgQT0vm>{yGtf9vqcAnpUUs*(}C}NXwkVjlqrgM6OAByNwx5I zjX(JMW0*fGu1jNu^3VQ9)=wFVi9OR~g)%`_1hOGPz@=p??4LacMGb(S={?w*7&VY<}AOuD&LJFUr~f8+p+RJjLu-#0s;dI)fE&}0!QSC z)5zkPtLw>w7%D1T(>W8nrtOduDPn5yiMEL;`=<47t4ZqN`MDX8KeMs9V+2kS?=hNp zo^B|_wL4Kg`Vy+e?HRFDgm=>Dlt}PWFW?*T_`5`kX}0%QJroQ+f2~(dT0u;Zh;7C_ zLRDVmSMmmZVV0wgc0bKKUvtd`#e7+)UCOa&wl{ej7_{$Z#(trr+hT&EqDIjCZ-D+W f=zkMR_3!*&95q4F(*1j)`cvCK8}i4s0Kk6$-}^47 literal 0 HcmV?d00001 diff --git a/tests/ast-parsing/custom-error-selector.sol b/tests/ast-parsing/custom-error-selector.sol new file mode 100644 index 000000000..05fe75f99 --- /dev/null +++ b/tests/ast-parsing/custom-error-selector.sol @@ -0,0 +1,13 @@ + contract Test { + error myError(); +} + +interface VM { + function expectRevert(bytes4) external; + function expectRevert(bytes calldata) external; +} +contract A { + function b(address c) public { + VM(c).expectRevert(Test.myError.selector); + } +} diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.10-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.10-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.10-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.11-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.11-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.11-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.12-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.12-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.12-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.13-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.13-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.13-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.14-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.14-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.14-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.15-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.15-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.15-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.4-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.4-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.4-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.5-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.5-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.5-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.6-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.6-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.6-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.7-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.7-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.7-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.8-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.8-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.8-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/ast-parsing/expected/custom-error-selector.sol-0.8.9-compact.json b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.9-compact.json new file mode 100644 index 000000000..d35b14059 --- /dev/null +++ b/tests/ast-parsing/expected/custom-error-selector.sol-0.8.9-compact.json @@ -0,0 +1,10 @@ +{ + "Test": {}, + "VM": { + "expectRevert(bytes4)": "digraph{\n}\n", + "expectRevert(bytes)": "digraph{\n}\n" + }, + "A": { + "b(address)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file From cf7c62bad138d1728c3961eb72bf42be539d4591 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Mon, 9 Jan 2023 15:25:05 -0600 Subject: [PATCH 60/61] add changes --- slither/slithir/convert.py | 25 ++++++++++++++++--- .../visitors/slithir/expression_to_slithir.py | 12 ++++++--- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/slither/slithir/convert.py b/slither/slithir/convert.py index 0d2ef1b74..7b9e286fa 100644 --- a/slither/slithir/convert.py +++ b/slither/slithir/convert.py @@ -379,7 +379,7 @@ def integrate_value_gas(result): ################################################################################### -def propagate_type_and_convert_call(result, node): +def propagate_type_and_convert_call(result: List[Operation], node: "Node") -> List[Operation]: """ Propagate the types variables and convert tmp call to real call operation """ @@ -664,7 +664,24 @@ def propagate_types(ir, node: "Node"): # pylint: disable=too-many-locals if ir.variable_right == "selector" and isinstance(ir.variable_left, (CustomError)): assignment = Assignment( ir.lvalue, - Constant(str(get_function_id(ir.variable_left.solidity_signature))), + Constant( + str(get_function_id(ir.variable_left.solidity_signature)), + ElementaryType("bytes4"), + ), + ElementaryType("bytes4"), + ) + assignment.set_expression(ir.expression) + assignment.set_node(ir.node) + assignment.lvalue.set_type(ElementaryType("bytes4")) + return assignment + + if isinstance(ir.variable_right, (CustomError)): + assignment = Assignment( + ir.lvalue, + Constant( + str(get_function_id(ir.variable_left.solidity_signature)), + ElementaryType("bytes4"), + ), ElementaryType("bytes4"), ) assignment.set_expression(ir.expression) @@ -736,7 +753,7 @@ def propagate_types(ir, node: "Node"): # pylint: disable=too-many-locals if f: ir.lvalue.set_type(f) else: - # Allow propgation for variable access through contract's nale + # Allow propgation for variable access through contract's name # like Base_contract.my_variable v = next( ( @@ -1819,7 +1836,7 @@ def _find_source_mapping_references(irs: List[Operation]): ################################################################################### -def apply_ir_heuristics(irs, node): +def apply_ir_heuristics(irs: List[Operation], node: "Node"): """ Apply a set of heuristic to improve slithIR """ diff --git a/slither/visitors/slithir/expression_to_slithir.py b/slither/visitors/slithir/expression_to_slithir.py index 3c4595b92..d59fc1a0e 100644 --- a/slither/visitors/slithir/expression_to_slithir.py +++ b/slither/visitors/slithir/expression_to_slithir.py @@ -455,14 +455,18 @@ class ExpressionToSlithIR(ExpressionVisitor): set_val(expression, expr) return - # Early lookup to detect user defined types from other contracts definitions - # contract A { type MyInt is int} - # contract B { function f() public{ A.MyInt test = A.MyInt.wrap(1);}} - # The logic is handled by _post_call_expression if isinstance(expr, Contract): + # Early lookup to detect user defined types from other contracts definitions + # contract A { type MyInt is int} + # contract B { function f() public{ A.MyInt test = A.MyInt.wrap(1);}} + # The logic is handled by _post_call_expression if expression.member_name in expr.file_scope.user_defined_types: set_val(expression, expr.file_scope.user_defined_types[expression.member_name]) return + # Lookup errors referred to as member of contract e.g. Test.myError.selector + if expression.member_name in expr.custom_errors_as_dict: + set_val(expression, expr.custom_errors_as_dict[expression.member_name]) + return val = ReferenceVariable(self._node) member = Member(expr, Constant(expression.member_name), val) From e21d6eb17b4441b12ede8a53a63e1c9d5868c5b5 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Mon, 9 Jan 2023 15:31:12 -0600 Subject: [PATCH 61/61] add ast test --- tests/test_ast_parsing.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_ast_parsing.py b/tests/test_ast_parsing.py index 2f0e9b12c..ff96df929 100644 --- a/tests/test_ast_parsing.py +++ b/tests/test_ast_parsing.py @@ -328,6 +328,7 @@ ALL_TESTS = [ ALL_VERSIONS, ), Test("custom_error-0.8.4.sol", make_version(8, 4, 15)), + Test("custom-error-selector.sol", make_version(8, 4, 15)), Test( "top-level-0.4.0.sol", VERSIONS_04 + VERSIONS_05 + VERSIONS_06 + ["0.7.0"],