Implement contract creation test

pull/419/head
Joran Honig 6 years ago
commit 5605911421
  1. 41
      mythril/laser/ethereum/instructions.py
  2. 1
      mythril/laser/ethereum/state.py
  3. 0
      tests/instructions/__init__.py
  4. 20
      tests/instructions/codecopy_test.py
  5. 2
      tests/report_test.py

@ -517,9 +517,44 @@ class Instruction:
@instruction @instruction
def codecopy_(self, global_state): def codecopy_(self, global_state):
# FIXME: not implemented memory_offset, code_offset, size = global_state.mstate.stack.pop(), global_state.mstate.stack.pop(), global_state.mstate.stack.pop()
state = global_state.mstate
start, s1, size = state.stack.pop(), state.stack.pop(), state.stack.pop() try:
concrete_memory_offset = helper.get_concrete_int(memory_offset)
except AttributeError:
logging.debug("Unsupported symbolic memory offset in CODECOPY")
return [global_state]
try:
concrete_size = helper.get_concrete_int(size)
global_state.mstate.mem_extend(concrete_memory_offset, concrete_size)
except:
# except both attribute error and Exception
global_state.mstate.mem_extend(concrete_memory_offset, 1)
global_state.mstate.memory[concrete_memory_offset] = \
BitVec("code({})".format(global_state.environment.active_account.contract_name), 256)
return [global_state]
try:
concrete_code_offset = helper.get_concrete_int(code_offset)
except AttributeError:
logging.debug("Unsupported symbolic code offset in CODECOPY")
global_state.mstate.mem_extend(concrete_memory_offset, concrete_size)
for i in range(concrete_size):
global_state.mstate.memory[concrete_memory_offset + i] = \
BitVec("code({})".format(global_state.environment.active_account.contract_name), 256)
return [global_state]
bytecode = global_state.environment.active_account.code.bytecode
for i in range(concrete_size):
try:
global_state.mstate.memory[concrete_memory_offset + i] =\
int(bytecode[2*(concrete_code_offset + i): 2*(concrete_code_offset + i + 1)], 16)
except IndexError:
global_state.mstate.memory[concrete_memory_offset + i] = \
BitVec("code({})".format(global_state.environment.active_account.contract_name), 256)
return [global_state] return [global_state]
@instruction @instruction

@ -68,6 +68,7 @@ class Environment:
calldata_type=CalldataType.SYMBOLIC, calldata_type=CalldataType.SYMBOLIC,
): ):
# Metadata # Metadata
self.active_account = active_account self.active_account = active_account
self.active_function_name = "" self.active_function_name = ""

@ -0,0 +1,20 @@
from mythril.disassembler.disassembly import Disassembly
from mythril.laser.ethereum.state import MachineState, GlobalState, Environment, Account
from mythril.laser.ethereum.instructions import Instruction
def test_codecopy_concrete():
# Arrange
active_account = Account("0x0", code= Disassembly("60606040"))
environment = Environment(active_account, None, None, None, None, None)
og_state = GlobalState(None, environment, None, MachineState(gas=10000000))
og_state.mstate.stack = [2, 2, 2]
instruction = Instruction("codecopy", dynamic_loader=None)
# Act
new_state = instruction.evaluate(og_state)[0]
# Assert
assert new_state.mstate.memory[2] == 96
assert new_state.mstate.memory[3] == 64

@ -38,7 +38,7 @@ def _generate_report(input_file):
def reports(): def reports():
""" Fixture that analyses all reports""" """ Fixture that analyses all reports"""
pool = Pool(cpu_count()) pool = Pool(cpu_count())
input_files = [f for f in TESTDATA_INPUTS.iterdir()] input_files = sorted([f for f in TESTDATA_INPUTS.iterdir()])
results = pool.map(_generate_report, input_files) results = pool.map(_generate_report, input_files)
return results return results

Loading…
Cancel
Save