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, gasprice,
callvalue, callvalue,
origin, origin,
code=None,
calldata_type=CalldataType.SYMBOLIC, calldata_type=CalldataType.SYMBOLIC,
): ):
# Metadata # Metadata
@ -66,7 +67,9 @@ class Environment:
self.active_function_name = "" self.active_function_name = ""
self.address = BitVecVal(int(active_account.address, 16), 256) 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.sender = sender
self.calldata = calldata self.calldata = calldata
@ -144,12 +147,12 @@ class GlobalState:
self.op_code = "" self.op_code = ""
def __copy__(self): def __copy__(self):
accounts = copy(self.accounts) accounts = copy(self.accounts)
environment = copy(self.environment) environment = copy(self.environment)
mstate = deepcopy(self.mstate) 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 #TODO: remove this, as two instructions are confusing
def get_current_instruction(self): def get_current_instruction(self):

@ -1,4 +1,5 @@
import logging import logging
from mythril.disassembler.disassembly import Disassembly
from mythril.laser.ethereum.state import GlobalState, Environment, CalldataType from mythril.laser.ethereum.state import GlobalState, Environment, CalldataType
from mythril.laser.ethereum.cfg import Node, Edge, JumpType from mythril.laser.ethereum.cfg import Node, Edge, JumpType
from z3 import BitVec from z3 import BitVec
@ -58,3 +59,59 @@ class MessageCall:
evm.exec() evm.exec()
logging.info("Execution complete") logging.info("Execution complete")
logging.info("Achieved {0:.3g}% coverage".format(evm.coverage)) 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