diff --git a/slither/core/declarations/contract.py b/slither/core/declarations/contract.py index 94c72786b..fc656b855 100644 --- a/slither/core/declarations/contract.py +++ b/slither/core/declarations/contract.py @@ -102,7 +102,9 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods self.file_scope: "FileScope" = scope # memoize - self._state_variables_used_in_reentrant_targets: Optional[Dict["StateVariable", Set[Union["StateVariable", "Function"]]]]= None + self._state_variables_used_in_reentrant_targets: Optional[ + Dict["StateVariable", Set[Union["StateVariable", "Function"]]] + ] = None ################################################################################### ################################################################################### @@ -354,7 +356,9 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods return list(set(slithir_variables)) @property - def state_variables_used_in_reentrant_targets(self) -> Dict["StateVariable", Set[Union["StateVariable", "Function"]]]: + def state_variables_used_in_reentrant_targets( + self, + ) -> Dict["StateVariable", Set[Union["StateVariable", "Function"]]]: """ Returns the state variables used in reentrant targets. Heuristics: - Variable used (read/write) in entry points that are reentrant @@ -362,9 +366,12 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods """ from slither.core.variables.state_variable import StateVariable + if self._state_variables_used_in_reentrant_targets is None: reentrant_functions = [f for f in self.functions_entry_points if f.is_reentrant] - variables_used: Dict[StateVariable, Set[Union[StateVariable, "Function"]]] = defaultdict(set) + variables_used: Dict[ + StateVariable, Set[Union[StateVariable, "Function"]] + ] = defaultdict(set) for function in reentrant_functions: for ir in function.all_slithir_operations(): state_variables = [v for v in ir.used if isinstance(v, StateVariable)] diff --git a/slither/detectors/reentrancy/reentrancy_eth.py b/slither/detectors/reentrancy/reentrancy_eth.py index b8ae6afbc..c5183e82f 100644 --- a/slither/detectors/reentrancy/reentrancy_eth.py +++ b/slither/detectors/reentrancy/reentrancy_eth.py @@ -74,14 +74,11 @@ Bob uses the re-entrancy bug to call `withdrawBalance` two times, and withdraw m v, node, tuple(sorted(nodes, key=lambda x: x.node_id)), - tuple(variables_used_in_reentrancy[v]) + tuple(variables_used_in_reentrancy[v]), ) for (v, nodes) in node.context[self.KEY].written.items() if v in node.context[self.KEY].reads_prior_calls[c] - and ( - f.is_reentrant - or v in variables_used_in_reentrancy - ) + and (f.is_reentrant or v in variables_used_in_reentrancy) } if read_then_written: @@ -132,7 +129,11 @@ Bob uses the re-entrancy bug to call `withdrawBalance` two times, and withdraw m if other_node != finding_value.node: info += ["\t\t- ", other_node, "\n"] if finding_value.cross_functions: - info += ["\t", finding_value.variable," can be used in cross function reentrancies:\n"] + info += [ + "\t", + finding_value.variable, + " can be used in cross function reentrancies:\n", + ] for cross in finding_value.cross_functions: info += ["\t- ", cross, "\n"] diff --git a/slither/detectors/reentrancy/reentrancy_read_before_write.py b/slither/detectors/reentrancy/reentrancy_read_before_write.py index 3b90437d5..fff022d5e 100644 --- a/slither/detectors/reentrancy/reentrancy_read_before_write.py +++ b/slither/detectors/reentrancy/reentrancy_read_before_write.py @@ -70,14 +70,11 @@ Do not report reentrancies that involve Ether (see `reentrancy-eth`).""" v, node, tuple(sorted(nodes, key=lambda x: x.node_id)), - tuple(variables_used_in_reentrancy[v]) + tuple(variables_used_in_reentrancy[v]), ) for (v, nodes) in node.context[self.KEY].written.items() if v in node.context[self.KEY].reads_prior_calls[c] - and ( - f.is_reentrant - or v in variables_used_in_reentrancy - ) + and (f.is_reentrant or v in variables_used_in_reentrancy) } # We found a potential re-entrancy bug @@ -120,7 +117,11 @@ Do not report reentrancies that involve Ether (see `reentrancy-eth`).""" if other_node != finding_value.node: info += ["\t\t- ", other_node, "\n"] if finding_value.cross_functions: - info += ["\t", finding_value.variable," can be used in cross function reentrancies:\n"] + info += [ + "\t", + finding_value.variable, + " can be used in cross function reentrancies:\n", + ] for cross in finding_value.cross_functions: info += ["\t- ", cross, "\n"]