|
|
|
@ -73,10 +73,22 @@ class StateTransition(object): |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def call_on_state_copy(func: Callable, func_obj: "Instruction", state: GlobalState): |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param func: |
|
|
|
|
:param func_obj: |
|
|
|
|
:param state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state_copy = copy(state) |
|
|
|
|
return func(func_obj, global_state_copy) |
|
|
|
|
|
|
|
|
|
def increment_states_pc(self, states: List[GlobalState]) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param states: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
if self.increment_pc: |
|
|
|
|
for state in states: |
|
|
|
|
state.mstate.pc += 1 |
|
|
|
@ -84,6 +96,11 @@ class StateTransition(object): |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def check_gas_usage_limit(global_state: GlobalState): |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.check_gas() |
|
|
|
|
if isinstance(global_state.current_transaction.gas_limit, BitVecRef): |
|
|
|
|
try: |
|
|
|
@ -99,6 +116,11 @@ class StateTransition(object): |
|
|
|
|
raise OutOfGasException() |
|
|
|
|
|
|
|
|
|
def accumulate_gas(self, global_state: GlobalState): |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
if not self.enable_gas: |
|
|
|
|
return global_state |
|
|
|
|
opcode = global_state.instruction["opcode"] |
|
|
|
@ -111,6 +133,12 @@ class StateTransition(object): |
|
|
|
|
def wrapper( |
|
|
|
|
func_obj: "Instruction", global_state: GlobalState |
|
|
|
|
) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param func_obj: |
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
new_global_states = self.call_on_state_copy(func, func_obj, global_state) |
|
|
|
|
new_global_states = [ |
|
|
|
|
self.accumulate_gas(state) for state in new_global_states |
|
|
|
@ -156,10 +184,20 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def jumpdest_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def push_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
push_instruction = global_state.get_current_instruction() |
|
|
|
|
push_value = push_instruction["argument"][2:] |
|
|
|
|
|
|
|
|
@ -174,12 +212,22 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def dup_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
value = int(global_state.get_current_instruction()["opcode"][3:], 10) |
|
|
|
|
global_state.mstate.stack.append(global_state.mstate.stack[-value]) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def swap_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
depth = int(self.op_code[4:]) |
|
|
|
|
stack = global_state.mstate.stack |
|
|
|
|
stack[-depth - 1], stack[-1] = stack[-1], stack[-depth - 1] |
|
|
|
@ -187,11 +235,21 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def pop_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.pop() |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def and_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
stack = global_state.mstate.stack |
|
|
|
|
op1, op2 = stack.pop(), stack.pop() |
|
|
|
|
if type(op1) == BoolRef: |
|
|
|
@ -204,6 +262,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def or_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
stack = global_state.mstate.stack |
|
|
|
|
op1, op2 = stack.pop(), stack.pop() |
|
|
|
|
|
|
|
|
@ -219,18 +282,33 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def xor_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
mstate = global_state.mstate |
|
|
|
|
mstate.stack.append(mstate.stack.pop() ^ mstate.stack.pop()) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def not_(self, global_state: GlobalState): |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
mstate = global_state.mstate |
|
|
|
|
mstate.stack.append(TT256M1 - mstate.stack.pop()) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def byte_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
mstate = global_state.mstate |
|
|
|
|
op0, op1 = mstate.stack.pop(), mstate.stack.pop() |
|
|
|
|
if not isinstance(op1, ExprRef): |
|
|
|
@ -256,6 +334,11 @@ class Instruction: |
|
|
|
|
# Arithmetic |
|
|
|
|
@StateTransition() |
|
|
|
|
def add_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append( |
|
|
|
|
( |
|
|
|
|
helper.pop_bitvec(global_state.mstate) |
|
|
|
@ -266,6 +349,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def sub_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append( |
|
|
|
|
( |
|
|
|
|
helper.pop_bitvec(global_state.mstate) |
|
|
|
@ -276,6 +364,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def mul_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append( |
|
|
|
|
( |
|
|
|
|
helper.pop_bitvec(global_state.mstate) |
|
|
|
@ -286,6 +379,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def div_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
op0, op1 = ( |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
@ -298,6 +396,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def sdiv_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
s0, s1 = ( |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
@ -310,6 +413,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def mod_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
s0, s1 = ( |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
@ -319,6 +427,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def smod_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
s0, s1 = ( |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
@ -328,6 +441,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def addmod_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
s0, s1, s2 = ( |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
@ -338,6 +456,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def mulmod_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
s0, s1, s2 = ( |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
|
util.pop_bitvec(global_state.mstate), |
|
|
|
@ -348,6 +471,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def exp_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
base, exponent = util.pop_bitvec(state), util.pop_bitvec(state) |
|
|
|
|
|
|
|
|
@ -366,6 +494,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def signextend_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
s0, s1 = state.stack.pop(), state.stack.pop() |
|
|
|
|
|
|
|
|
@ -389,6 +522,11 @@ class Instruction: |
|
|
|
|
# Comparisons |
|
|
|
|
@StateTransition() |
|
|
|
|
def lt_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
exp = ULT(util.pop_bitvec(state), util.pop_bitvec(state)) |
|
|
|
|
state.stack.append(exp) |
|
|
|
@ -396,6 +534,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def gt_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
exp = UGT(util.pop_bitvec(state), util.pop_bitvec(state)) |
|
|
|
|
state.stack.append(exp) |
|
|
|
@ -403,6 +546,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def slt_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
exp = util.pop_bitvec(state) < util.pop_bitvec(state) |
|
|
|
|
state.stack.append(exp) |
|
|
|
@ -410,6 +558,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def sgt_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
|
|
|
|
|
exp = util.pop_bitvec(state) > util.pop_bitvec(state) |
|
|
|
@ -418,6 +571,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def eq_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
|
|
|
|
|
op1 = state.stack.pop() |
|
|
|
@ -436,6 +594,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def iszero_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
|
|
|
|
|
val = state.stack.pop() |
|
|
|
@ -447,6 +610,11 @@ class Instruction: |
|
|
|
|
# Call data |
|
|
|
|
@StateTransition() |
|
|
|
|
def callvalue_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
environment = global_state.environment |
|
|
|
|
state.stack.append(environment.callvalue) |
|
|
|
@ -455,6 +623,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def calldataload_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
environment = global_state.environment |
|
|
|
|
op0 = state.stack.pop() |
|
|
|
@ -467,6 +640,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def calldatasize_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
environment = global_state.environment |
|
|
|
|
state.stack.append(environment.calldata.calldatasize) |
|
|
|
@ -474,6 +652,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def calldatacopy_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
environment = global_state.environment |
|
|
|
|
op0, op1, op2 = state.stack.pop(), state.stack.pop(), state.stack.pop() |
|
|
|
@ -568,6 +751,11 @@ class Instruction: |
|
|
|
|
# Environment |
|
|
|
|
@StateTransition() |
|
|
|
|
def address_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
environment = global_state.environment |
|
|
|
|
state.stack.append(environment.address) |
|
|
|
@ -575,6 +763,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def balance_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
address = state.stack.pop() |
|
|
|
|
state.stack.append(global_state.new_bitvec("balance_at_" + str(address), 256)) |
|
|
|
@ -582,6 +775,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def origin_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
environment = global_state.environment |
|
|
|
|
state.stack.append(environment.origin) |
|
|
|
@ -589,6 +787,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def caller_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
environment = global_state.environment |
|
|
|
|
state.stack.append(environment.sender) |
|
|
|
@ -596,6 +799,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def codesize_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
environment = global_state.environment |
|
|
|
|
disassembly = environment.code |
|
|
|
@ -604,6 +812,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition(enable_gas=False) |
|
|
|
|
def sha3_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global keccak_function_manager |
|
|
|
|
|
|
|
|
|
state = global_state.mstate |
|
|
|
@ -650,11 +863,21 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def gasprice_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append(global_state.new_bitvec("gasprice", 256)) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def codecopy_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
memory_offset, code_offset, size = ( |
|
|
|
|
global_state.mstate.stack.pop(), |
|
|
|
|
global_state.mstate.stack.pop(), |
|
|
|
@ -741,6 +964,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def extcodesize_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
addr = state.stack.pop() |
|
|
|
|
environment = global_state.environment |
|
|
|
@ -767,6 +995,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def extcodecopy_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
# FIXME: not implemented |
|
|
|
|
state = global_state.mstate |
|
|
|
|
addr = state.stack.pop() |
|
|
|
@ -776,6 +1009,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def returndatacopy_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
# FIXME: not implemented |
|
|
|
|
state = global_state.mstate |
|
|
|
|
start, s2, size = state.stack.pop(), state.stack.pop(), state.stack.pop() |
|
|
|
@ -784,11 +1022,21 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def returndatasize_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append(global_state.new_bitvec("returndatasize", 256)) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def blockhash_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
blocknumber = state.stack.pop() |
|
|
|
|
state.stack.append( |
|
|
|
@ -798,21 +1046,41 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def coinbase_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append(global_state.new_bitvec("coinbase", 256)) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def timestamp_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append(global_state.new_bitvec("timestamp", 256)) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def number_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append(global_state.new_bitvec("block_number", 256)) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def difficulty_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append( |
|
|
|
|
global_state.new_bitvec("block_difficulty", 256) |
|
|
|
|
) |
|
|
|
@ -820,12 +1088,22 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def gaslimit_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append(global_state.mstate.gas_limit) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
# Memory operations |
|
|
|
|
@StateTransition() |
|
|
|
|
def mload_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
op0 = state.stack.pop() |
|
|
|
|
|
|
|
|
@ -849,6 +1127,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def mstore_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
op0, value = state.stack.pop(), state.stack.pop() |
|
|
|
|
|
|
|
|
@ -873,6 +1156,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def mstore8_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
op0, value = state.stack.pop(), state.stack.pop() |
|
|
|
|
|
|
|
|
@ -896,6 +1184,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def sload_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global keccak_function_manager |
|
|
|
|
|
|
|
|
|
state = global_state.mstate |
|
|
|
@ -965,6 +1258,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def sstore_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global keccak_function_manager |
|
|
|
|
state = global_state.mstate |
|
|
|
|
index, value = state.stack.pop(), state.stack.pop() |
|
|
|
@ -1041,6 +1339,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition(increment_pc=False, enable_gas=False) |
|
|
|
|
def jump_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
disassembly = global_state.environment.code |
|
|
|
|
try: |
|
|
|
@ -1075,6 +1378,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition(increment_pc=False, enable_gas=False) |
|
|
|
|
def jumpi_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
disassembly = global_state.environment.code |
|
|
|
|
min_gas, max_gas = OPCODE_GAS["JUMPI"] |
|
|
|
@ -1144,22 +1452,42 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def pc_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append(global_state.mstate.pc - 1) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def msize_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
global_state.mstate.stack.append(global_state.new_bitvec("msize", 256)) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def gas_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
# TODO: Push a Constrained variable which lies between min gas and max gas |
|
|
|
|
global_state.mstate.stack.append(global_state.new_bitvec("gas", 256)) |
|
|
|
|
return [global_state] |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def log_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
# TODO: implement me |
|
|
|
|
state = global_state.mstate |
|
|
|
|
dpth = int(self.op_code[3:]) |
|
|
|
@ -1170,6 +1498,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def create_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
# TODO: implement me |
|
|
|
|
state = global_state.mstate |
|
|
|
|
state.stack.pop(), state.stack.pop(), state.stack.pop() |
|
|
|
@ -1179,6 +1512,10 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def return_(self, global_state: GlobalState): |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
offset, length = state.stack.pop(), state.stack.pop() |
|
|
|
|
return_data = [global_state.new_bitvec("return_data", 8)] |
|
|
|
@ -1192,6 +1529,10 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def suicide_(self, global_state: GlobalState): |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
""" |
|
|
|
|
target = global_state.mstate.stack.pop() |
|
|
|
|
account_created = False |
|
|
|
|
# Often the target of the suicide instruction will be symbolic |
|
|
|
@ -1223,6 +1564,10 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def revert_(self, global_state: GlobalState) -> None: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
""" |
|
|
|
|
state = global_state.mstate |
|
|
|
|
offset, length = state.stack.pop(), state.stack.pop() |
|
|
|
|
return_data = [global_state.new_bitvec("return_data", 8)] |
|
|
|
@ -1238,20 +1583,36 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def assert_fail_(self, global_state: GlobalState): |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
""" |
|
|
|
|
# 0xfe: designated invalid opcode |
|
|
|
|
raise InvalidInstruction |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def invalid_(self, global_state: GlobalState): |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
""" |
|
|
|
|
raise InvalidInstruction |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def stop_(self, global_state: GlobalState): |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
""" |
|
|
|
|
global_state.current_transaction.end(global_state) |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def call_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
instr = global_state.get_current_instruction() |
|
|
|
|
environment = global_state.environment |
|
|
|
|
|
|
|
|
@ -1333,6 +1694,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def call_post(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
instr = global_state.get_current_instruction() |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
@ -1395,6 +1761,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def callcode_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
instr = global_state.get_current_instruction() |
|
|
|
|
environment = global_state.environment |
|
|
|
|
|
|
|
|
@ -1429,6 +1800,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def callcode_post(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
instr = global_state.get_current_instruction() |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
@ -1489,6 +1865,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def delegatecall_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
instr = global_state.get_current_instruction() |
|
|
|
|
environment = global_state.environment |
|
|
|
|
|
|
|
|
@ -1523,6 +1904,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def delegatecall_post(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
instr = global_state.get_current_instruction() |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
@ -1583,6 +1969,11 @@ class Instruction: |
|
|
|
|
|
|
|
|
|
@StateTransition() |
|
|
|
|
def staticcall_(self, global_state: GlobalState) -> List[GlobalState]: |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
:param global_state: |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
# TODO: implement me |
|
|
|
|
instr = global_state.get_current_instruction() |
|
|
|
|
global_state.mstate.stack.append( |
|
|
|
|