From 87264863f73eff6998885c788e760be789c5af68 Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 2 Apr 2025 16:24:37 +0200 Subject: [PATCH] Add calls stack information --- slither/detectors/statements/calls_in_loop.py | 45 ++++++++++++------- .../statements/costly_operations_in_loop.py | 36 ++++++++++----- .../statements/delegatecall_in_loop.py | 36 ++++++++++----- .../detectors/statements/msg_value_in_loop.py | 36 ++++++++++----- ...tiple_costly_operations_in_loop_sol__0.txt | 8 ++-- ...tiple_costly_operations_in_loop_sol__0.txt | 2 + ...tiple_costly_operations_in_loop_sol__0.txt | 8 ++-- ...tiple_costly_operations_in_loop_sol__0.txt | 8 ++-- ...InLoop_0_4_25_delegatecall_loop_sol__0.txt | 6 ++- ...InLoop_0_5_16_delegatecall_loop_sol__0.txt | 6 ++- ...InLoop_0_6_11_delegatecall_loop_sol__0.txt | 2 + ...lInLoop_0_7_6_delegatecall_loop_sol__0.txt | 6 ++- ...lInLoop_0_8_0_delegatecall_loop_sol__0.txt | 2 + ...lueInLoop_0_4_25_msg_value_loop_sol__0.txt | 2 + ...lueInLoop_0_5_16_msg_value_loop_sol__0.txt | 2 + ...lueInLoop_0_6_11_msg_value_loop_sol__0.txt | 6 ++- ...alueInLoop_0_7_6_msg_value_loop_sol__0.txt | 2 + ...alueInLoop_0_8_0_msg_value_loop_sol__0.txt | 2 + ...p_0_4_25_multiple_calls_in_loop_sol__0.txt | 2 + ...p_0_5_16_multiple_calls_in_loop_sol__0.txt | 6 ++- ...p_0_6_11_multiple_calls_in_loop_sol__0.txt | 6 ++- ...op_0_7_6_multiple_calls_in_loop_sol__0.txt | 2 + 22 files changed, 164 insertions(+), 67 deletions(-) diff --git a/slither/detectors/statements/calls_in_loop.py b/slither/detectors/statements/calls_in_loop.py index d40d18f599..6b5ee61bcc 100644 --- a/slither/detectors/statements/calls_in_loop.py +++ b/slither/detectors/statements/calls_in_loop.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List, Optional, Tuple from slither.core.cfg.node import NodeType, Node from slither.detectors.abstract_detector import ( AbstractDetector, @@ -16,18 +16,24 @@ InternalCall, ) +Result = List[Tuple[Node, List[str]]] -def detect_call_in_loop(contract: Contract) -> List[Node]: - ret: List[Node] = [] + +def detect_call_in_loop(contract: Contract) -> Result: + ret: Result = [] for f in contract.functions_entry_points: if f.is_implemented: - call_in_loop(f.entry_point, 0, [], ret) + call_in_loop(f.entry_point, 0, [], [], ret) return ret def call_in_loop( - node: Optional[Node], in_loop_counter: int, visited: List[Node], ret: List[Node] + node: Optional[Node], + in_loop_counter: int, + visited: List[Node], + calls_stack: List[str], + ret: Result, ) -> None: if node is None: return @@ -41,18 +47,19 @@ def call_in_loop( elif node.type == NodeType.ENDLOOP: in_loop_counter -= 1 - if in_loop_counter > 0: - for ir in node.all_slithir_operations(): - if isinstance(ir, (LowLevelCall, HighLevelCall, Send, Transfer)): - if isinstance(ir, LibraryCall): - continue - ret.append(ir.node) - if isinstance(ir, (InternalCall)): - assert ir.function - call_in_loop(ir.function.entry_point, in_loop_counter, visited, ret) + for ir in node.irs: + if isinstance(ir, (LowLevelCall, HighLevelCall, Send, Transfer)) and in_loop_counter > 0: + if isinstance(ir, LibraryCall): + continue + ret.append((ir.node, calls_stack.copy())) + if isinstance(ir, (InternalCall)): + assert ir.function + calls_stack.append(node.function.canonical_name) + call_in_loop(ir.function.entry_point, in_loop_counter, visited, calls_stack, ret) + calls_stack.pop() for son in node.sons: - call_in_loop(son, in_loop_counter, visited, ret) + call_in_loop(son, in_loop_counter, visited, calls_stack, ret) class MultipleCallsInLoop(AbstractDetector): @@ -96,10 +103,16 @@ def _detect(self) -> List[Output]: results: List[Output] = [] for c in self.compilation_unit.contracts_derived: values = detect_call_in_loop(c) - for node in values: + for node, calls_stack in values: func = node.function info: DETECTOR_INFO = [func, " has external calls inside a loop: ", node, "\n"] + + if len(calls_stack) > 0: + info.append("\tCalls stack containing the loop:\n") + for call in calls_stack: + info.extend(["\t\t", call, "\n"]) + res = self.generate_result(info) results.append(res) diff --git a/slither/detectors/statements/costly_operations_in_loop.py b/slither/detectors/statements/costly_operations_in_loop.py index 53fa126477..c27b102a66 100644 --- a/slither/detectors/statements/costly_operations_in_loop.py +++ b/slither/detectors/statements/costly_operations_in_loop.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List, Optional, Tuple from slither.core.cfg.node import NodeType, Node from slither.detectors.abstract_detector import ( AbstractDetector, @@ -10,18 +10,24 @@ from slither.slithir.operations import InternalCall, OperationWithLValue from slither.core.variables.state_variable import StateVariable +Result = List[Tuple[Node, List[str]]] -def detect_costly_operations_in_loop(contract: Contract) -> List[Node]: - ret: List[Node] = [] + +def detect_costly_operations_in_loop(contract: Contract) -> Result: + ret: Result = [] for f in contract.functions_entry_points: if f.is_implemented: - costly_operations_in_loop(f.entry_point, 0, [], ret) + costly_operations_in_loop(f.entry_point, 0, [], [], ret) return ret def costly_operations_in_loop( - node: Optional[Node], in_loop_counter: int, visited: List[Node], ret: List[Node] + node: Optional[Node], + in_loop_counter: int, + visited: List[Node], + calls_stack: List[str], + ret: Result, ) -> None: if node is None: @@ -38,16 +44,20 @@ def costly_operations_in_loop( in_loop_counter -= 1 if in_loop_counter > 0: - for ir in node.all_slithir_operations(): + for ir in node.irs: # Ignore Array/Mapping/Struct types for now if isinstance(ir, OperationWithLValue) and isinstance(ir.lvalue, StateVariable): - ret.append(ir.node) + ret.append((ir.node, calls_stack.copy())) break if isinstance(ir, (InternalCall)) and ir.function: - costly_operations_in_loop(ir.function.entry_point, in_loop_counter, visited, ret) + calls_stack.append(node.function.canonical_name) + costly_operations_in_loop( + ir.function.entry_point, in_loop_counter, visited, calls_stack, ret + ) + calls_stack.pop() for son in node.sons: - costly_operations_in_loop(son, in_loop_counter, visited, ret) + costly_operations_in_loop(son, in_loop_counter, visited, calls_stack, ret) class CostlyOperationsInLoop(AbstractDetector): @@ -100,10 +110,16 @@ def _detect(self) -> List[Output]: results: List[Output] = [] for c in self.compilation_unit.contracts_derived: values = detect_costly_operations_in_loop(c) - for node in values: + for node, calls_stack in values: func = node.function info: DETECTOR_INFO = [func, " has costly operations inside a loop:\n"] info += ["\t- ", node, "\n"] + + if len(calls_stack) > 0: + info.append("\tCalls stack containing the loop:\n") + for call in calls_stack: + info.extend(["\t\t", call, "\n"]) + res = self.generate_result(info) results.append(res) diff --git a/slither/detectors/statements/delegatecall_in_loop.py b/slither/detectors/statements/delegatecall_in_loop.py index bdcf5dcae8..e28345f651 100644 --- a/slither/detectors/statements/delegatecall_in_loop.py +++ b/slither/detectors/statements/delegatecall_in_loop.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List, Optional, Tuple from slither.core.cfg.node import NodeType, Node from slither.detectors.abstract_detector import ( AbstractDetector, @@ -9,17 +9,23 @@ from slither.core.declarations import Contract from slither.utils.output import Output +Result = List[Tuple[Node, List[str]]] -def detect_delegatecall_in_loop(contract: Contract) -> List[Node]: - results: List[Node] = [] + +def detect_delegatecall_in_loop(contract: Contract) -> Result: + results: Result = [] for f in contract.functions_entry_points: if f.is_implemented and f.payable: - delegatecall_in_loop(f.entry_point, 0, [], results) + delegatecall_in_loop(f.entry_point, 0, [], [], results) return results def delegatecall_in_loop( - node: Optional[Node], in_loop_counter: int, visited: List[Node], results: List[Node] + node: Optional[Node], + in_loop_counter: int, + visited: List[Node], + calls_stack: List[str], + results: Result, ) -> None: if node is None: @@ -35,18 +41,22 @@ def delegatecall_in_loop( elif node.type == NodeType.ENDLOOP: in_loop_counter -= 1 - for ir in node.all_slithir_operations(): + for ir in node.irs: if ( in_loop_counter > 0 and isinstance(ir, (LowLevelCall)) and ir.function_name == "delegatecall" ): - results.append(ir.node) + results.append((ir.node, calls_stack.copy())) if isinstance(ir, (InternalCall)) and ir.function: - delegatecall_in_loop(ir.function.entry_point, in_loop_counter, visited, results) + calls_stack.append(node.function.canonical_name) + delegatecall_in_loop( + ir.function.entry_point, in_loop_counter, visited, calls_stack, results + ) + calls_stack.pop() for son in node.sons: - delegatecall_in_loop(son, in_loop_counter, visited, results) + delegatecall_in_loop(son, in_loop_counter, visited, calls_stack, results) class DelegatecallInLoop(AbstractDetector): @@ -95,7 +105,7 @@ def _detect(self) -> List[Output]: results: List[Output] = [] for c in self.compilation_unit.contracts_derived: values = detect_delegatecall_in_loop(c) - for node in values: + for node, calls_stack in values: func = node.function info: DETECTOR_INFO = [ @@ -104,6 +114,12 @@ def _detect(self) -> List[Output]: node, "\n", ] + + if len(calls_stack) > 0: + info.append("\tCalls stack containing the loop:\n") + for call in calls_stack: + info.extend(["\t\t", call, "\n"]) + res = self.generate_result(info) results.append(res) diff --git a/slither/detectors/statements/msg_value_in_loop.py b/slither/detectors/statements/msg_value_in_loop.py index 290447aa8e..f6c66a9780 100644 --- a/slither/detectors/statements/msg_value_in_loop.py +++ b/slither/detectors/statements/msg_value_in_loop.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List, Optional, Tuple from slither.core.cfg.node import NodeType, Node from slither.detectors.abstract_detector import ( AbstractDetector, @@ -12,17 +12,23 @@ from slither.core.variables import Variable from slither.core.expressions.literal import Literal +Result = List[Tuple[Node, List[str]]] -def detect_msg_value_in_loop(contract: Contract) -> List[Node]: - results: List[Node] = [] + +def detect_msg_value_in_loop(contract: Contract) -> Result: + results: Result = [] for f in contract.functions_entry_points: if f.is_implemented and f.payable: - msg_value_in_loop(f.entry_point, 0, [], results) + msg_value_in_loop(f.entry_point, 0, [], [], results) return results def msg_value_in_loop( - node: Optional[Node], in_loop_counter: int, visited: List[Node], results: List[Node] + node: Optional[Node], + in_loop_counter: int, + visited: List[Node], + calls_stack: List[str], + results: Result, ) -> None: if node is None: @@ -38,7 +44,7 @@ def msg_value_in_loop( elif node.type == NodeType.ENDLOOP: in_loop_counter -= 1 - for ir in node.all_slithir_operations(): + for ir in node.irs: if in_loop_counter > 0 and SolidityVariableComposed("msg.value") in ir.read: # If we find a conditional expression with msg.value and is compared to 0 we don't report it if ir.node.is_conditional() and SolidityVariableComposed("msg.value") in ir.read: @@ -55,12 +61,16 @@ def msg_value_in_loop( and str(compared_to.expression.value) == "0" ): continue - results.append(ir.node) + results.append((ir.node, calls_stack.copy())) if isinstance(ir, (InternalCall)): - msg_value_in_loop(ir.function.entry_point, in_loop_counter, visited, results) + calls_stack.append(node.function.canonical_name) + msg_value_in_loop( + ir.function.entry_point, in_loop_counter, visited, calls_stack, results + ) + calls_stack.pop() for son in node.sons: - msg_value_in_loop(son, in_loop_counter, visited, results) + msg_value_in_loop(son, in_loop_counter, visited, calls_stack, results) class MsgValueInLoop(AbstractDetector): @@ -105,10 +115,16 @@ def _detect(self) -> List[Output]: results: List[Output] = [] for c in self.compilation_unit.contracts_derived: values = detect_msg_value_in_loop(c) - for node in values: + for node, calls_stack in values: func = node.function info: DETECTOR_INFO = [func, " use msg.value in a loop: ", node, "\n"] + + if len(calls_stack) > 0: + info.append("\tCalls stack containing the loop:\n") + for call in calls_stack: + info.extend(["\t\t", call, "\n"]) + res = self.generate_result(info) results.append(res) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_4_25_multiple_costly_operations_in_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_4_25_multiple_costly_operations_in_loop_sol__0.txt index 7b114acb78..7a2052c05d 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_4_25_multiple_costly_operations_in_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_4_25_multiple_costly_operations_in_loop_sol__0.txt @@ -1,12 +1,14 @@ CostlyOperationsInLoopBase.bad_base() (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#5-9) has costly operations inside a loop: - state_variable_base ++ (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#7) -CostlyOperationsInLoop.bad3_internal() (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#41-43) has costly operations inside a loop: - - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#42) - CostlyOperationsInLoop.bad2() (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#26-33) has costly operations inside a loop: - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#31) +CostlyOperationsInLoop.bad3_internal() (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#41-43) has costly operations inside a loop: + - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#42) + Calls stack containing the loop: + CostlyOperationsInLoop.bad3() + CostlyOperationsInLoop.bad() (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#20-24) has costly operations inside a loop: - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.4.25/multiple_costly_operations_in_loop.sol#22) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_5_16_multiple_costly_operations_in_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_5_16_multiple_costly_operations_in_loop_sol__0.txt index 6d2fd27e1a..55f002d4a1 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_5_16_multiple_costly_operations_in_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_5_16_multiple_costly_operations_in_loop_sol__0.txt @@ -6,6 +6,8 @@ CostlyOperationsInLoop.bad2() (tests/e2e/detectors/test_data/costly-loop/0.5.16/ CostlyOperationsInLoop.bad3_internal() (tests/e2e/detectors/test_data/costly-loop/0.5.16/multiple_costly_operations_in_loop.sol#41-43) has costly operations inside a loop: - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.5.16/multiple_costly_operations_in_loop.sol#42) + Calls stack containing the loop: + CostlyOperationsInLoop.bad3() CostlyOperationsInLoop.bad() (tests/e2e/detectors/test_data/costly-loop/0.5.16/multiple_costly_operations_in_loop.sol#20-24) has costly operations inside a loop: - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.5.16/multiple_costly_operations_in_loop.sol#22) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_6_11_multiple_costly_operations_in_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_6_11_multiple_costly_operations_in_loop_sol__0.txt index d7ca011c8c..7da87c8915 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_6_11_multiple_costly_operations_in_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_6_11_multiple_costly_operations_in_loop_sol__0.txt @@ -4,9 +4,11 @@ CostlyOperationsInLoop.bad() (tests/e2e/detectors/test_data/costly-loop/0.6.11/m CostlyOperationsInLoop.bad2() (tests/e2e/detectors/test_data/costly-loop/0.6.11/multiple_costly_operations_in_loop.sol#26-33) has costly operations inside a loop: - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.6.11/multiple_costly_operations_in_loop.sol#31) -CostlyOperationsInLoop.bad3_internal() (tests/e2e/detectors/test_data/costly-loop/0.6.11/multiple_costly_operations_in_loop.sol#41-43) has costly operations inside a loop: - - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.6.11/multiple_costly_operations_in_loop.sol#42) - CostlyOperationsInLoopBase.bad_base() (tests/e2e/detectors/test_data/costly-loop/0.6.11/multiple_costly_operations_in_loop.sol#5-9) has costly operations inside a loop: - state_variable_base ++ (tests/e2e/detectors/test_data/costly-loop/0.6.11/multiple_costly_operations_in_loop.sol#7) +CostlyOperationsInLoop.bad3_internal() (tests/e2e/detectors/test_data/costly-loop/0.6.11/multiple_costly_operations_in_loop.sol#41-43) has costly operations inside a loop: + - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.6.11/multiple_costly_operations_in_loop.sol#42) + Calls stack containing the loop: + CostlyOperationsInLoop.bad3() + diff --git a/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_7_6_multiple_costly_operations_in_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_7_6_multiple_costly_operations_in_loop_sol__0.txt index da2804728c..46607c6c98 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_7_6_multiple_costly_operations_in_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_CostlyOperationsInLoop_0_7_6_multiple_costly_operations_in_loop_sol__0.txt @@ -1,12 +1,14 @@ -CostlyOperationsInLoop.bad3_internal() (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#41-43) has costly operations inside a loop: - - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#42) - CostlyOperationsInLoopBase.bad_base() (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#5-9) has costly operations inside a loop: - state_variable_base ++ (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#7) CostlyOperationsInLoop.bad2() (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#26-33) has costly operations inside a loop: - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#31) +CostlyOperationsInLoop.bad3_internal() (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#41-43) has costly operations inside a loop: + - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#42) + Calls stack containing the loop: + CostlyOperationsInLoop.bad3() + CostlyOperationsInLoop.bad() (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#20-24) has costly operations inside a loop: - state_variable ++ (tests/e2e/detectors/test_data/costly-loop/0.7.6/multiple_costly_operations_in_loop.sol#22) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_4_25_delegatecall_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_4_25_delegatecall_loop_sol__0.txt index a64167702b..f38152f7ad 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_4_25_delegatecall_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_4_25_delegatecall_loop_sol__0.txt @@ -1,6 +1,8 @@ +C.bad2_internal(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.4.25/delegatecall_loop.sol#19-23) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.4.25/delegatecall_loop.sol#21) + Calls stack containing the loop: + C.bad2(address[]) + C.bad(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.4.25/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.4.25/delegatecall_loop.sol#7) C.bad3(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.4.25/delegatecall_loop.sol#25-31) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.4.25/delegatecall_loop.sol#28) -C.bad2_internal(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.4.25/delegatecall_loop.sol#19-23) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.4.25/delegatecall_loop.sol#21) - diff --git a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_5_16_delegatecall_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_5_16_delegatecall_loop_sol__0.txt index e6ea14e791..320eb7d94d 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_5_16_delegatecall_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_5_16_delegatecall_loop_sol__0.txt @@ -1,6 +1,8 @@ C.bad3(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.5.16/delegatecall_loop.sol#25-31) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.5.16/delegatecall_loop.sol#28) -C.bad2_internal(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.5.16/delegatecall_loop.sol#19-23) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.5.16/delegatecall_loop.sol#21) - C.bad(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.5.16/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.5.16/delegatecall_loop.sol#7) +C.bad2_internal(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.5.16/delegatecall_loop.sol#19-23) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.5.16/delegatecall_loop.sol#21) + Calls stack containing the loop: + C.bad2(address[]) + diff --git a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_6_11_delegatecall_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_6_11_delegatecall_loop_sol__0.txt index ce50766feb..621679964f 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_6_11_delegatecall_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_6_11_delegatecall_loop_sol__0.txt @@ -1,4 +1,6 @@ C.bad2_internal(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.6.11/delegatecall_loop.sol#19-23) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.6.11/delegatecall_loop.sol#21) + Calls stack containing the loop: + C.bad2(address[]) C.bad(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.6.11/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.6.11/delegatecall_loop.sol#7) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_7_6_delegatecall_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_7_6_delegatecall_loop_sol__0.txt index 9d4decf4d2..f5c4f228bf 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_7_6_delegatecall_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_7_6_delegatecall_loop_sol__0.txt @@ -1,6 +1,8 @@ +C.bad2_internal(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.7.6/delegatecall_loop.sol#19-23) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.7.6/delegatecall_loop.sol#21) + Calls stack containing the loop: + C.bad2(address[]) + C.bad3(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.7.6/delegatecall_loop.sol#25-31) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.7.6/delegatecall_loop.sol#28) C.bad(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.7.6/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.7.6/delegatecall_loop.sol#7) -C.bad2_internal(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.7.6/delegatecall_loop.sol#19-23) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.7.6/delegatecall_loop.sol#21) - diff --git a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_8_0_delegatecall_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_8_0_delegatecall_loop_sol__0.txt index d3d9f047c3..f3a5e9d2f0 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_8_0_delegatecall_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_DelegatecallInLoop_0_8_0_delegatecall_loop_sol__0.txt @@ -1,4 +1,6 @@ C.bad2_internal(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.8.0/delegatecall_loop.sol#19-23) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.8.0/delegatecall_loop.sol#21) + Calls stack containing the loop: + C.bad2(address[]) C.bad(address[]) (tests/e2e/detectors/test_data/delegatecall-loop/0.8.0/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/e2e/detectors/test_data/delegatecall-loop/0.8.0/delegatecall_loop.sol#7) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_4_25_msg_value_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_4_25_msg_value_loop_sol__0.txt index b694677bdd..0d2f9a9456 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_4_25_msg_value_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_4_25_msg_value_loop_sol__0.txt @@ -3,4 +3,6 @@ C.bad(address[]) (tests/e2e/detectors/test_data/msg-value-loop/0.4.25/msg_value_ C.bad3(address[]) (tests/e2e/detectors/test_data/msg-value-loop/0.4.25/msg_value_loop.sol#21-27) use msg.value in a loop: balances[receivers[j]] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.4.25/msg_value_loop.sol#24) C.bad2_internal(address) (tests/e2e/detectors/test_data/msg-value-loop/0.4.25/msg_value_loop.sol#17-19) use msg.value in a loop: balances[a] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.4.25/msg_value_loop.sol#18) + Calls stack containing the loop: + C.bad2(address[]) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_5_16_msg_value_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_5_16_msg_value_loop_sol__0.txt index 66cd57b2b8..ef1ab2eb88 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_5_16_msg_value_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_5_16_msg_value_loop_sol__0.txt @@ -1,6 +1,8 @@ C.bad3(address[]) (tests/e2e/detectors/test_data/msg-value-loop/0.5.16/msg_value_loop.sol#21-27) use msg.value in a loop: balances[receivers[j]] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.5.16/msg_value_loop.sol#24) C.bad2_internal(address) (tests/e2e/detectors/test_data/msg-value-loop/0.5.16/msg_value_loop.sol#17-19) use msg.value in a loop: balances[a] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.5.16/msg_value_loop.sol#18) + Calls stack containing the loop: + C.bad2(address[]) C.bad(address[]) (tests/e2e/detectors/test_data/msg-value-loop/0.5.16/msg_value_loop.sol#5-9) use msg.value in a loop: balances[receivers[i]] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.5.16/msg_value_loop.sol#7) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_6_11_msg_value_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_6_11_msg_value_loop_sol__0.txt index 4ae4ca2a81..1744c2c40d 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_6_11_msg_value_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_6_11_msg_value_loop_sol__0.txt @@ -1,6 +1,8 @@ -C.bad2_internal(address) (tests/e2e/detectors/test_data/msg-value-loop/0.6.11/msg_value_loop.sol#17-19) use msg.value in a loop: balances[a] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.6.11/msg_value_loop.sol#18) - C.bad(address[]) (tests/e2e/detectors/test_data/msg-value-loop/0.6.11/msg_value_loop.sol#5-9) use msg.value in a loop: balances[receivers[i]] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.6.11/msg_value_loop.sol#7) C.bad3(address[]) (tests/e2e/detectors/test_data/msg-value-loop/0.6.11/msg_value_loop.sol#21-27) use msg.value in a loop: balances[receivers[j]] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.6.11/msg_value_loop.sol#24) +C.bad2_internal(address) (tests/e2e/detectors/test_data/msg-value-loop/0.6.11/msg_value_loop.sol#17-19) use msg.value in a loop: balances[a] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.6.11/msg_value_loop.sol#18) + Calls stack containing the loop: + C.bad2(address[]) + diff --git a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_7_6_msg_value_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_7_6_msg_value_loop_sol__0.txt index 0ec9098f7a..6405ebba33 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_7_6_msg_value_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_7_6_msg_value_loop_sol__0.txt @@ -1,4 +1,6 @@ C.bad2_internal(address) (tests/e2e/detectors/test_data/msg-value-loop/0.7.6/msg_value_loop.sol#17-19) use msg.value in a loop: balances[a] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.7.6/msg_value_loop.sol#18) + Calls stack containing the loop: + C.bad2(address[]) C.bad3(address[]) (tests/e2e/detectors/test_data/msg-value-loop/0.7.6/msg_value_loop.sol#21-27) use msg.value in a loop: balances[receivers[j]] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.7.6/msg_value_loop.sol#24) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_8_0_msg_value_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_8_0_msg_value_loop_sol__0.txt index 6f36e2a630..2a490a34a0 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_8_0_msg_value_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_MsgValueInLoop_0_8_0_msg_value_loop_sol__0.txt @@ -1,4 +1,6 @@ C.bad2_internal(address) (tests/e2e/detectors/test_data/msg-value-loop/0.8.0/msg_value_loop.sol#17-19) use msg.value in a loop: balances[a] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.8.0/msg_value_loop.sol#18) + Calls stack containing the loop: + C.bad2(address[]) C.bad3(address[]) (tests/e2e/detectors/test_data/msg-value-loop/0.8.0/msg_value_loop.sol#21-27) use msg.value in a loop: balances[receivers[j]] += msg.value (tests/e2e/detectors/test_data/msg-value-loop/0.8.0/msg_value_loop.sol#24) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_4_25_multiple_calls_in_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_4_25_multiple_calls_in_loop_sol__0.txt index 5340988510..26717502ac 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_4_25_multiple_calls_in_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_4_25_multiple_calls_in_loop_sol__0.txt @@ -3,6 +3,8 @@ CallInLoop.bad() (tests/e2e/detectors/test_data/calls-loop/0.4.25/multiple_calls CallInLoop.bad2() (tests/e2e/detectors/test_data/calls-loop/0.4.25/multiple_calls_in_loop.sol#30-37) has external calls inside a loop: destinations[i].transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.4.25/multiple_calls_in_loop.sol#35) CallInLoop.bad3_internal(address,uint256) (tests/e2e/detectors/test_data/calls-loop/0.4.25/multiple_calls_in_loop.sol#45-47) has external calls inside a loop: a.transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.4.25/multiple_calls_in_loop.sol#46) + Calls stack containing the loop: + CallInLoop.bad3() CallInLoopBase.bad_base() (tests/e2e/detectors/test_data/calls-loop/0.4.25/multiple_calls_in_loop.sol#9-13) has external calls inside a loop: destinations_base[i].transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.4.25/multiple_calls_in_loop.sol#11) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_5_16_multiple_calls_in_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_5_16_multiple_calls_in_loop_sol__0.txt index ffa813d874..16efb90ae9 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_5_16_multiple_calls_in_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_5_16_multiple_calls_in_loop_sol__0.txt @@ -1,8 +1,10 @@ -CallInLoop.bad3_internal(address,uint256) (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#45-47) has external calls inside a loop: address(uint160(a)).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#46) - CallInLoop.bad() (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#24-28) has external calls inside a loop: address(uint160(destinations[i])).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#26) CallInLoop.bad2() (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#30-37) has external calls inside a loop: address(uint160(destinations[i])).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#35) CallInLoopBase.bad_base() (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#9-13) has external calls inside a loop: address(uint160(destinations_base[i])).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#11) +CallInLoop.bad3_internal(address,uint256) (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#45-47) has external calls inside a loop: address(uint160(a)).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.5.16/multiple_calls_in_loop.sol#46) + Calls stack containing the loop: + CallInLoop.bad3() + diff --git a/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_6_11_multiple_calls_in_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_6_11_multiple_calls_in_loop_sol__0.txt index 4601b6909d..d1d584c1a2 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_6_11_multiple_calls_in_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_6_11_multiple_calls_in_loop_sol__0.txt @@ -1,7 +1,9 @@ -CallInLoop.bad3_internal(address,uint256) (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#45-47) has external calls inside a loop: address(uint160(a)).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#46) - CallInLoopBase.bad_base() (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#9-13) has external calls inside a loop: address(uint160(destinations_base[i])).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#11) +CallInLoop.bad3_internal(address,uint256) (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#45-47) has external calls inside a loop: address(uint160(a)).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#46) + Calls stack containing the loop: + CallInLoop.bad3() + CallInLoop.bad() (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#24-28) has external calls inside a loop: address(uint160(destinations[i])).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#26) CallInLoop.bad2() (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#30-37) has external calls inside a loop: address(uint160(destinations[i])).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.6.11/multiple_calls_in_loop.sol#35) diff --git a/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_7_6_multiple_calls_in_loop_sol__0.txt b/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_7_6_multiple_calls_in_loop_sol__0.txt index 7d67fde528..9951c77f43 100644 --- a/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_7_6_multiple_calls_in_loop_sol__0.txt +++ b/tests/e2e/detectors/snapshots/detectors__detector_MultipleCallsInLoop_0_7_6_multiple_calls_in_loop_sol__0.txt @@ -1,6 +1,8 @@ CallInLoop.bad() (tests/e2e/detectors/test_data/calls-loop/0.7.6/multiple_calls_in_loop.sol#24-28) has external calls inside a loop: address(uint160(destinations[i])).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.7.6/multiple_calls_in_loop.sol#26) CallInLoop.bad3_internal(address,uint256) (tests/e2e/detectors/test_data/calls-loop/0.7.6/multiple_calls_in_loop.sol#45-47) has external calls inside a loop: address(uint160(a)).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.7.6/multiple_calls_in_loop.sol#46) + Calls stack containing the loop: + CallInLoop.bad3() CallInLoopBase.bad_base() (tests/e2e/detectors/test_data/calls-loop/0.7.6/multiple_calls_in_loop.sol#9-13) has external calls inside a loop: address(uint160(destinations_base[i])).transfer(i) (tests/e2e/detectors/test_data/calls-loop/0.7.6/multiple_calls_in_loop.sol#11)