Add logic for CREATE opcode, still need to add unit test for CREATE. Refactored extcodehash unit tests into separate test units.

pending-opcodes
e-ngo 5 years ago
parent 1e225eb770
commit 52ba355b65
  1. 5
      mythril/laser/ethereum/gas.py
  2. 42
      mythril/laser/ethereum/instructions.py
  3. 32
      tests/instructions/extcodehash_test.py

@ -180,10 +180,7 @@ OPCODE_GAS = {
"LOG3": (4 * 375, 4 * 375 + 8 * 32),
"LOG4": (5 * 375, 5 * 375 + 8 * 32),
"CREATE": (32000, 32000),
"CREATE2": (
32000,
32000,
), # TODO: The gas value is dynamic, to be done while implementing create2
"CREATE2": (32000, 32000), # TODO: Make the gas value is dynamic
"CALL": (700, 700 + 9000 + 25000),
"NATIVE_COST": calculate_native_gas,
"CALLCODE": (700, 700 + 9000 + 25000),

@ -1605,12 +1605,42 @@ class Instruction:
:param global_state:
:return:
"""
# TODO: implement me
state = global_state.mstate
state.stack.pop(), state.stack.pop(), state.stack.pop()
# Not supported
state.stack.append(0)
return [global_state]
mstate = global_state.mstate
environment = global_state.environment
world_state = global_state.world_state
call_value, mem_offset, mem_size = (
mstate.stack.pop(),
mstate.stack.pop(),
mstate.stack.pop(),
)
try:
call_data = mstate.memory[
util.get_concrete_int(mem_offset) : util.get_concrete_int(
mem_offset + mem_size
)
]
except TypeError:
log.debug("Create with symbolic length or offset. Not supported")
caller = environment.sender
gas_price = environment.gasprice
origin = environment.origin
transaction = ContractCreationTransaction(
world_state=world_state,
caller=caller,
call_data=call_data,
gas_price=gas_price,
origin=origin,
call_value=call_value,
)
contract_address = transaction.callee_account.address
mstate.stack.append(contract_address)
raise TransactionStartSignal(transaction, self.op_code)
@StateTransition()
def create2_(self, global_state: GlobalState) -> List[GlobalState]:

@ -11,33 +11,37 @@ from mythril.support.support_utils import get_code_hash
from mythril.laser.smt import symbol_factory
def test_extcodehash_concrete():
# Arrange
world_state = WorldState()
account = world_state.create_account(balance=10, address=101)
account.code = Disassembly("60606040")
world_state.create_account(balance=10, address=1000)
environment = Environment(account, None, None, None, None, None)
og_state = GlobalState(
world_state, environment, None, MachineState(gas_limit=8000000)
)
og_state.transaction_stack.append(
# Arrange
world_state = WorldState()
account = world_state.create_account(balance=10, address=101)
account.code = Disassembly("60606040")
world_state.create_account(balance=10, address=1000)
environment = Environment(account, None, None, None, None, None)
og_state = GlobalState(world_state, environment, None, MachineState(gas_limit=8000000))
og_state.transaction_stack.append(
(MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None)
)
)
instruction = Instruction("extcodehash", dynamic_loader=None)
instruction = Instruction("extcodehash", dynamic_loader=None)
def test_extcodehash_no_account():
# If account does not exist, return 0
og_state.mstate.stack = [symbol_factory.BitVecVal(1, 256)]
new_state = instruction.evaluate(og_state)[0]
assert new_state.mstate.stack[-1] == 0
def test_extcodehash_no_code():
# If account code does not exist, return hash of empty set.
og_state.mstate.stack = [symbol_factory.BitVecVal(1000, 256)]
new_state = instruction.evaluate(og_state)[0]
assert hex(new_state.mstate.stack[-1].value) == get_code_hash("")
def test_extcodehash_return_hash():
# If account code exists, return hash of the code.
og_state.mstate.stack = [symbol_factory.BitVecVal(101, 256)]
new_state = instruction.evaluate(og_state)[0]

Loading…
Cancel
Save