From f6749a1e9729c4efa94d0a84ca339260d6db1ca3 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Sun, 28 Oct 2018 18:51:48 +0100 Subject: [PATCH 1/2] Bugfix search_children --- mythril/analysis/modules/external_calls.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index 1b45205a..9f581dba 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -5,7 +5,7 @@ from mythril.analysis import solver from mythril.analysis.swc_data import REENTRANCY import re import logging - +from mythril.laser.ethereum.cfg import JumpType """ MODULE DESCRIPTION: @@ -30,16 +30,15 @@ def search_children(statespace, node, start_index=0, depth=0, results=None): for j in range(start_index, n_states): if node.states[j].get_current_instruction()["opcode"] == "SSTORE": results.append(node.states[j].get_current_instruction()["address"]) - children = [] for edge in statespace.edges: - if edge.node_from == node.uid: + if edge.node_from == node.uid and edge.type != JumpType.Transaction: children.append(statespace.nodes[edge.node_to]) if len(children): for node in children: - return search_children( + results += search_children( statespace, node, depth=depth + 1, results=results ) From 31a8107dafdf20a67360d39d1b11cd1c9070f6b5 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Sun, 28 Oct 2018 18:55:51 +0100 Subject: [PATCH 2/2] Make search_children compatible with multi transactional analysis --- mythril/analysis/modules/external_calls.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index 9f581dba..a5fbfded 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -16,7 +16,9 @@ Check for call.value()() to external addresses MAX_SEARCH_DEPTH = 64 -def search_children(statespace, node, start_index=0, depth=0, results=None): +def search_children( + statespace, node, transaction_id, start_index=0, depth=0, results=None +): if results is None: results = [] logging.debug("SEARCHING NODE %d", node.uid) @@ -28,7 +30,10 @@ def search_children(statespace, node, start_index=0, depth=0, results=None): if n_states > start_index: for j in range(start_index, n_states): - if node.states[j].get_current_instruction()["opcode"] == "SSTORE": + if ( + node.states[j].get_current_instruction()["opcode"] == "SSTORE" + and node.states[j].current_transaction.id == transaction_id + ): results.append(node.states[j].get_current_instruction()["address"]) children = [] @@ -39,7 +44,7 @@ def search_children(statespace, node, start_index=0, depth=0, results=None): if len(children): for node in children: results += search_children( - statespace, node, depth=depth + 1, results=results + statespace, node, transaction_id, depth=depth + 1, results=results ) return results @@ -149,7 +154,12 @@ def execute(statespace): # Check for SSTORE in remaining instructions in current node & nodes down the CFG state_change_addresses = search_children( - statespace, call.node, call.state_index + 1, depth=0, results=[] + statespace, + call.node, + call.state.current_transaction.id, + call.state_index + 1, + depth=0, + results=[], ) logging.debug(