mirror of https://github.com/ConsenSys/mythril
Add the first code to build transaction traces from the storage state at STOP instruction and a combination strategy to build felxibly large trace chain combinations. Starting from the trace of a constructor and using the traces of the external and public functions of a contract. All possible programmstates to a certain depth can be reached.
parent
c3131a579d
commit
0f458e7541
@ -0,0 +1,22 @@ |
|||||||
|
from mythril.analysis.report import Issue |
||||||
|
import logging |
||||||
|
|
||||||
|
|
||||||
|
''' |
||||||
|
Build execution traces from the statespace |
||||||
|
''' |
||||||
|
|
||||||
|
def print_obj(obj): |
||||||
|
print() |
||||||
|
print(obj) |
||||||
|
# print(dir(obj)) |
||||||
|
print() |
||||||
|
|
||||||
|
|
||||||
|
def execute(statespace): |
||||||
|
|
||||||
|
logging.debug("Executing module: Transaction End") |
||||||
|
|
||||||
|
traces = [] |
||||||
|
|
||||||
|
return [] |
@ -0,0 +1,27 @@ |
|||||||
|
import logging |
||||||
|
from mythril.solidnotary.transactiontrace import TransactionTrace |
||||||
|
|
||||||
|
class SolidNotary: |
||||||
|
|
||||||
|
def __init__(self): |
||||||
|
# Todo Parse Annotations and store them in an additional structure |
||||||
|
# Todo receive a list of files or a file, these are modified for the analysis |
||||||
|
pass |
||||||
|
|
||||||
|
def notarize(self): |
||||||
|
# Todo Instantiate an instance of Mythril, analyze and print the result |
||||||
|
# Todo Find how they are storing results |
||||||
|
pass |
||||||
|
|
||||||
|
def get_transaction_traces(statespace): |
||||||
|
logging.debug("Executing module: Transaction End") |
||||||
|
|
||||||
|
traces = [] |
||||||
|
|
||||||
|
for k in statespace.nodes: |
||||||
|
node = statespace.nodes[k] |
||||||
|
for state in node.states: |
||||||
|
instruction = state.get_current_instruction() |
||||||
|
if instruction['opcode'] == "STOP": |
||||||
|
traces.append(TransactionTrace(state.environment.active_account.storage)) |
||||||
|
return traces |
@ -0,0 +1,54 @@ |
|||||||
|
class TransactionTrace: |
||||||
|
|
||||||
|
def __init__(self, storage): |
||||||
|
self.storage = storage |
||||||
|
# Todo Identifiy addional trace information such as blocknumber and more |
||||||
|
|
||||||
|
""" |
||||||
|
Applies the new trace tt on a possibly even changed trace self. |
||||||
|
""" |
||||||
|
def apply_trace(self, tt): |
||||||
|
if tt is None: |
||||||
|
return self |
||||||
|
# Todo implement application of a trace on a existing trace. |
||||||
|
return None |
||||||
|
|
||||||
|
def apply_traces_parallel(self, traces): |
||||||
|
combined_traces = [] |
||||||
|
for trace in traces: |
||||||
|
combined_traces.append(self.apply_trace(trace)) |
||||||
|
return combined_traces |
||||||
|
|
||||||
|
def apply_exact_trace_levels(self, traces, depth): |
||||||
|
# Todo maybe some faster trace build not building one level at a time to e.g. |
||||||
|
# Todo reach level 17 but build 2, then 4, then 8 and then 16 then 17 |
||||||
|
trace_lvl_n = [self] |
||||||
|
for i in range(depth): |
||||||
|
trace_lvl_np1 = [] |
||||||
|
for trace in trace_lvl_n: |
||||||
|
trace_lvl_np1.append(trace.apply_traces_parallel(traces)) |
||||||
|
if deep_equals(trace_lvl_np1, trace_lvl_n): # Fixpoint detected, function needs to ignore lists, dicts and objects. |
||||||
|
return trace_lvl_n |
||||||
|
trace_lvl_n = trace_lvl_np1 |
||||||
|
return trace_lvl_n |
||||||
|
|
||||||
|
def apply_up_to_trace_levels(self, traces, depth): |
||||||
|
traces_up_to = [[self]] # elements are trace_levels |
||||||
|
for i in range(depth): |
||||||
|
trace_lvl_np1 = [] |
||||||
|
for trace in traces_up_to[-1]: |
||||||
|
trace_lvl_np1.append(trace.apply_traces_parallel(traces)) |
||||||
|
for trace_lvl_i in traces_up_to: |
||||||
|
# the following might be faster to check when using a content representing hash |
||||||
|
if deep_equals(trace_lvl_np1, trace_lvl_i): # cycle in the traces of trace chains detected: levels |
||||||
|
# while repeat themselves, function needs to ignore lists, dicts and objects. |
||||||
|
return traces_up_to |
||||||
|
traces_up_to.append(trace_lvl_np1) |
||||||
|
return traces_up_to |
||||||
|
|
||||||
|
""" |
||||||
|
Either do only deep checing here and use the proper trace or storage_slot reduction in the apply function. Or do |
||||||
|
both here. |
||||||
|
""" |
||||||
|
def deep_equals(trace_lvl1, trace_lvl2): |
||||||
|
pass |
Loading…
Reference in new issue