mirror of https://github.com/ConsenSys/mythril
Add new features (#1841)
parent
13969337fd
commit
2b5445fe11
@ -0,0 +1 @@ |
|||||||
|
from .metrics_plugin import CoverageMetricsPluginBuilder |
@ -0,0 +1 @@ |
|||||||
|
BATCH_OF_STATES = 5 |
@ -0,0 +1,73 @@ |
|||||||
|
import json |
||||||
|
from typing import Dict, List |
||||||
|
|
||||||
|
from mythril.support.support_utils import get_code_hash |
||||||
|
from mythril.laser.execution_info import ExecutionInfo |
||||||
|
|
||||||
|
|
||||||
|
class InstructionCoverageInfo(ExecutionInfo): |
||||||
|
def __init__(self): |
||||||
|
self._instruction_coverage = {} # type: Dict[str, int] |
||||||
|
|
||||||
|
def as_dict(self): |
||||||
|
return dict(instruction_discovery_time=self._instruction_coverage) |
||||||
|
|
||||||
|
def get_code_instr_hex(self, code: str, instruction: int): |
||||||
|
code_hash = get_code_hash(code)[2:] |
||||||
|
instruction_hex = hex(instruction)[2:] |
||||||
|
return "{}:{}".format(code_hash, instruction_hex) |
||||||
|
|
||||||
|
def is_covered(self, code: str, instruction: int): |
||||||
|
code_instr_hex = self.get_code_instr_hex(code, instruction) |
||||||
|
return code_instr_hex in self._instruction_coverage |
||||||
|
|
||||||
|
def add_data(self, code: str, instruction: int, discovery_time: int): |
||||||
|
code_instr_hex = self.get_code_instr_hex(code, instruction) |
||||||
|
self._instruction_coverage[code_instr_hex] = discovery_time |
||||||
|
|
||||||
|
def output(self, filename: str): |
||||||
|
with open(filename, "w") as outfile: |
||||||
|
json.dump( |
||||||
|
self._instruction_coverage, default=lambda o: o.__dict__, fp=outfile |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
class CoverageData: |
||||||
|
def __init__( |
||||||
|
self, |
||||||
|
instructions_covered: int, |
||||||
|
total_instructions: int, |
||||||
|
branches_covered: int, |
||||||
|
tx_id: int, |
||||||
|
total_branches: int, |
||||||
|
state_counter: int, |
||||||
|
code: str, |
||||||
|
time_elapsed: int, |
||||||
|
): |
||||||
|
self.instructions_covered = instructions_covered |
||||||
|
self.total_instructions = total_instructions |
||||||
|
self.branches_covered = branches_covered |
||||||
|
self.tx_id = tx_id |
||||||
|
self.total_branches = total_branches |
||||||
|
self.state_counter = state_counter |
||||||
|
self.code_hash = get_code_hash(code)[2:] |
||||||
|
self.time_elapsed = time_elapsed |
||||||
|
|
||||||
|
def as_dict(self): |
||||||
|
return self.__dict__ |
||||||
|
|
||||||
|
|
||||||
|
class CoverageTimeSeries(ExecutionInfo): |
||||||
|
def __init__(self): |
||||||
|
self.coverage = [] # type: List[CoverageData] |
||||||
|
|
||||||
|
def output(self, filename: str): |
||||||
|
with open(filename, "w") as outfile: |
||||||
|
json.dump(self.coverage, default=lambda o: o.__dict__, fp=outfile) |
||||||
|
|
||||||
|
def as_dict(self): |
||||||
|
return dict(coverage=self.coverage) |
||||||
|
|
||||||
|
def add_data(self, *args, **kwargs): |
||||||
|
cov_data = CoverageData(*args, **kwargs) |
||||||
|
self.coverage.append(cov_data.as_dict()) |
@ -0,0 +1,131 @@ |
|||||||
|
from mythril.laser.ethereum.svm import LaserEVM |
||||||
|
from mythril.laser.plugin.interface import LaserPlugin |
||||||
|
from mythril.laser.plugin.builder import PluginBuilder |
||||||
|
from mythril.laser.ethereum.state.global_state import GlobalState |
||||||
|
from .coverage_data import ( |
||||||
|
CoverageTimeSeries, |
||||||
|
InstructionCoverageInfo, |
||||||
|
) |
||||||
|
from .constants import BATCH_OF_STATES |
||||||
|
from typing import Dict, Tuple, List |
||||||
|
|
||||||
|
import time |
||||||
|
import logging |
||||||
|
|
||||||
|
log = logging.getLogger(__name__) |
||||||
|
|
||||||
|
|
||||||
|
class CoverageMetricsPluginBuilder(PluginBuilder): |
||||||
|
"""CoveragePlugin |
||||||
|
Checks Instruction and branch coverage and puts it to data.json file |
||||||
|
which appears in the directory in which mythril is run. |
||||||
|
""" |
||||||
|
|
||||||
|
plugin_default_enabled = True |
||||||
|
enabled = True |
||||||
|
|
||||||
|
author = "MythX Development Team" |
||||||
|
plugin_name = "MythX Coverage Metrics" |
||||||
|
plugin_license = "All rights reserved." |
||||||
|
plugin_type = "Laser Plugin" |
||||||
|
plugin_description = ( |
||||||
|
"This plugin measures coverage throughout symbolic execution," |
||||||
|
" reporting it at the end in the MythX coverage format." |
||||||
|
) |
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs): |
||||||
|
"""Constructs the plugin""" |
||||||
|
return LaserCoveragePlugin() |
||||||
|
|
||||||
|
|
||||||
|
class LaserCoveragePlugin(LaserPlugin): |
||||||
|
def __init__(self): |
||||||
|
self.instruction_coverage_data = {} # type: Dict[str, Tuple[int, Dict[bool]]] |
||||||
|
self.branch_possibilities = {} # type: Dict[str, Dict[int, List]] |
||||||
|
self.tx_id = 0 |
||||||
|
self.state_counter = 0 |
||||||
|
self.coverage = CoverageTimeSeries() |
||||||
|
self.instruction_coverage_info = InstructionCoverageInfo() |
||||||
|
self.start_time = time.time_ns() |
||||||
|
|
||||||
|
def initialize(self, symbolic_vm: LaserEVM) -> None: |
||||||
|
"""Initializes the instruction coverage plugin |
||||||
|
|
||||||
|
Introduces hooks for each instruction |
||||||
|
:param symbolic_vm: The symbolic virtual machine to initialise this plugin for |
||||||
|
""" |
||||||
|
log.info("Initializing coverage metrics plugin") |
||||||
|
|
||||||
|
self.instruction_coverage_data = {} |
||||||
|
self.branch_possibilities = {} |
||||||
|
self.tx_id = 0 |
||||||
|
|
||||||
|
# Add the instruction coverage ExecutionInfo to laser vm for use in reporting |
||||||
|
symbolic_vm.execution_info.append(self.instruction_coverage_info) |
||||||
|
symbolic_vm.execution_info.append(self.coverage) |
||||||
|
|
||||||
|
@symbolic_vm.laser_hook("execute_state") |
||||||
|
def execute_state_hook(global_state: GlobalState): |
||||||
|
self._update_instruction_coverage_data(global_state) |
||||||
|
self._update_branch_coverage_data(global_state) |
||||||
|
self.state_counter += 1 |
||||||
|
if self.state_counter == BATCH_OF_STATES: |
||||||
|
self._record_coverage() |
||||||
|
self.state_counter = 0 |
||||||
|
|
||||||
|
@symbolic_vm.laser_hook("stop_sym_trans") |
||||||
|
def execute_stop_sym_trans_hook(): |
||||||
|
self.tx_id += 1 |
||||||
|
|
||||||
|
# The following is useful for debugging |
||||||
|
# @symbolic_vm.laser_hook("stop_sym_exec") |
||||||
|
# def execute_stop_sym_exec_hook(): |
||||||
|
# self.coverage.output("coverage_data.json") |
||||||
|
# self.instruction_coverage_info.output("instruction_discovery_data.json") |
||||||
|
|
||||||
|
def _update_instruction_coverage_data(self, global_state: GlobalState): |
||||||
|
"""Records instruction coverage""" |
||||||
|
code = global_state.environment.code.bytecode |
||||||
|
if code not in self.instruction_coverage_data.keys(): |
||||||
|
number_of_instructions = len(global_state.environment.code.instruction_list) |
||||||
|
self.instruction_coverage_data[code] = (number_of_instructions, {}) |
||||||
|
current_instr = global_state.get_current_instruction()["address"] |
||||||
|
if self.instruction_coverage_info.is_covered(code, current_instr) is False: |
||||||
|
self.instruction_coverage_info.add_data( |
||||||
|
code, current_instr, time.time_ns() - self.start_time |
||||||
|
) |
||||||
|
self.instruction_coverage_data[code][1][current_instr] = True |
||||||
|
|
||||||
|
def _update_branch_coverage_data(self, global_state: GlobalState): |
||||||
|
"""Records branch coverage""" |
||||||
|
code = global_state.environment.code.bytecode |
||||||
|
if code not in self.branch_possibilities: |
||||||
|
self.branch_possibilities[code] = {} |
||||||
|
|
||||||
|
if global_state.get_current_instruction()["opcode"] != "JUMPI": |
||||||
|
return |
||||||
|
addr = global_state.get_current_instruction()["address"] |
||||||
|
jump_addr = global_state.mstate.stack[-1] |
||||||
|
if jump_addr.symbolic: |
||||||
|
log.debug("Encountered a symbolic jump, ignoring it for branch coverage") |
||||||
|
return |
||||||
|
self.branch_possibilities[code][addr] = [addr + 1, jump_addr.value] |
||||||
|
|
||||||
|
def _record_coverage(self): |
||||||
|
for code, code_cov in self.instruction_coverage_data.items(): |
||||||
|
total_branches = 0 |
||||||
|
branches_covered = 0 |
||||||
|
for jumps, branches in self.branch_possibilities[code].items(): |
||||||
|
for branch in branches: |
||||||
|
total_branches += 1 |
||||||
|
branches_covered += branch in code_cov[1] |
||||||
|
self.coverage.add_data( |
||||||
|
code=code, |
||||||
|
instructions_covered=len(code_cov[1]), |
||||||
|
total_instructions=code_cov[0], |
||||||
|
branches_covered=branches_covered, |
||||||
|
tx_id=self.tx_id, |
||||||
|
total_branches=total_branches, |
||||||
|
state_counter=self.state_counter, |
||||||
|
time_elapsed=time.time_ns() - self.start_time, |
||||||
|
) |
@ -0,0 +1,48 @@ |
|||||||
|
from mythril.laser.plugin.interface import LaserPlugin |
||||||
|
from mythril.laser.plugin.builder import PluginBuilder |
||||||
|
from mythril.laser.ethereum.state.global_state import GlobalState |
||||||
|
from mythril.laser.ethereum.svm import LaserEVM |
||||||
|
from typing import List, Tuple |
||||||
|
|
||||||
|
|
||||||
|
class TraceFinderBuilder(PluginBuilder): |
||||||
|
name = "trace-finder" |
||||||
|
plugin_default_enabled = True |
||||||
|
enabled = True |
||||||
|
|
||||||
|
author = "MythX Development Team" |
||||||
|
name = "MythX Trace Finder" |
||||||
|
plugin_license = "All rights reserved." |
||||||
|
plugin_type = "Laser Plugin" |
||||||
|
plugin_version = "0.0.1 " |
||||||
|
plugin_description = "This plugin merges states after the end of a transaction" |
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs): |
||||||
|
return TraceFinder() |
||||||
|
|
||||||
|
|
||||||
|
class TraceFinder(LaserPlugin): |
||||||
|
def __init__(self): |
||||||
|
self._reset() |
||||||
|
|
||||||
|
def _reset(self): |
||||||
|
self.tx_trace: List[List[Tuple[int, str]]] = [] |
||||||
|
|
||||||
|
def initialize(self, symbolic_vm: LaserEVM): |
||||||
|
"""Initializes Trace Finder |
||||||
|
|
||||||
|
Introduces hooks during the start of the execution and each execution state |
||||||
|
:param symbolic_vm: |
||||||
|
:return: |
||||||
|
""" |
||||||
|
self._reset() |
||||||
|
|
||||||
|
@symbolic_vm.laser_hook("start_exec") |
||||||
|
def start_sym_trans_hook(): |
||||||
|
self.tx_trace.append([]) |
||||||
|
|
||||||
|
@symbolic_vm.laser_hook("execute_state") |
||||||
|
def trace_jumpi_hook(global_state: GlobalState): |
||||||
|
self.tx_trace[-1].append( |
||||||
|
(global_state.mstate.pc, global_state.current_transaction.id) |
||||||
|
) |
@ -0,0 +1,240 @@ |
|||||||
|
import binascii |
||||||
|
import json |
||||||
|
import pathlib |
||||||
|
import pytest |
||||||
|
import subprocess |
||||||
|
|
||||||
|
from copy import deepcopy |
||||||
|
from datetime import datetime |
||||||
|
from mock import patch |
||||||
|
from subprocess import check_output, CalledProcessError |
||||||
|
from tests import BaseTestCase, PROJECT_DIR, TESTDATA |
||||||
|
|
||||||
|
from mythril.concolic import concrete_execution |
||||||
|
from mythril.concolic.find_trace import setup_concrete_initial_state |
||||||
|
from mythril.disassembler.asm import disassemble |
||||||
|
from mythril.concolic.concrete_data import ConcreteData |
||||||
|
from mythril.laser.ethereum import util |
||||||
|
|
||||||
|
from mythril.disassembler.disassembly import Disassembly |
||||||
|
from mythril.laser.ethereum.svm import LaserEVM |
||||||
|
from mythril.laser.ethereum.state.world_state import WorldState |
||||||
|
from mythril.laser.ethereum.state.account import Account |
||||||
|
from mythril.laser.ethereum.time_handler import time_handler |
||||||
|
from mythril.laser.ethereum.transaction.concolic import execute_transaction |
||||||
|
from mythril.laser.plugin.loader import LaserPluginLoader |
||||||
|
from mythril.laser.smt import Expression, BitVec, symbol_factory |
||||||
|
from mythril.laser.plugin.plugins import TraceFinderBuilder |
||||||
|
|
||||||
|
MYTH = str(PROJECT_DIR / "myth") |
||||||
|
|
||||||
|
|
||||||
|
def output_of(command): |
||||||
|
try: |
||||||
|
return json.loads(check_output(command, shell=True).decode("UTF-8")) |
||||||
|
except CalledProcessError as exc: |
||||||
|
return json.loads(exc.output.decode("UTF-8")) |
||||||
|
|
||||||
|
|
||||||
|
# TODO: Try using some python EVM for these tests |
||||||
|
|
||||||
|
|
||||||
|
def validate_simple_example(output, branches): |
||||||
|
for branch_output, branch in zip(output, branches): |
||||||
|
if branch == "153": |
||||||
|
# Validation for initialState |
||||||
|
|
||||||
|
# Validation for tx steps |
||||||
|
tx_step = branch_output["steps"][1] |
||||||
|
assert tx_step["input"] == tx_step["calldata"] |
||||||
|
assert int(tx_step["input"][10:], 16) == 3 |
||||||
|
|
||||||
|
|
||||||
|
def validate_multiple_example(output, branches): |
||||||
|
for branch_output, branch in zip(output, branches): |
||||||
|
if branch == "153": |
||||||
|
# Validation for initialState |
||||||
|
|
||||||
|
# Validation for tx steps |
||||||
|
tx_step = branch_output["steps"][1] |
||||||
|
assert tx_step["input"] == tx_step["calldata"] |
||||||
|
assert int(tx_step["input"][10:], 16) == 3 |
||||||
|
elif branch == "192": |
||||||
|
# Validation for initialState |
||||||
|
|
||||||
|
# Validation for tx steps |
||||||
|
tx_step = branch_output["steps"][1] |
||||||
|
assert tx_step["input"] == tx_step["calldata"] |
||||||
|
assert int(tx_step["input"][10:], 16) == 5 |
||||||
|
elif branch == "243": |
||||||
|
# Validation for initialState |
||||||
|
|
||||||
|
# Validation for tx steps |
||||||
|
tx_step = branch_output["steps"][1] |
||||||
|
assert tx_step["input"] == tx_step["calldata"] |
||||||
|
assert int(tx_step["input"][10:], 16) == 7 |
||||||
|
|
||||||
|
|
||||||
|
def validate_two_contract(output, branches): |
||||||
|
for branch_output, branch in zip(output, branches): |
||||||
|
if branch == "311": |
||||||
|
|
||||||
|
# Validation for initialState |
||||||
|
# Validation for tx steps |
||||||
|
assert ( |
||||||
|
int(branch_output["steps"][1]["input"][10:], 16) |
||||||
|
+ int(branch_output["steps"][3]["input"][10:], 16) |
||||||
|
== 11 |
||||||
|
) |
||||||
|
|
||||||
|
if branch == "341": |
||||||
|
# Validation for initialState |
||||||
|
|
||||||
|
# Validation for tx steps |
||||||
|
assert ( |
||||||
|
int(branch_output["steps"][1]["input"][10:], 16) |
||||||
|
+ int(branch_output["steps"][3]["input"][10:], 16) |
||||||
|
== 30 |
||||||
|
) |
||||||
|
|
||||||
|
if branch == "371": |
||||||
|
# Validation for initialState |
||||||
|
|
||||||
|
# Validation for tx steps |
||||||
|
assert ( |
||||||
|
int(branch_output["steps"][1]["input"][10:], 16) |
||||||
|
+ int(branch_output["steps"][3]["input"][10:], 16) |
||||||
|
== 20 |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
def validate_multi_contract(output, branches): |
||||||
|
for branch_output, branch in zip(output, branches): |
||||||
|
if branch == "453": |
||||||
|
# Validation for initialState |
||||||
|
|
||||||
|
# Validation for tx steps |
||||||
|
assert ( |
||||||
|
int(branch_output["steps"][1]["input"][10:], 16) |
||||||
|
+ int(branch_output["steps"][3]["input"][10:], 16) |
||||||
|
+ int(branch_output["steps"][5]["input"][10:], 16) |
||||||
|
== 10 |
||||||
|
) |
||||||
|
|
||||||
|
if branch == "483": |
||||||
|
# Validation for initialState |
||||||
|
|
||||||
|
# Validation for tx steps |
||||||
|
assert ( |
||||||
|
int(branch_output["steps"][1]["input"][10:], 16) |
||||||
|
+ int(branch_output["steps"][3]["input"][10:], 16) |
||||||
|
+ int(branch_output["steps"][5]["input"][10:], 16) |
||||||
|
== 25 |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
validate_test_data = ( |
||||||
|
("simple_example_input.json", validate_simple_example, "153"), |
||||||
|
("multiple_example_input.json", validate_multiple_example, "153,192,243"), |
||||||
|
("two_contract_input.json", validate_two_contract, "311,341,371"), |
||||||
|
("multi_contract_example_input.json", validate_multi_contract, "453,483"), |
||||||
|
) |
||||||
|
check_state_validity_test_data = ( |
||||||
|
("simple_example_input.json", "153"), |
||||||
|
("multiple_example_input.json", "153,192,243"), |
||||||
|
("two_contract_input.json", "311,341,371"), |
||||||
|
("multi_contract_example_input.json", "453,483"), |
||||||
|
) |
||||||
|
|
||||||
|
test_data_error = (("simple_example_input.json", "508"),) |
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("input_file,validate_function,branches", validate_test_data) |
||||||
|
def test_concolic_conditions(input_file, validate_function, branches): |
||||||
|
input_path = str(TESTDATA / "concolic_io" / input_file) |
||||||
|
|
||||||
|
command = f"{MYTH} concolic {input_path} --branches {branches}" |
||||||
|
received_output = output_of(command) |
||||||
|
branches = [branch for branch in branches.split(",")] |
||||||
|
validate_function(received_output, branches) |
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("input_file,branch", test_data_error) |
||||||
|
def test_concolic_error(input_file, branch): |
||||||
|
input_path = str(TESTDATA / "concolic_io" / input_file) |
||||||
|
command = f"{MYTH} concolic {input_path} --branches {branch}" |
||||||
|
received_output = subprocess.run( |
||||||
|
command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE |
||||||
|
) |
||||||
|
|
||||||
|
assert ( |
||||||
|
f"The branch {branch} does not lead to a jump address, skipping this branch" |
||||||
|
in received_output.stderr.decode("UTF-8") |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
def get_pc_from_disassembler(concrete_data, branches): |
||||||
|
init_state = setup_concrete_initial_state(concrete_data) |
||||||
|
laser_evm = LaserEVM(execution_timeout=100) |
||||||
|
|
||||||
|
laser_evm.open_states = [deepcopy(init_state)] |
||||||
|
plugin_loader = LaserPluginLoader() |
||||||
|
trace_plugin = TraceFinderBuilder() |
||||||
|
plugin_loader.load(trace_plugin) |
||||||
|
laser_evm.time = datetime.now() |
||||||
|
plugin_loader.instrument_virtual_machine(laser_evm, None) |
||||||
|
|
||||||
|
for transaction in concrete_data["steps"][:-1]: |
||||||
|
execute_transaction( |
||||||
|
laser_evm, |
||||||
|
callee_address=transaction["address"], |
||||||
|
caller_address=symbol_factory.BitVecVal( |
||||||
|
int(transaction["origin"], 16), 256 |
||||||
|
), |
||||||
|
origin_address=symbol_factory.BitVecVal( |
||||||
|
int(transaction["origin"], 16), 256 |
||||||
|
), |
||||||
|
gas_limit=int(transaction.get("gasLimit", "0x9999999999999999999999"), 16), |
||||||
|
data=binascii.a2b_hex(transaction["input"][2:]), |
||||||
|
gas_price=int(transaction.get("gasPrice", "0x773594000"), 16), |
||||||
|
value=int(transaction["value"], 16), |
||||||
|
track_gas=False, |
||||||
|
) |
||||||
|
contract_addr = concrete_data["steps"][-1]["address"] |
||||||
|
assert len(laser_evm.open_states) == 1 |
||||||
|
instruction_list = ( |
||||||
|
laser_evm.open_states[0].accounts[int(contract_addr, 16)].code.instruction_list |
||||||
|
) |
||||||
|
branches = [ |
||||||
|
util.get_instruction_index(instruction_list, branch) for branch in branches |
||||||
|
] |
||||||
|
return branches |
||||||
|
|
||||||
|
|
||||||
|
def run_concolic(input_path, output, branches): |
||||||
|
with open(input_path) as f: |
||||||
|
concrete_data = json.load(f) |
||||||
|
_, input_trace = concrete_execution(concrete_data) |
||||||
|
input_last_tx = input_trace[-1] |
||||||
|
branches = [int(branch) for branch in branches.split(",")] |
||||||
|
time_handler.start_execution(1000) |
||||||
|
branches = get_pc_from_disassembler(concrete_data, branches) |
||||||
|
for out, branch in zip(output, branches): |
||||||
|
_, trace = concrete_execution(out) |
||||||
|
last_tx = trace[-1] |
||||||
|
tx_id = last_tx[0][1] |
||||||
|
branch_idx = last_tx.index((branch, tx_id)) |
||||||
|
input_idx = input_last_tx.index((branch, tx_id)) |
||||||
|
|
||||||
|
assert (branch_idx == input_idx) and last_tx[branch_idx + 1][ |
||||||
|
0 |
||||||
|
] != input_last_tx[branch_idx + 1][0] |
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("input_file,branches", check_state_validity_test_data) |
||||||
|
def test_validate_concolic_output(input_file, branches): |
||||||
|
input_path = str(TESTDATA / "concolic_io" / input_file) |
||||||
|
|
||||||
|
command = f"{MYTH} concolic {input_path} --branches {branches}" |
||||||
|
received_output = output_of(command) |
||||||
|
run_concolic(input_path, received_output, branches) |
@ -0,0 +1,19 @@ |
|||||||
|
import pytest |
||||||
|
|
||||||
|
from tests import PROJECT_DIR, TESTDATA |
||||||
|
from utils import output_of |
||||||
|
|
||||||
|
MYTH = str(PROJECT_DIR / "myth") |
||||||
|
|
||||||
|
|
||||||
|
test_data = [ |
||||||
|
(open(f"{TESTDATA}/inputs/coverage.sol.o").read(), True), |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("code, exists", test_data) |
||||||
|
def test_basic_coverage(code, exists): |
||||||
|
assert ( |
||||||
|
"instruction_discovery_time" |
||||||
|
in output_of(f"{MYTH} a -c 0x{code} --solver-timeout 1000 -o jsonv2") |
||||||
|
) == exists |
@ -0,0 +1,54 @@ |
|||||||
|
pragma solidity 0.8.6; |
||||||
|
|
||||||
|
/** |
||||||
|
* @title Storage |
||||||
|
* @dev Store & retreive value in a variable |
||||||
|
*/ |
||||||
|
contract D1 { |
||||||
|
|
||||||
|
uint256 number; |
||||||
|
|
||||||
|
function store(uint256 num) public { |
||||||
|
number =num; |
||||||
|
} |
||||||
|
|
||||||
|
function retval() public returns(uint256){ |
||||||
|
return number; |
||||||
|
} |
||||||
|
} |
||||||
|
contract D2 { |
||||||
|
|
||||||
|
|
||||||
|
uint256 number; |
||||||
|
|
||||||
|
function store(uint256 num) external { |
||||||
|
number = num; |
||||||
|
} |
||||||
|
function retval() public returns(uint256){ |
||||||
|
return number; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
contract D3 { |
||||||
|
D2 d2; |
||||||
|
D1 d1; |
||||||
|
constructor() public |
||||||
|
{ |
||||||
|
d1 = D1(0x0901d12ebE1b195E5AA8748E62Bd7734aE19B51F); |
||||||
|
d2 = D2(0x384f682f4a5AbefC8795Cc38a340dE9446dFAE7A); |
||||||
|
} |
||||||
|
function test(uint256 num) public returns(uint256) { |
||||||
|
uint256 sum = d1.retval() + d2.retval() + num; |
||||||
|
if (sum == 10) { |
||||||
|
return sum + 10; |
||||||
|
} |
||||||
|
else if(sum == 25) { |
||||||
|
return sum * 2; |
||||||
|
} |
||||||
|
else return sum*10; |
||||||
|
return sum; |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,108 @@ |
|||||||
|
{ |
||||||
|
"initialState": { |
||||||
|
"accounts": { |
||||||
|
"0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe": { |
||||||
|
"balance": "0x1000000", |
||||||
|
"code": "", |
||||||
|
"nonce": 0, |
||||||
|
"storage": {} |
||||||
|
}, |
||||||
|
"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": { |
||||||
|
"balance": "0x0", |
||||||
|
"code": "", |
||||||
|
"nonce": 0, |
||||||
|
"storage": {} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"steps": [{ |
||||||
|
"address": "", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636057361d1461003b5780639c88345314610057575b600080fd5b6100556004803603810190610050919061009d565b610075565b005b61005f61007f565b60405161006c91906100d9565b60405180910390f35b8060008190555050565b60008054905090565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220773ac8f6769c8b896b1ac993a29718d8f1463998522b37ec8e410ded6f1bd3d464736f6c63430008060033", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "0x0901d12ebE1b195E5AA8748E62Bd7734aE19B51F", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x6057361d0000000000000000000000000000000000000000000000000000000000000001", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636057361d1461003b5780639c88345314610057575b600080fd5b6100556004803603810190610050919061009d565b610075565b005b61005f61007f565b60405161006c91906100d9565b60405180910390f35b8060008190555050565b60008054905090565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea264697066735822122046b7cc08908c1d17c2b2b523dfb5fc5a50e56068ce85f705f6f75ff54c7b16c864736f6c63430008060033", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "0x384f682f4a5AbefC8795Cc38a340dE9446dFAE7A", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x6057361d0000000000000000000000000000000000000000000000000000000000000001", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x608060405234801561001057600080fd5b50730901d12ebe1b195e5aa8748e62bd7734ae19b51f600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073384f682f4a5abefc8795cc38a340de9446dfae7a6000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506103f7806100c96000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806329e99f0714610030575b600080fd5b61004a60048036038101906100459190610238565b610060565b60405161005791906102a1565b60405180910390f35b6000808260008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639c8834536040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156100cc57600080fd5b505af11580156100e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101049190610265565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639c8834536040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561016e57600080fd5b505af1158015610182573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a69190610265565b6101b091906102bc565b6101ba91906102bc565b9050600a8114156101da57600a816101d291906102bc565b915050610209565b60198114156101f8576002816101f09190610312565b915050610209565b600a816102059190610312565b9150505b919050565b60008135905061021d816103aa565b92915050565b600081519050610232816103aa565b92915050565b60006020828403121561024e5761024d6103a5565b5b600061025c8482850161020e565b91505092915050565b60006020828403121561027b5761027a6103a5565b5b600061028984828501610223565b91505092915050565b61029b8161036c565b82525050565b60006020820190506102b66000830184610292565b92915050565b60006102c78261036c565b91506102d28361036c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561030757610306610376565b5b828201905092915050565b600061031d8261036c565b91506103288361036c565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561036157610360610376565b5b828202905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b6103b38161036c565b81146103be57600080fd5b5056fea2646970667358221220f0c85d3c193689a686ebf30f33bdac178593d7fe1036cce209c44c7833209cb464736f6c63430008060033", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "0xc538a4c3f414cbf7f78373e253c1beadd6310d45", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "0x29e99f070000000000000000000000000000000000000000000000000000000000000006", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x29e99f070000000000000000000000000000000000000000000000000000000000000006", |
||||||
|
"name": "", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}] |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
// source of the bytecode, as a reference for the test. |
||||||
|
pragma solidity 0.8.6; |
||||||
|
|
||||||
|
contract Example1 { |
||||||
|
uint256 private initialized = 0; |
||||||
|
uint256 public count = 1; |
||||||
|
|
||||||
|
function init() public { |
||||||
|
initialized = 1; |
||||||
|
} |
||||||
|
|
||||||
|
function run(uint256 input, uint val) public { |
||||||
|
if (val == 3) { |
||||||
|
count += input; |
||||||
|
} |
||||||
|
else if(val == 5) { |
||||||
|
count += 2 * input; |
||||||
|
} |
||||||
|
else if(val == 7) { |
||||||
|
count += 10 + input; |
||||||
|
} |
||||||
|
else |
||||||
|
count++; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
{ |
||||||
|
"initialState": { |
||||||
|
"accounts": { |
||||||
|
"0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe": { |
||||||
|
"balance": "0x10000", |
||||||
|
"code": "", |
||||||
|
"nonce": 0, |
||||||
|
"storage": {} |
||||||
|
}, |
||||||
|
"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": { |
||||||
|
"balance": "0x0", |
||||||
|
"code": "", |
||||||
|
"nonce": 0, |
||||||
|
"storage": {} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"steps": [{ |
||||||
|
"address": "", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x6080604052600080556001805534801561001857600080fd5b50610349806100286000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806306661abd146100465780637357f5d214610064578063e1c7392a14610080575b600080fd5b61004e61008a565b60405161005b91906101aa565b60405180910390f35b61007e6004803603810190610079919061015b565b610090565b005b61008861013c565b005b60015481565b60038114156100b75781600160008282546100ab91906101c5565b92505081905550610138565b60058114156100ea578160026100cd919061021b565b600160008282546100de91906101c5565b92505081905550610137565b600781141561011d5781600a61010091906101c5565b6001600082825461011191906101c5565b92505081905550610136565b600160008154809291906101309061027f565b91905055505b5b5b5050565b6001600081905550565b600081359050610155816102fc565b92915050565b60008060408385031215610172576101716102f7565b5b600061018085828601610146565b925050602061019185828601610146565b9150509250929050565b6101a481610275565b82525050565b60006020820190506101bf600083018461019b565b92915050565b60006101d082610275565b91506101db83610275565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156102105761020f6102c8565b5b828201905092915050565b600061022682610275565b915061023183610275565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561026a576102696102c8565b5b828202905092915050565b6000819050919050565b600061028a82610275565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156102bd576102bc6102c8565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b61030581610275565b811461031057600080fd5b5056fea26469706673582212202f9c24200282a71edb4cfb1018bca4a5608551f6bf5910ca1569133908c2605464736f6c63430008060033", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "0x901d12ebe1b195e5aa8748e62bd7734ae19b51f", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "0x7357f5d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x7357f5d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
||||||
|
"name": "run(uint256,uint256)", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}] |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
// source of the bytecode, as a reference for the test. |
||||||
|
pragma solidity 0.8.6; |
||||||
|
|
||||||
|
contract Example1 { |
||||||
|
uint256 private initialized = 0; |
||||||
|
uint256 public count = 1; |
||||||
|
|
||||||
|
function init() public { |
||||||
|
initialized = 1; |
||||||
|
} |
||||||
|
|
||||||
|
function run(uint256 input, uint val) public { |
||||||
|
if (val == 3) { |
||||||
|
count += input; |
||||||
|
} |
||||||
|
else |
||||||
|
count++; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
{ |
||||||
|
"initialState": { |
||||||
|
"accounts": { |
||||||
|
"0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe": { |
||||||
|
"balance": "0x10000", |
||||||
|
"code": "", |
||||||
|
"nonce": 0, |
||||||
|
"storage": {} |
||||||
|
}, |
||||||
|
"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": { |
||||||
|
"balance": "0x0", |
||||||
|
"code": "", |
||||||
|
"nonce": 0, |
||||||
|
"storage": {} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"steps": [{ |
||||||
|
"address": "", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x6080604052600080556001805534801561001857600080fd5b50610287806100286000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806306661abd146100465780637357f5d214610064578063e1c7392a14610080575b600080fd5b61004e61008a565b60405161005b9190610142565b60405180910390f35b61007e600480360381019061007991906100f3565b610090565b005b6100886100d4565b005b60015481565b60038114156100b75781600160008282546100ab919061015d565b925050819055506100d0565b600160008154809291906100ca906101bd565b91905055505b5050565b6001600081905550565b6000813590506100ed8161023a565b92915050565b6000806040838503121561010a57610109610235565b5b6000610118858286016100de565b9250506020610129858286016100de565b9150509250929050565b61013c816101b3565b82525050565b60006020820190506101576000830184610133565b92915050565b6000610168826101b3565b9150610173836101b3565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156101a8576101a7610206565b5b828201905092915050565b6000819050919050565b60006101c8826101b3565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156101fb576101fa610206565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610243816101b3565b811461024e57600080fd5b5056fea2646970667358221220de20d82abee4e4f81661465126dda93179255f9249d58bde7c3ea5f5f8bc3dbb64736f6c63430008060033", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "0x901d12ebe1b195e5aa8748e62bd7734ae19b51f", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "0x7357f5d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x7357f5d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
||||||
|
"name": "run(uint256,uint256)", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}] |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
pragma solidity 0.8.6; |
||||||
|
|
||||||
|
/** |
||||||
|
* @title Storage |
||||||
|
* @dev Store & retreive value in a variable |
||||||
|
*/ |
||||||
|
contract D1 { |
||||||
|
|
||||||
|
uint256 number; |
||||||
|
|
||||||
|
function store(uint256 num) public { |
||||||
|
assert(num < 5); |
||||||
|
number =num; |
||||||
|
} |
||||||
|
|
||||||
|
function retval() public returns(uint256){ |
||||||
|
return number; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract D2 { |
||||||
|
D1 d1; |
||||||
|
constructor() public |
||||||
|
{ |
||||||
|
d1 = D1(0x0901d12ebE1b195E5AA8748E62Bd7734aE19B51F); |
||||||
|
} |
||||||
|
function test(uint256 num) public returns(uint256) { |
||||||
|
uint256 sum = d1.retval() + num; |
||||||
|
if (sum == 10) { |
||||||
|
return sum + 10; |
||||||
|
} |
||||||
|
else if(sum == 11) { |
||||||
|
return sum + 12; |
||||||
|
} |
||||||
|
else if(sum == 30) { |
||||||
|
return sum * 2; |
||||||
|
} |
||||||
|
assert(sum != 20); |
||||||
|
return sum; |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,78 @@ |
|||||||
|
{ |
||||||
|
"initialState": { |
||||||
|
"accounts": { |
||||||
|
"0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe": { |
||||||
|
"balance": "0x10000000000000000000000000000", |
||||||
|
"code": "", |
||||||
|
"nonce": 0, |
||||||
|
"storage": {} |
||||||
|
}, |
||||||
|
"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": { |
||||||
|
"balance": "0x0", |
||||||
|
"code": "", |
||||||
|
"nonce": 0, |
||||||
|
"storage": {} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"steps": [{ |
||||||
|
"address": "", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x608060405234801561001057600080fd5b50610190806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636057361d1461003b5780639c88345314610057575b600080fd5b610055600480360381019061005091906100ae565b610075565b005b61005f610090565b60405161006c91906100ea565b60405180910390f35b600581106100865761008561010f565b5b8060008190555050565b60008054905090565b6000813590506100a881610143565b92915050565b6000602082840312156100c4576100c361013e565b5b60006100d284828501610099565b91505092915050565b6100e481610105565b82525050565b60006020820190506100ff60008301846100db565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600080fd5b61014c81610105565b811461015757600080fd5b5056fea26469706673582212200d02c19e8a2bae5958a822a8cfde054e94c216f2113e4b13c9dfcebaa7fd6d1564736f6c63430008060033", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "0x0901d12ebE1b195E5AA8748E62Bd7734aE19B51F", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x6057361d0000000000000000000000000000000000000000000000000000000000000001", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x608060405234801561001057600080fd5b50730901d12ebe1b195e5aa8748e62bd7734ae19b51f6000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061039e806100746000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806329e99f0714610030575b600080fd5b61004a600480360381019061004591906101b0565b610060565b6040516100579190610219565b60405180910390f35b6000808260008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639c8834536040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156100cc57600080fd5b505af11580156100e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010491906101dd565b61010e9190610234565b9050600a81141561012e57600a816101269190610234565b915050610181565b600b81141561014c57600c816101449190610234565b915050610181565b601e81141561016a57600281610162919061028a565b915050610181565b601481141561017c5761017b6102ee565b5b809150505b919050565b60008135905061019581610351565b92915050565b6000815190506101aa81610351565b92915050565b6000602082840312156101c6576101c561034c565b5b60006101d484828501610186565b91505092915050565b6000602082840312156101f3576101f261034c565b5b60006102018482850161019b565b91505092915050565b610213816102e4565b82525050565b600060208201905061022e600083018461020a565b92915050565b600061023f826102e4565b915061024a836102e4565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561027f5761027e61031d565b5b828201905092915050565b6000610295826102e4565b91506102a0836102e4565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156102d9576102d861031d565b5b828202905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b61035a816102e4565b811461036557600080fd5b5056fea26469706673582212205af1f2d3a496abf9b24e8953ec8c2869d565a0a6057c1ff82097fbff424f6e3464736f6c63430008060033", |
||||||
|
"name": "unknown", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"address": "0x384f682f4a5AbefC8795Cc38a340dE9446dFAE7A", |
||||||
|
"blockCoinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb", |
||||||
|
"blockDifficulty": "0xa7d7343662e26", |
||||||
|
"blockGasLimit": "0x7d0000", |
||||||
|
"blockNumber": "0x66e393", |
||||||
|
"blockTime": "0x5bfa4639", |
||||||
|
"calldata": "0x29e99f07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
||||||
|
"gasLimit": "0x7d000", |
||||||
|
"gasPrice": "0x773594000", |
||||||
|
"input": "0x29e99f07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
||||||
|
"name": "", |
||||||
|
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||||
|
"value": "0x0" |
||||||
|
}] |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610340806100606000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063228cb733146100725780633eb6a67e1461009d5780638da5cb5b146100a7578063ae169a50146100fe578063e834a8341461012b575b600080fd5b34801561007e57600080fd5b5061008761015a565b6040518082815260200191505060405180910390f35b6100a5610160565b005b3480156100b357600080fd5b506100bc61024a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561010a57600080fd5b506101296004803603810190808035906020019092919050505061026f565b005b34801561013757600080fd5b50610140610301565b604051808215151515815260200191505060405180910390f35b60015481565b600060149054906101000a900460ff1615151561017c57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156101d757600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc6001549081150290604051600060405180830381858888f19350505050158015610240573d6000803e3d6000fd5b5034600181905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff1615151561028b57600080fd5b600a8110151561029a57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc6001549081150290604051600060405180830381858888f193505050501580156102e2573d6000803e3d6000fd5b506001600060146101000a81548160ff02191690831515021790555050565b600060149054906101000a900460ff16815600a165627a7a723058207bb1caf5a53e1b9c9895f50b1740af67a18d256f4c2724858bdcd660db1729310029 |
Loading…
Reference in new issue