|
|
@ -5,7 +5,7 @@ from mythril.analysis import solver |
|
|
|
from mythril.analysis.swc_data import REENTRANCY |
|
|
|
from mythril.analysis.swc_data import REENTRANCY |
|
|
|
import re |
|
|
|
import re |
|
|
|
import logging |
|
|
|
import logging |
|
|
|
|
|
|
|
from mythril.laser.ethereum.cfg import JumpType |
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
|
""" |
|
|
|
MODULE DESCRIPTION: |
|
|
|
MODULE DESCRIPTION: |
|
|
@ -16,7 +16,9 @@ Check for call.value()() to external addresses |
|
|
|
MAX_SEARCH_DEPTH = 64 |
|
|
|
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: |
|
|
|
if results is None: |
|
|
|
results = [] |
|
|
|
results = [] |
|
|
|
logging.debug("SEARCHING NODE %d", node.uid) |
|
|
|
logging.debug("SEARCHING NODE %d", node.uid) |
|
|
@ -28,19 +30,21 @@ def search_children(statespace, node, start_index=0, depth=0, results=None): |
|
|
|
if n_states > start_index: |
|
|
|
if n_states > start_index: |
|
|
|
|
|
|
|
|
|
|
|
for j in range(start_index, n_states): |
|
|
|
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"]) |
|
|
|
results.append(node.states[j].get_current_instruction()["address"]) |
|
|
|
|
|
|
|
|
|
|
|
children = [] |
|
|
|
children = [] |
|
|
|
|
|
|
|
|
|
|
|
for edge in statespace.edges: |
|
|
|
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]) |
|
|
|
children.append(statespace.nodes[edge.node_to]) |
|
|
|
|
|
|
|
|
|
|
|
if len(children): |
|
|
|
if len(children): |
|
|
|
for node in children: |
|
|
|
for node in children: |
|
|
|
return search_children( |
|
|
|
results += search_children( |
|
|
|
statespace, node, depth=depth + 1, results=results |
|
|
|
statespace, node, transaction_id, depth=depth + 1, results=results |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
return results |
|
|
|
return results |
|
|
@ -150,7 +154,12 @@ def execute(statespace): |
|
|
|
# Check for SSTORE in remaining instructions in current node & nodes down the CFG |
|
|
|
# Check for SSTORE in remaining instructions in current node & nodes down the CFG |
|
|
|
|
|
|
|
|
|
|
|
state_change_addresses = search_children( |
|
|
|
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( |
|
|
|
logging.debug( |
|
|
|