Contract creation init

pull/404/head
Joran Honig 6 years ago
parent 5955abc1e1
commit 9bcfd70afb
  1. 9
      mythril/laser/ethereum/state.py
  2. 57
      mythril/laser/ethereum/transaction.py

@ -58,6 +58,7 @@ class Environment:
gasprice,
callvalue,
origin,
code=None,
calldata_type=CalldataType.SYMBOLIC,
):
# Metadata
@ -66,7 +67,9 @@ class Environment:
self.active_function_name = ""
self.address = BitVecVal(int(active_account.address, 16), 256)
self.code = active_account.code
# Ib
self.code = active_account.code if code is None else code
self.sender = sender
self.calldata = calldata
@ -144,12 +147,12 @@ class GlobalState:
self.op_code = ""
def __copy__(self):
accounts = copy(self.accounts)
environment = copy(self.environment)
mstate = deepcopy(self.mstate)
return GlobalState(accounts, environment, self.node, mstate)
call_stack = copy(self.call_stack)
return GlobalState(accounts, environment, self.node, mstate, call_stack=call_stack)
#TODO: remove this, as two instructions are confusing
def get_current_instruction(self):

@ -1,4 +1,5 @@
import logging
from mythril.disassembler.disassembly import Disassembly
from mythril.laser.ethereum.state import GlobalState, Environment, CalldataType
from mythril.laser.ethereum.cfg import Node, Edge, JumpType
from z3 import BitVec
@ -58,3 +59,59 @@ class MessageCall:
evm.exec()
logging.info("Execution complete")
logging.info("Achieved {0:.3g}% coverage".format(evm.coverage))
class ContractCreation:
""" Represents a contract creation transaction"""
def __init__(self, creation_code):
"""
Constructor for ContractCreation, sets up all symbolic parameters
:param creation_code: Contract creation code for this contract
"""
self.caller = BitVec("caller", 256)
self.gas_price = BitVec("gasprice", 256)
self.origin = BitVec("origin", 256)
self.init = creation_code
self.open_states = None
@property
def has_ran(self):
return self.open_states is not None
def run(self, open_world_states: list, evm):
""" Runs this transaction on the evm starting from the open world states """
# Consume the open states
open_states = open_world_states[:]
del open_world_states[:]
for open_world_state in open_states:
new_account = open_world_state.create_account()
# Initialize the execution environment
environment = Environment(
new_account,
self.caller,
[],
self.gas_price,
None,
self.origin,
code=Disassembly(self.init),
calldata_type=CalldataType.SYMBOLIC,
)
new_node = Node(environment.active_account.contract_name)
evm.instructions_covered = [False for _ in environment.code.instruction_list]
evm.nodes[new_node.uid] = new_node
if open_world_state.node:
evm.edges.append(Edge(open_world_state.node.uid, new_node.uid, edge_type=JumpType.Transaction, condition=None))
global_state = GlobalState(open_world_state, environment, new_node)
new_node.states.append(global_state)
evm.work_list.append(global_state)
evm.exec()
logging.info("Execution complete")
logging.info("Achieved {0:.3g}% coverage".format(evm.coverage))

Loading…
Cancel
Save