|
|
@ -25,7 +25,6 @@ from mythril.laser.smt import ( |
|
|
|
Bool, |
|
|
|
Bool, |
|
|
|
Not, |
|
|
|
Not, |
|
|
|
LShR, |
|
|
|
LShR, |
|
|
|
BVSubNoUnderflow, |
|
|
|
|
|
|
|
UGE, |
|
|
|
UGE, |
|
|
|
) |
|
|
|
) |
|
|
|
from mythril.laser.smt import symbol_factory |
|
|
|
from mythril.laser.smt import symbol_factory |
|
|
@ -56,6 +55,30 @@ TT256 = 2 ** 256 |
|
|
|
TT256M1 = 2 ** 256 - 1 |
|
|
|
TT256M1 = 2 ** 256 - 1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def transfer_ether( |
|
|
|
|
|
|
|
global_state: GlobalState, |
|
|
|
|
|
|
|
sender: BitVec, |
|
|
|
|
|
|
|
receiver: BitVec, |
|
|
|
|
|
|
|
value: Union[int, BitVec], |
|
|
|
|
|
|
|
): |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
Perform an Ether transfer between two accounts |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:param global_state: The global state in which the Ether transfer occurs |
|
|
|
|
|
|
|
:param sender: The sender of the Ether |
|
|
|
|
|
|
|
:param receiver: The recipient of the Ether |
|
|
|
|
|
|
|
:param value: The amount of Ether to send |
|
|
|
|
|
|
|
:return: |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
value = value if isinstance(value, BitVec) else symbol_factory.BitVecVal(value, 256) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_state.mstate.constraints.append( |
|
|
|
|
|
|
|
UGE(global_state.world_state.balances[sender], value) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
global_state.world_state.balances[receiver] += value |
|
|
|
|
|
|
|
global_state.world_state.balances[sender] -= value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class StateTransition(object): |
|
|
|
class StateTransition(object): |
|
|
|
"""Decorator that handles global state copy and original return. |
|
|
|
"""Decorator that handles global state copy and original return. |
|
|
|
|
|
|
|
|
|
|
@ -1697,17 +1720,7 @@ class Instruction: |
|
|
|
log.debug("The call is related to ether transfer between accounts") |
|
|
|
log.debug("The call is related to ether transfer between accounts") |
|
|
|
sender = environment.active_account.address |
|
|
|
sender = environment.active_account.address |
|
|
|
receiver = callee_account.address |
|
|
|
receiver = callee_account.address |
|
|
|
value = ( |
|
|
|
transfer_ether(sender, receiver, value) |
|
|
|
value |
|
|
|
|
|
|
|
if isinstance(value, BitVec) |
|
|
|
|
|
|
|
else symbol_factory.BitVecVal(value, 256) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_state.mstate.constraints.append( |
|
|
|
|
|
|
|
UGE(global_state.world_state.balances[sender], value) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
global_state.world_state.balances[receiver] += value |
|
|
|
|
|
|
|
global_state.world_state.balances[sender] -= value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_state.mstate.stack.append( |
|
|
|
global_state.mstate.stack.append( |
|
|
|
global_state.new_bitvec("retval_" + str(instr["address"]), 256) |
|
|
|
global_state.new_bitvec("retval_" + str(instr["address"]), 256) |
|
|
@ -1829,17 +1842,7 @@ class Instruction: |
|
|
|
log.debug("The call is related to ether transfer between accounts") |
|
|
|
log.debug("The call is related to ether transfer between accounts") |
|
|
|
sender = global_state.environment.active_account.address |
|
|
|
sender = global_state.environment.active_account.address |
|
|
|
receiver = callee_account.address |
|
|
|
receiver = callee_account.address |
|
|
|
value = ( |
|
|
|
transfer_ether(sender, receiver, value) |
|
|
|
value |
|
|
|
|
|
|
|
if isinstance(value, BitVec) |
|
|
|
|
|
|
|
else symbol_factory.BitVecVal(value, 256) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_state.mstate.constraints.append( |
|
|
|
|
|
|
|
UGE(global_state.world_state.balances[sender], value) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
global_state.world_state.balances[receiver] += value |
|
|
|
|
|
|
|
global_state.world_state.balances[sender] -= value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_state.mstate.stack.append( |
|
|
|
global_state.mstate.stack.append( |
|
|
|
global_state.new_bitvec("retval_" + str(instr["address"]), 256) |
|
|
|
global_state.new_bitvec("retval_" + str(instr["address"]), 256) |
|
|
@ -1954,17 +1957,7 @@ class Instruction: |
|
|
|
log.debug("The call is related to ether transfer between accounts") |
|
|
|
log.debug("The call is related to ether transfer between accounts") |
|
|
|
sender = environment.active_account.address |
|
|
|
sender = environment.active_account.address |
|
|
|
receiver = callee_account.address |
|
|
|
receiver = callee_account.address |
|
|
|
value = ( |
|
|
|
transfer_ether(sender, receiver, value) |
|
|
|
value |
|
|
|
|
|
|
|
if isinstance(value, BitVec) |
|
|
|
|
|
|
|
else symbol_factory.BitVecVal(value, 256) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_state.mstate.constraints.append( |
|
|
|
|
|
|
|
UGE(global_state.world_state.balances[sender], value) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
global_state.world_state.balances[receiver] += value |
|
|
|
|
|
|
|
global_state.world_state.balances[sender] -= value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_state.mstate.stack.append( |
|
|
|
global_state.mstate.stack.append( |
|
|
|
global_state.new_bitvec("retval_" + str(instr["address"]), 256) |
|
|
|
global_state.new_bitvec("retval_" + str(instr["address"]), 256) |
|
|
@ -2077,17 +2070,7 @@ class Instruction: |
|
|
|
log.debug("The call is related to ether transfer between accounts") |
|
|
|
log.debug("The call is related to ether transfer between accounts") |
|
|
|
sender = global_state.environment.active_account.address |
|
|
|
sender = global_state.environment.active_account.address |
|
|
|
receiver = callee_account.address |
|
|
|
receiver = callee_account.address |
|
|
|
value = ( |
|
|
|
transfer_ether(sender, receiver, value) |
|
|
|
value |
|
|
|
|
|
|
|
if isinstance(value, BitVec) |
|
|
|
|
|
|
|
else symbol_factory.BitVecVal(value, 256) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_state.mstate.constraints.append( |
|
|
|
|
|
|
|
UGE(global_state.world_state.balances[sender], value) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
global_state.world_state.balances[receiver] += value |
|
|
|
|
|
|
|
global_state.world_state.balances[sender] -= value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_state.mstate.stack.append( |
|
|
|
global_state.mstate.stack.append( |
|
|
|
global_state.new_bitvec("retval_" + str(instr["address"]), 256) |
|
|
|
global_state.new_bitvec("retval_" + str(instr["address"]), 256) |
|
|
|