mirror of https://github.com/ConsenSys/mythril
commit
7ff3b3f8ab
@ -1,64 +1,72 @@ |
||||
from mythril.analysis.report import Issue |
||||
from mythril.analysis.swc_data import TX_ORIGIN_USAGE |
||||
from mythril.analysis.swc_data import DEPRICATED_FUNCTIONS_USAGE |
||||
from mythril.analysis.modules.base import DetectionModule |
||||
from mythril.laser.ethereum.state.global_state import GlobalState |
||||
import logging |
||||
|
||||
|
||||
DESCRIPTION = """ |
||||
Check for usage of deprecated opcodes |
||||
""" |
||||
MODULE DESCRIPTION: |
||||
|
||||
Check for constraints on tx.origin (i.e., access to some functionality is restricted to a specific origin). |
||||
""" |
||||
|
||||
def _analyze_state(state): |
||||
node = state.node |
||||
instruction = state.get_current_instruction() |
||||
|
||||
if instruction["opcode"] == "ORIGIN": |
||||
logging.debug("ORIGIN in function " + node.function_name) |
||||
title = "Use of tx.origin" |
||||
description = ( |
||||
"The function `{}` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. " |
||||
"Use msg.sender instead.\nSee also: " |
||||
"https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin".format( |
||||
node.function_name |
||||
) |
||||
) |
||||
swc_id = DEPRICATED_FUNCTIONS_USAGE |
||||
|
||||
elif instruction["opcode"] == "CALLCODE": |
||||
logging.debug("CALLCODE in function " + node.function_name) |
||||
title = "Use of callcode" |
||||
description = ( |
||||
"The function `{}` uses callcode. Callcode does not persist sender or value over the call. " |
||||
"Use delegatecall instead.".format(node.function_name) |
||||
) |
||||
swc_id = DEPRICATED_FUNCTIONS_USAGE |
||||
|
||||
issue = Issue( |
||||
contract=node.contract_name, |
||||
function_name=node.function_name, |
||||
address=instruction["address"], |
||||
title=title, |
||||
bytecode=state.environment.code.bytecode, |
||||
_type="Warning", |
||||
swc_id=swc_id, |
||||
description=description, |
||||
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), |
||||
) |
||||
return [issue] |
||||
|
||||
|
||||
class DeprecatedOperationsModule(DetectionModule): |
||||
def __init__(self): |
||||
super().__init__( |
||||
name="Deprecated Operations", |
||||
swc_id=TX_ORIGIN_USAGE, |
||||
hooks=["ORIGIN"], |
||||
description=( |
||||
"Check for constraints on tx.origin (i.e., access to some " |
||||
"functionality is restricted to a specific origin)." |
||||
), |
||||
swc_id=DEPRICATED_FUNCTIONS_USAGE, |
||||
hooks=["ORIGIN", "CALLCODE"], |
||||
description=(DESCRIPTION), |
||||
entrypoint="callback", |
||||
) |
||||
self._issues = [] |
||||
|
||||
def execute(self, statespace): |
||||
|
||||
logging.debug("Executing module: DEPRECATED OPCODES") |
||||
|
||||
issues = [] |
||||
|
||||
for k in statespace.nodes: |
||||
node = statespace.nodes[k] |
||||
|
||||
for state in node.states: |
||||
|
||||
instruction = state.get_current_instruction() |
||||
|
||||
if instruction["opcode"] == "ORIGIN": |
||||
description = ( |
||||
"The function `{}` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. " |
||||
"Use msg.sender instead.\nSee also: " |
||||
"https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin".format( |
||||
node.function_name |
||||
) |
||||
) |
||||
|
||||
issue = Issue( |
||||
contract=node.contract_name, |
||||
function_name=node.function_name, |
||||
address=instruction["address"], |
||||
title="Use of tx.origin", |
||||
bytecode=state.environment.code.bytecode, |
||||
_type="Warning", |
||||
swc_id=TX_ORIGIN_USAGE, |
||||
description=description, |
||||
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), |
||||
) |
||||
issues.append(issue) |
||||
def execute(self, state: GlobalState): |
||||
self._issues.extend(_analyze_state(state)) |
||||
return self.issues |
||||
|
||||
return issues |
||||
@property |
||||
def issues(self): |
||||
return self._issues |
||||
|
||||
|
||||
detector = DeprecatedOperationsModule() |
||||
|
@ -0,0 +1,31 @@ |
||||
class StateAnnotation: |
||||
""" |
||||
The StateAnnotation class is used to persist information over traces. This allows modules to reason about traces |
||||
without the need to traverse the state space themselves. |
||||
""" |
||||
|
||||
@property |
||||
def persist_to_world_state(self) -> bool: |
||||
""" |
||||
If this function returns true then laser will also annotate the world state. |
||||
|
||||
If you want annotations to persist through different user initiated message call transactions |
||||
then this should be enabled. |
||||
|
||||
The default is set to False |
||||
""" |
||||
return False |
||||
|
||||
|
||||
class NoCopyAnnotation(StateAnnotation): |
||||
""" |
||||
This class provides a base annotation class for annotations that shouldn't be copied on every new state. |
||||
Rather the same object should be propagated. |
||||
This is very useful if you are looking to analyze a property over multiple substates |
||||
""" |
||||
|
||||
def __copy__(self): |
||||
return self |
||||
|
||||
def __deepcopy__(self, _): |
||||
return self |
@ -0,0 +1,73 @@ |
||||
from mythril.laser.smt.bitvec import BitVec |
||||
from mythril.laser.smt.expression import Expression |
||||
from mythril.laser.smt.bool import Bool |
||||
|
||||
import z3 |
||||
|
||||
|
||||
class SymbolFactory: |
||||
""" |
||||
A symbol factory provides a default interface for all the components of mythril to create symbols |
||||
""" |
||||
|
||||
@staticmethod |
||||
def BitVecVal(value: int, size: int, annotations=None): |
||||
""" |
||||
Creates a new bit vector with a concrete value |
||||
:param value: The concrete value to set the bit vector to |
||||
:param size: The size of the bit vector |
||||
:param annotations: The annotations to initialize the bit vector with |
||||
:return: The freshly created bit vector |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@staticmethod |
||||
def BitVecSym(name: str, size: int, annotations=None): |
||||
""" |
||||
Creates a new bit vector with a symbolic value |
||||
:param name: The name of the symbolic bit vector |
||||
:param size: The size of the bit vector |
||||
:param annotations: The annotations to initialize the bit vector with |
||||
:return: The freshly created bit vector |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class _SmtSymbolFactory(SymbolFactory): |
||||
""" |
||||
An implementation of a SymbolFactory that creates symbols using |
||||
the classes in: mythril.laser.smt |
||||
""" |
||||
|
||||
@staticmethod |
||||
def BitVecVal(value: int, size: int, annotations=None): |
||||
""" Creates a new bit vector with a concrete value """ |
||||
raw = z3.BitVecVal(value, size) |
||||
return BitVec(raw, annotations) |
||||
|
||||
@staticmethod |
||||
def BitVecSym(name: str, size: int, annotations=None): |
||||
""" Creates a new bit vector with a symbolic value """ |
||||
raw = z3.BitVec(name, size) |
||||
return BitVec(raw, annotations) |
||||
|
||||
|
||||
class _Z3SymbolFactory(SymbolFactory): |
||||
""" |
||||
An implementation of a SymbolFactory that directly returns |
||||
z3 symbols |
||||
""" |
||||
|
||||
@staticmethod |
||||
def BitVecVal(value: int, size: int, annotations=None): |
||||
""" Creates a new bit vector with a concrete value """ |
||||
return z3.BitVecVal(value, size) |
||||
|
||||
@staticmethod |
||||
def BitVecSym(name: str, size: int, annotations=None): |
||||
""" Creates a new bit vector with a symbolic value """ |
||||
return z3.BitVec(name, size) |
||||
|
||||
|
||||
# This is the instance that other parts of mythril should use |
||||
symbol_factory = _Z3SymbolFactory() |
@ -0,0 +1,128 @@ |
||||
import z3 |
||||
|
||||
from mythril.laser.smt.expression import Expression |
||||
from mythril.laser.smt.bool import Bool |
||||
|
||||
# fmt: off |
||||
|
||||
|
||||
class BitVec(Expression): |
||||
""" |
||||
Bit vector symbol |
||||
""" |
||||
def __init__(self, raw, annotations=None): |
||||
super().__init__(raw, annotations) |
||||
|
||||
@property |
||||
def symbolic(self): |
||||
""" Returns whether this symbol doesn't have a concrete value """ |
||||
self.simplify() |
||||
return not isinstance(self.raw, z3.BitVecNumRef) |
||||
|
||||
@property |
||||
def value(self): |
||||
""" Returns the value of this symbol if concrete, otherwise None""" |
||||
if self.symbolic: |
||||
return None |
||||
assert isinstance(self.raw, z3.BitVecNumRef) |
||||
return self.raw.as_long() |
||||
|
||||
def __add__(self, other: "BV") -> "BV": |
||||
""" Create an addition expression """ |
||||
union = self.annotations + other.annotations |
||||
return BitVec(self.raw + other.raw, annotations=union) |
||||
|
||||
def __sub__(self, other: "BV") -> "BV": |
||||
""" Create a subtraction expression """ |
||||
union = self.annotations + other.annotations |
||||
return BitVec(self.raw - other.raw, annotations=union) |
||||
|
||||
def __mul__(self, other: "BV") -> "BV": |
||||
""" Create a multiplication expression """ |
||||
union = self.annotations + other.annotations |
||||
return BitVec(self.raw * other.raw, annotations=union) |
||||
|
||||
def __truediv__(self, other: "BV") -> "BV": |
||||
""" Create a signed division expression """ |
||||
union = self.annotations + other.annotations |
||||
return BitVec(self.raw / other.raw, annotations=union) |
||||
|
||||
def __and__(self, other: "BV") -> "BV": |
||||
""" Create an and expression """ |
||||
union = self.annotations + other.annotations |
||||
return BitVec(self.raw & other.raw, annotations=union) |
||||
|
||||
def __or__(self, other: "BV") -> "BV": |
||||
""" Create an or expression """ |
||||
union = self.annotations + other.annotations |
||||
return BitVec(self.raw | other.raw, annotations=union) |
||||
|
||||
def __xor__(self, other: "BV") -> "BV": |
||||
""" Create a xor expression """ |
||||
union = self.annotations + other.annotations |
||||
return BitVec(self.raw ^ other.raw, annotations=union) |
||||
|
||||
def __lt__(self, other: "BV") -> Bool: |
||||
""" Create a signed less than expression """ |
||||
union = self.annotations + other.annotations |
||||
return Bool(self.raw < other.raw, annotations=union) |
||||
|
||||
def __gt__(self, other: "BV") -> Bool: |
||||
""" Create a signed greater than expression """ |
||||
union = self.annotations + other.annotations |
||||
return Bool(self.raw < other.raw, annotations=union) |
||||
|
||||
def __eq__(self, other: "BV") -> Bool: |
||||
""" Create an equality expression """ |
||||
union = self.annotations + other.annotations |
||||
return Bool(self.raw == other.raw, annotations=union) |
||||
|
||||
|
||||
def If(a: Bool, b: BitVec, c: BitVec): |
||||
""" Create an if-then-else expression """ |
||||
union = a.annotations + b.annotations + c.annotations |
||||
return BitVec(z3.If(a, b, c), union) |
||||
|
||||
|
||||
def UGT(a: BitVec, b: BitVec) -> Bool: |
||||
""" Create an unsigned greater than expression """ |
||||
annotations = a.annotations + b.annotations |
||||
return Bool(z3.UGT(a, b), annotations) |
||||
|
||||
|
||||
def ULT(a: BitVec, b: BitVec) -> Bool: |
||||
""" Create an unsigned less than expression """ |
||||
annotations = a.annotations + b.annotations |
||||
return Bool(z3.ULT(a, b), annotations) |
||||
|
||||
|
||||
def Concat(*args) -> BitVec: |
||||
""" Create a concatenation expression """ |
||||
nraw = z3.Concat([a.raw for a in args]) |
||||
annotations = [] |
||||
for bv in args: |
||||
annotations += bv.annotations |
||||
return BitVec(nraw, annotations) |
||||
|
||||
|
||||
def Extract(high: int, low: int, bv: BitVec) -> BitVec: |
||||
""" Create an extract expression""" |
||||
return BitVec(z3.Extract(high, low, bv.raw), annotations=bv.annotations) |
||||
|
||||
|
||||
def URem(a: BitVec, b: BitVec) -> BitVec: |
||||
""" Create an unsigned remainder expression""" |
||||
union = a.annotations + b.annotations |
||||
return BitVec(z3.URem(a.raw, b.raw), annotations=union) |
||||
|
||||
|
||||
def SRem(a: BitVec, b: BitVec) -> BitVec: |
||||
""" Create a signed remainder expression""" |
||||
union = a.annotations + b.annotations |
||||
return BitVec(z3.SRem(a.raw, b.raw), annotations=union) |
||||
|
||||
|
||||
def UDiv(a: BitVec, b: BitVec) -> BitVec: |
||||
""" Create an unsigned division expression """ |
||||
union = a.annotations + b.annotations |
||||
return BitVec(z3.UDiv(a.raw, b.raw), annotations=union) |
@ -0,0 +1,44 @@ |
||||
import z3 |
||||
from typing import Union |
||||
|
||||
from mythril.laser.smt.expression import Expression |
||||
|
||||
# fmt: off |
||||
|
||||
|
||||
class Bool(Expression): |
||||
""" |
||||
This is a Bool expression |
||||
""" |
||||
|
||||
@property |
||||
def is_false(self) -> bool: |
||||
""" Specifies whether this variable can be simplified to false""" |
||||
self.simplify() |
||||
return z3.is_false(self.raw) |
||||
|
||||
@property |
||||
def is_true(self) -> bool: |
||||
""" Specifies whether this variable can be simplified to true""" |
||||
self.simplify() |
||||
return z3.is_true(self.raw) |
||||
|
||||
@property |
||||
def value(self) -> Union[bool, None]: |
||||
""" Returns the concrete value of this bool if concrete, otherwise None""" |
||||
if self.is_true: |
||||
return True |
||||
elif self.is_false: |
||||
return False |
||||
else: |
||||
return None |
||||
|
||||
|
||||
def is_false(a: Bool) -> bool: |
||||
""" Returns whether the provided bool can be simplified to false""" |
||||
return is_false(a) |
||||
|
||||
|
||||
def is_true(a: Bool) -> bool: |
||||
""" Returns whether the provided bool can be simplified to true""" |
||||
return is_true(a) |
@ -0,0 +1,32 @@ |
||||
import z3 |
||||
|
||||
|
||||
class Expression: |
||||
""" |
||||
This is the base symbol class and maintains functionality for simplification and annotations |
||||
""" |
||||
|
||||
def __init__(self, raw, annotations=None): |
||||
self.raw = raw |
||||
self._annotations = annotations or [] |
||||
|
||||
@property |
||||
def annotations(self): |
||||
""" Gets the annotations for this expression """ |
||||
return self._annotations |
||||
|
||||
def annotate(self, annotation): |
||||
""" Annotates this expression with the given annotation""" |
||||
if isinstance(annotation, list): |
||||
self._annotations += annotation |
||||
else: |
||||
self._annotations.append(annotation) |
||||
|
||||
def simplify(self): |
||||
""" Simplifies this expression """ |
||||
self.raw = z3.simplify(self.raw) |
||||
|
||||
|
||||
def simplify(expression: Expression): |
||||
""" Simplifies the expression """ |
||||
expression.simplify() |
@ -1,4 +0,0 @@ |
||||
[defaults] |
||||
leveldb_dir = /Users/bernhardmueller/Library/Ethereum/geth/chaindata |
||||
dynamic_loading = infura |
||||
|
Binary file not shown.
@ -1,122 +0,0 @@ |
||||
import json |
||||
from mythril.analysis.security import get_detection_module_hooks |
||||
from mythril.analysis.symbolic import SymExecWrapper |
||||
from mythril.analysis.callgraph import generate_graph |
||||
from mythril.ethereum.evmcontract import EVMContract |
||||
from mythril.solidity.soliditycontract import SolidityContract |
||||
from mythril.mythril import Mythril |
||||
|
||||
|
||||
from mythril.laser.ethereum.state.account import Account |
||||
from mythril.laser.ethereum.state.machine_state import MachineState |
||||
from mythril.laser.ethereum.state.global_state import GlobalState |
||||
from mythril.laser.ethereum import svm |
||||
from tests import ( |
||||
BaseTestCase, |
||||
TESTDATA_INPUTS_CONTRACTS, |
||||
TESTDATA_OUTPUTS_EXPECTED_LASER_RESULT, |
||||
TESTDATA_OUTPUTS_CURRENT_LASER_RESULT, |
||||
) |
||||
|
||||
|
||||
class LaserEncoder(json.JSONEncoder): |
||||
def default(self, o): |
||||
if getattr(o, "__module__", None) == "z3.z3": |
||||
return str(o) |
||||
return str(o) |
||||
|
||||
|
||||
def _all_info(laser): |
||||
accounts = {} |
||||
for address, _account in laser.world_state.accounts.items(): |
||||
account = _account.as_dict |
||||
account["code"] = account["code"].instruction_list |
||||
account["balance"] = str(account["balance"]) |
||||
accounts[address] = account |
||||
|
||||
nodes = {} |
||||
for uid, node in laser.nodes.items(): |
||||
states = [] |
||||
for state in node.states: |
||||
if isinstance(state, MachineState): |
||||
states.append(state.as_dict) |
||||
elif isinstance(state, GlobalState): |
||||
environment = state.environment.as_dict |
||||
environment["active_account"] = environment["active_account"].address |
||||
states.append( |
||||
{ |
||||
"accounts": state.accounts.keys(), |
||||
"environment": environment, |
||||
"mstate": state.mstate.as_dict, |
||||
} |
||||
) |
||||
|
||||
nodes[uid] = { |
||||
"uid": node.uid, |
||||
"contract_name": node.contract_name, |
||||
"start_addr": node.start_addr, |
||||
"states": states, |
||||
"constraints": node.constraints, |
||||
"function_name": node.function_name, |
||||
"flags": str(node.flags), |
||||
} |
||||
|
||||
edges = [edge.as_dict for edge in laser.edges] |
||||
|
||||
return { |
||||
"accounts": accounts, |
||||
"nodes": nodes, |
||||
"edges": edges, |
||||
"total_states": laser.total_states, |
||||
"max_depth": laser.max_depth, |
||||
} |
||||
|
||||
|
||||
class SVMTestCase(BaseTestCase): |
||||
def setUp(self): |
||||
super(SVMTestCase, self).setUp() |
||||
svm.gbl_next_uid = 0 |
||||
|
||||
def test_laser_result(self): |
||||
for input_file in TESTDATA_INPUTS_CONTRACTS.iterdir(): |
||||
if input_file.name in ["weak_random.sol", "environments.sol"]: |
||||
continue |
||||
output_expected = TESTDATA_OUTPUTS_EXPECTED_LASER_RESULT / ( |
||||
input_file.name + ".json" |
||||
) |
||||
output_current = TESTDATA_OUTPUTS_CURRENT_LASER_RESULT / ( |
||||
input_file.name + ".json" |
||||
) |
||||
|
||||
disassembly = SolidityContract( |
||||
str(input_file), solc_binary=Mythril._init_solc_binary("0.5.0") |
||||
).disassembly |
||||
account = Account("0x0000000000000000000000000000000000000000", disassembly) |
||||
accounts = {account.address: account} |
||||
|
||||
laser = svm.LaserEVM(accounts, max_depth=22, transaction_count=1) |
||||
laser.register_hooks( |
||||
hook_type="post", hook_dict=get_detection_module_hooks() |
||||
) |
||||
laser.sym_exec(account.address) |
||||
laser_info = _all_info(laser) |
||||
|
||||
output_current.write_text( |
||||
json.dumps(laser_info, cls=LaserEncoder, indent=4) |
||||
) |
||||
|
||||
if not (output_expected.read_text() == output_expected.read_text()): |
||||
self.found_changed_files(input_file, output_expected, output_current) |
||||
|
||||
self.assert_and_show_changed_files() |
||||
|
||||
def runTest(self): |
||||
|
||||
code = "0x60606040525b603c5b60006010603e565b9050593681016040523660008237602060003683856040603f5a0204f41560545760206000f35bfe5b50565b005b73c3b2ae46792547a96b9f84405e36d0e07edcd05c5b905600a165627a7a7230582062a884f947232ada573f95940cce9c8bfb7e4e14e21df5af4e884941afb55e590029" |
||||
|
||||
contract = EVMContract(code) |
||||
sym = SymExecWrapper(contract, "0xd0a6E6C543bC68Db5db3A191B171A77407Ff7ccf") |
||||
|
||||
html = generate_graph(sym) |
||||
|
||||
self.assertTrue("0 PUSH1 0x60\\n2 PUSH1 0x40\\n4 MSTORE\\n5 JUMPDEST" in html) |
File diff suppressed because it is too large
Load Diff
@ -1,472 +0,0 @@ |
||||
{ |
||||
"accounts": { |
||||
"0x0000000000000000000000000000000000000000": { |
||||
"storage": "<mythril.laser.ethereum.state.Storage object at 0x7f18fbbcab70>", |
||||
"nonce": 0, |
||||
"balance": "balance", |
||||
"code": [ |
||||
{ |
||||
"address": 0, |
||||
"argument": "0x80", |
||||
"opcode": "PUSH1" |
||||
}, |
||||
{ |
||||
"address": 2, |
||||
"argument": "0x40", |
||||
"opcode": "PUSH1" |
||||
}, |
||||
{ |
||||
"address": 4, |
||||
"opcode": "MSTORE" |
||||
}, |
||||
{ |
||||
"address": 5, |
||||
"argument": "0x00", |
||||
"opcode": "PUSH1" |
||||
}, |
||||
{ |
||||
"address": 7, |
||||
"opcode": "DUP1" |
||||
}, |
||||
{ |
||||
"address": 8, |
||||
"opcode": "REVERT" |
||||
}, |
||||
{ |
||||
"address": 9, |
||||
"opcode": "STOP" |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
"total_states": 5, |
||||
"nodes": { |
||||
"933": { |
||||
"contract_name": "unknown", |
||||
"flags": "NodeFlags()", |
||||
"constraints": [], |
||||
"function_name": "unknown", |
||||
"start_addr": 0, |
||||
"uid": 933, |
||||
"states": [ |
||||
{ |
||||
"accounts": "dict_keys(['0x0000000000000000000000000000000000000000'])", |
||||
"mstate": { |
||||
"gas": 10000000, |
||||
"memory": [], |
||||
"pc": 0, |
||||
"memsize": 0, |
||||
"stack": [] |
||||
}, |
||||
"environment": { |
||||
"sender": "caller", |
||||
"callvalue": "call_value", |
||||
"origin": "origin", |
||||
"active_account": "0x0000000000000000000000000000000000000000", |
||||
"gasprice": "gas_price", |
||||
"calldata": [], |
||||
"calldata_type": "CalldataType.SYMBOLIC" |
||||
} |
||||
}, |
||||
{ |
||||
"accounts": "dict_keys(['0x0000000000000000000000000000000000000000'])", |
||||
"mstate": { |
||||
"gas": 10000000, |
||||
"memory": [], |
||||
"pc": 1, |
||||
"memsize": 0, |
||||
"stack": [ |
||||
"128" |
||||
] |
||||
}, |
||||
"environment": { |
||||
"sender": "caller", |
||||
"callvalue": "call_value", |
||||
"origin": "origin", |
||||
"active_account": "0x0000000000000000000000000000000000000000", |
||||
"gasprice": "gas_price", |
||||
"calldata": [], |
||||
"calldata_type": "CalldataType.SYMBOLIC" |
||||
} |
||||
}, |
||||
{ |
||||
"accounts": "dict_keys(['0x0000000000000000000000000000000000000000'])", |
||||
"mstate": { |
||||
"gas": 10000000, |
||||
"memory": [], |
||||
"pc": 2, |
||||
"memsize": 0, |
||||
"stack": [ |
||||
"128", |
||||
"64" |
||||
] |
||||
}, |
||||
"environment": { |
||||
"sender": "caller", |
||||
"callvalue": "call_value", |
||||
"origin": "origin", |
||||
"active_account": "0x0000000000000000000000000000000000000000", |
||||
"gasprice": "gas_price", |
||||
"calldata": [], |
||||
"calldata_type": "CalldataType.SYMBOLIC" |
||||
} |
||||
}, |
||||
{ |
||||
"accounts": "dict_keys(['0x0000000000000000000000000000000000000000'])", |
||||
"mstate": { |
||||
"gas": 10000000, |
||||
"memory": [ |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
128 |
||||
], |
||||
"pc": 3, |
||||
"memsize": 96, |
||||
"stack": [] |
||||
}, |
||||
"environment": { |
||||
"sender": "caller", |
||||
"callvalue": "call_value", |
||||
"origin": "origin", |
||||
"active_account": "0x0000000000000000000000000000000000000000", |
||||
"gasprice": "gas_price", |
||||
"calldata": [], |
||||
"calldata_type": "CalldataType.SYMBOLIC" |
||||
} |
||||
}, |
||||
{ |
||||
"accounts": "dict_keys(['0x0000000000000000000000000000000000000000'])", |
||||
"mstate": { |
||||
"gas": 10000000, |
||||
"memory": [ |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
128 |
||||
], |
||||
"pc": 4, |
||||
"memsize": 96, |
||||
"stack": [ |
||||
"0" |
||||
] |
||||
}, |
||||
"environment": { |
||||
"sender": "caller", |
||||
"callvalue": "call_value", |
||||
"origin": "origin", |
||||
"active_account": "0x0000000000000000000000000000000000000000", |
||||
"gasprice": "gas_price", |
||||
"calldata": [], |
||||
"calldata_type": "CalldataType.SYMBOLIC" |
||||
} |
||||
}, |
||||
{ |
||||
"accounts": "dict_keys(['0x0000000000000000000000000000000000000000'])", |
||||
"mstate": { |
||||
"gas": 10000000, |
||||
"memory": [ |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
0, |
||||
128 |
||||
], |
||||
"pc": 5, |
||||
"memsize": 96, |
||||
"stack": [ |
||||
"0", |
||||
"0" |
||||
] |
||||
}, |
||||
"environment": { |
||||
"sender": "caller", |
||||
"callvalue": "call_value", |
||||
"origin": "origin", |
||||
"active_account": "0x0000000000000000000000000000000000000000", |
||||
"gasprice": "gas_price", |
||||
"calldata": [], |
||||
"calldata_type": "CalldataType.SYMBOLIC" |
||||
} |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
"max_depth": 22, |
||||
"edges": [] |
||||
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue