Support transaction display

feature/tx_lists
Nikhil Parasaram 6 years ago
parent 6f1d9b24da
commit dec47b102b
  1. 2
      CONTRIBUTING.md
  2. 5
      mythril/analysis/call_helpers.py
  3. 4
      mythril/analysis/modules/ether_thief.py
  4. 3
      mythril/analysis/modules/exceptions.py
  5. 6
      mythril/analysis/modules/external_calls.py
  6. 3
      mythril/analysis/modules/integer.py
  7. 172
      mythril/analysis/modules/state_change_external_calls.py
  8. 3
      mythril/analysis/modules/suicide.py
  9. 30
      mythril/analysis/report.py
  10. 31
      mythril/analysis/solver.py
  11. 4
      mythril/analysis/symbolic.py
  12. 4
      mythril/analysis/templates/report_as_markdown.jinja2
  13. 4
      mythril/analysis/templates/report_as_text.jinja2
  14. 9
      mythril/interfaces/cli.py
  15. 1
      mythril/laser/ethereum/call.py
  16. 47
      mythril/laser/ethereum/plugins/implementations/save_initial_world_state.py
  17. 8
      mythril/laser/ethereum/plugins/plugin_factory.py
  18. 41
      mythril/laser/ethereum/svm.py
  19. 4
      tests/report_test.py
  20. 45
      tests/testdata/outputs_expected/calls.sol.o.json
  21. 42
      tests/testdata/outputs_expected/calls.sol.o.jsonv2
  22. 13
      tests/testdata/outputs_expected/calls.sol.o.markdown
  23. 11
      tests/testdata/outputs_expected/calls.sol.o.text
  24. 12
      tests/testdata/outputs_expected/ether_send.sol.o.jsonv2
  25. 16
      tests/testdata/outputs_expected/exceptions.sol.o.json
  26. 12
      tests/testdata/outputs_expected/exceptions.sol.o.jsonv2
  27. 20
      tests/testdata/outputs_expected/kinds_of_calls.sol.o.json
  28. 15
      tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2
  29. 12
      tests/testdata/outputs_expected/metacoin.sol.o.jsonv2
  30. 4
      tests/testdata/outputs_expected/multi_contracts.sol.o.json
  31. 3
      tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2
  32. 12
      tests/testdata/outputs_expected/nonascii.sol.o.jsonv2
  33. 4
      tests/testdata/outputs_expected/origin.sol.o.json
  34. 3
      tests/testdata/outputs_expected/origin.sol.o.jsonv2
  35. 8
      tests/testdata/outputs_expected/overflow.sol.o.json
  36. 6
      tests/testdata/outputs_expected/overflow.sol.o.jsonv2
  37. 12
      tests/testdata/outputs_expected/returnvalue.sol.o.json
  38. 9
      tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2
  39. 4
      tests/testdata/outputs_expected/suicide.sol.o.json
  40. 3
      tests/testdata/outputs_expected/suicide.sol.o.jsonv2
  41. 8
      tests/testdata/outputs_expected/underflow.sol.o.json
  42. 6
      tests/testdata/outputs_expected/underflow.sol.o.jsonv2

@ -10,7 +10,7 @@ If you have a small question or aren't sure if you should create an issue for yo
# Coding
If you want to help out with the development of Mythril then you can take a look at our issues or [Waffle board](https://waffle.io/ConsenSys/mythril).
Before you start working on an issue pkease stop by on Discord to message a collaborator, this way we can assign you to the issue making sure nobody does double work. We can also provide you with support through Discord if there are any questions during the development process.
Before you start working on an issue please stop by on Discord to message a collaborator, this way we can assign you to the issue making sure nobody does double work. We can also provide you with support through Discord if there are any questions during the development process.
## New ideas
Before you start working on a new idea, it's useful to create an issue on GitHub, that way we know what you want to implement and that you are working on it. Additionally, it might happen that your feature does not fit with our roadmap, in which case it would be unfortunate if you have already spent some time working on it.

@ -15,10 +15,9 @@ def get_call_from_state(state: GlobalState) -> Union[Call, None]:
instruction = state.get_current_instruction()
op = instruction["opcode"]
stack = state.mstate.stack
if op in ("CALL", "CALLCODE"):
if op in ("CALL", "CALLCODE", "STATICCALL"):
gas, to, value, meminstart, meminsz, memoutstart, memoutsz = (
get_variable(stack[-1]),
get_variable(stack[-2]),
@ -29,7 +28,7 @@ def get_call_from_state(state: GlobalState) -> Union[Call, None]:
get_variable(stack[-7]),
)
if to.type == VarType.CONCRETE and to.val < 5:
if to.type == VarType.CONCRETE and 0 < to.val < 5:
return None
if meminstart.type == VarType.CONCRETE and meminsz.type == VarType.CONCRETE:

@ -97,8 +97,6 @@ class EtherThief(DetectionModule):
transaction_sequence = solver.get_transaction_sequence(state, constraints)
debug = json.dumps(transaction_sequence, indent=4)
issue = Issue(
contract=state.environment.active_account.contract_name,
function_name=state.environment.active_function_name,
@ -111,7 +109,7 @@ class EtherThief(DetectionModule):
description_tail="Arbitrary senders other than the contract creator can withdraw ETH from the contract"
+ " account without previously having sent an equivalent amount of ETH to it. This is likely to be"
+ " a vulnerability.",
debug=debug,
transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
)
except UnsatError:

@ -36,7 +36,6 @@ def _analyze_state(state) -> list:
transaction_sequence = solver.get_transaction_sequence(
state, state.mstate.constraints
)
debug = json.dumps(transaction_sequence, indent=4)
issue = Issue(
contract=state.environment.active_account.contract_name,
@ -48,7 +47,7 @@ def _analyze_state(state) -> list:
description_head="A reachable exception has been detected.",
description_tail=description_tail,
bytecode=state.environment.code.bytecode,
debug=debug,
transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
)
return [issue]

@ -36,6 +36,7 @@ def _analyze_state(state):
try:
constraints = copy(state.mstate.constraints)
transaction_sequence = solver.get_transaction_sequence(
state, constraints + [UGT(gas, symbol_factory.BitVecVal(2300, 256))]
)
@ -46,7 +47,6 @@ def _analyze_state(state):
constraints += [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF]
transaction_sequence = solver.get_transaction_sequence(state, constraints)
debug = json.dumps(transaction_sequence, indent=4)
description_head = "A call to a user-supplied address is executed."
description_tail = (
"The callee address of an external message call can be set by "
@ -65,7 +65,7 @@ def _analyze_state(state):
severity="Medium",
description_head=description_head,
description_tail=description_tail,
debug=debug,
transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
)
@ -92,7 +92,7 @@ def _analyze_state(state):
severity="Low",
description_head=description_head,
description_tail=description_tail,
debug=debug,
transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
)

@ -306,10 +306,9 @@ class IntegerOverflowUnderflowModule(DetectionModule):
description_head=self._get_description_head(annotation, _type),
description_tail=self._get_description_tail(annotation, _type),
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
transaction_sequence=transaction_sequence,
)
issue.debug = json.dumps(transaction_sequence, indent=4)
if annotation.operator == "subtraction":
self._underflow_cache[address] = True
else:

@ -0,0 +1,172 @@
from mythril.analysis.swc_data import REENTRANCY
from mythril.analysis.modules.base import DetectionModule
from mythril.analysis.report import Issue
from mythril.laser.smt import symbol_factory, UGT, BitVec, Or
from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.state.annotation import StateAnnotation
from mythril.analysis import solver
from mythril.exceptions import UnsatError
from typing import List, cast, Optional
from copy import copy
import logging
log = logging.getLogger(__name__)
DESCRIPTION = """
Check whether there is a state change of the contract after the execution of an external call
"""
class StateChangeCallsAnnotation(StateAnnotation):
def __init__(self, call_state: GlobalState, user_defined_address: bool) -> None:
self.call_state = call_state
self.state_change_states = [] # type: List[GlobalState]
self.user_defined_address = user_defined_address
def __copy__(self):
new_annotation = StateChangeCallsAnnotation(
self.call_state, self.user_defined_address
)
new_annotation.state_change_states = self.state_change_states[:]
return new_annotation
def get_issue(self, global_state: GlobalState) -> Optional[Issue]:
if not self.state_change_states:
return None
severity = "Medium" if self.user_defined_address else "Low"
address = global_state.get_current_instruction()["address"]
logging.debug(
"[EXTERNAL_CALLS] Detected state changes at addresses: {}".format(address)
)
description_head = (
"The contract account state is changed after an external call. "
)
description_tail = (
"Consider that the called contract could re-enter the function before this "
"state change takes place. This can lead to business logic vulnerabilities."
)
return Issue(
contract=global_state.environment.active_account.contract_name,
function_name=global_state.environment.active_function_name,
address=address,
title="State change after external call",
severity=severity,
description_head=description_head,
description_tail=description_tail,
swc_id=REENTRANCY,
bytecode=global_state.environment.code.bytecode,
)
class StateChange(DetectionModule):
"""This module searches for state change after low level calls (e.g. call.value()) that
forward gas to the callee."""
def __init__(self):
""""""
super().__init__(
name="State Change After External calls",
swc_id=REENTRANCY,
description=DESCRIPTION,
entrypoint="callback",
pre_hooks=[
"CALL",
"SSTORE",
"DELEGATECALL",
"STATICCALL",
"CREATE",
"CREATE2",
"CALLCODE",
],
)
def execute(self, state: GlobalState):
self._issues.extend(self._analyze_state(state))
return self.issues
@staticmethod
def _add_external_call(global_state: GlobalState) -> None:
gas = global_state.mstate.stack[-1]
to = global_state.mstate.stack[-2]
try:
constraints = copy(global_state.mstate.constraints)
solver.get_model(
constraints
+ [
UGT(gas, symbol_factory.BitVecVal(2300, 256)),
Or(
to > symbol_factory.BitVecVal(16, 256),
to == symbol_factory.BitVecVal(0, 256),
),
]
)
# Check whether we can also set the callee address
try:
constraints += [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF]
solver.get_model(constraints)
global_state.annotate(StateChangeCallsAnnotation(global_state, True))
except UnsatError:
global_state.annotate(StateChangeCallsAnnotation(global_state, False))
except UnsatError:
pass
@staticmethod
def _analyze_state(global_state: GlobalState) -> List[Issue]:
annotations = cast(
List[StateChangeCallsAnnotation],
list(global_state.get_annotations(StateChangeCallsAnnotation)),
)
op_code = global_state.get_current_instruction()["opcode"]
if len(annotations) == 0:
if op_code in ("SSTORE", "CREATE", "CREATE2"):
return []
if op_code in ("SSTORE", "CREATE", "CREATE2"):
for annotation in annotations:
annotation.state_change_states.append(global_state)
# Record state changes following from a transfer of ether
if op_code in ("CALL", "DELEGATECALL", "CALLCODE"):
value = global_state.mstate.stack[-3] # type: BitVec
if StateChange._balance_change(value, global_state):
for annotation in annotations:
annotation.state_change_states.append(global_state)
# Record external calls
if op_code in ("CALL", "DELEGATECALL", "CALLCODE"):
StateChange._add_external_call(global_state)
# Check for vulnerabilities
vulnerabilities = []
for annotation in annotations:
if not annotation.state_change_states:
continue
vulnerabilities.append(annotation.get_issue(global_state))
return vulnerabilities
@staticmethod
def _balance_change(value: BitVec, global_state: GlobalState) -> bool:
if not value.symbolic:
assert value.value is not None
return value.value > 0
else:
constraints = copy(global_state.mstate.constraints)
try:
solver.get_model(
constraints + [value > symbol_factory.BitVecVal(0, 256)]
)
return True
except UnsatError:
return False
detector = StateChange()

@ -76,7 +76,6 @@ class SuicideModule(DetectionModule):
)
description_tail = "Arbitrary senders can kill this contract."
debug = json.dumps(transaction_sequence, indent=4)
self._cache_address[instruction["address"]] = True
issue = Issue(
@ -89,7 +88,7 @@ class SuicideModule(DetectionModule):
severity="High",
description_head=description_head,
description_tail=description_tail,
debug=debug,
transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
)
return [issue]

@ -31,7 +31,7 @@ class Issue:
severity=None,
description_head="",
description_tail="",
debug="",
transaction_sequence=None,
):
"""
@ -55,7 +55,6 @@ class Issue:
self.description_tail = description_tail
self.description = "%s\n%s" % (description_head, description_tail)
self.severity = severity
self.debug = debug
self.swc_id = swc_id
self.min_gas_used, self.max_gas_used = gas_used
self.filename = None
@ -64,6 +63,24 @@ class Issue:
self.source_mapping = None
self.discovery_time = time() - StartTime().global_start_time
self.bytecode_hash = get_code_hash(bytecode)
if transaction_sequence is None:
self.tx_sequence_users = None
self.transaction_sequence_jsonv2 = None
else:
self.tx_sequence_users = json.dumps(transaction_sequence, indent=4)
self.transaction_sequence_jsonv2 = self.add_block_data(transaction_sequence)
@staticmethod
def add_block_data(transaction_sequence: Dict):
for step in transaction_sequence["steps"]:
step["gasLimit"] = "0x7d000"
step["gasPrice"] = "0x773594000"
step["blockCoinbase"] = "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb"
step["blockDifficulty"] = "0xa7d7343662e26"
step["blockGasLimit"] = "0x7d0000"
step["blockNumber"] = "0x66e393"
step["blockTime"] = "0x5bfa4639"
return transaction_sequence
@property
def as_dict(self):
@ -79,7 +96,7 @@ class Issue:
"function": self.function,
"severity": self.severity,
"address": self.address,
"debug": self.debug,
"tx_sequence": self.tx_sequence_users,
"min_gas_used": self.min_gas_used,
"max_gas_used": self.max_gas_used,
"sourceMap": self.source_mapping,
@ -168,6 +185,7 @@ class Report:
"""
name = self._file_name()
template = Report.environment.get_template("report_as_text.jinja2")
return template.render(
filename=name, issues=self.sorted_issues(), verbose=self.verbose
)
@ -203,7 +221,9 @@ class Report:
title = SWC_TO_TITLE[issue.swc_id]
except KeyError:
title = "Unspecified Security Issue"
extra = {"discoveryTime": int(issue.discovery_time * 10 ** 9)}
if issue.transaction_sequence_jsonv2:
extra["testCase"] = str(issue.transaction_sequence_jsonv2)
_issues.append(
{
"swcID": "SWC-" + issue.swc_id,
@ -214,7 +234,7 @@ class Report:
},
"severity": issue.severity,
"locations": [{"sourceMap": "%d:1:%d" % (issue.address, idx)}],
"extra": {"discoveryTime": int(issue.discovery_time * 10 ** 9)},
"extra": extra,
}
)
meta_data = self._get_exception_data()

@ -1,9 +1,11 @@
"""This module contains analysis module helpers to solve path constraints."""
from typing import Dict, List
from z3 import sat, unknown, FuncInterp
from copy import copy
import z3
from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.state.constraints import Constraints
from mythril.laser.ethereum.transaction import BaseTransaction
from mythril.laser.smt import simplify, UGE, Optimize, symbol_factory
from mythril.laser.ethereum.time_handler import time_handler
@ -77,7 +79,9 @@ def pretty_print_model(model):
return ret
def get_transaction_sequence(global_state: GlobalState, constraints) -> Dict:
def get_transaction_sequence(
global_state: GlobalState, constraints: Constraints
) -> Dict:
"""Generate concrete transaction sequence.
:param global_state: GlobalState to generate transaction sequence for
@ -86,18 +90,11 @@ def get_transaction_sequence(global_state: GlobalState, constraints) -> Dict:
transaction_sequence = global_state.world_state.transaction_sequence
# gaslimit & gasprice don't exist yet
tx_template = {
"origin": None,
"value": None,
"address": None,
"input": None,
"gasLimit": "<GAS_LIMIT>",
"blockCoinbase": "<ARBITRARY_COINBASE>",
"blockDifficulty": "<ARBITRARY_DIFFICULTY>",
"blockGasLimit": "<ARBITRARY_GAS_LIMIT>",
"blockNumber": "<ARBITRARY_BLOCKNUMBER>",
"blockTime": "<ARBITRARY_BLOCKTIME>",
} # type: Dict[str, str]
concrete_transactions = []
@ -123,7 +120,7 @@ def get_transaction_sequence(global_state: GlobalState, constraints) -> Dict:
creation_tx_ids.append(tx_id)
model = get_model(tx_constraints, minimize=minimize)
min_price_dict = {} # type: Dict[str, int]
for transaction in transactions:
tx_id = str(transaction.id)
concrete_transaction = tx_template.copy()
@ -133,16 +130,20 @@ def get_transaction_sequence(global_state: GlobalState, constraints) -> Dict:
for b in transaction.call_data.concrete(model)
]
)
concrete_transaction["value"] = (
"0x%x"
% model.eval(transaction.call_value.raw, model_completion=True).as_long()
)
concrete_transaction["origin"] = "0x" + (
value = model.eval(transaction.call_value.raw, model_completion=True).as_long()
concrete_transaction["value"] = "0x%x" % value
origin = "0x" + (
"%x" % model.eval(transaction.caller.raw, model_completion=True).as_long()
).zfill(40)
concrete_transaction["origin"] = origin
concrete_transaction["address"] = "%s" % transaction.callee_account.address
concrete_transactions.append(concrete_transaction)
min_price_dict[origin] = min_price_dict.get(origin, 0) + value
initial_state = copy(global_state.world_state.initial_state_account)
for account, data in initial_state["accounts"].items():
data["balance"] = min_price_dict.get(account, 0)
steps = {
"initialState": global_state.world_state.initial_state_account,
"steps": concrete_transactions,

@ -85,6 +85,9 @@ class SymExecWrapper:
requires_statespace = (
compulsory_statespace or len(get_detection_modules("post", modules)) > 0
)
if not contract.creation_code:
self.accounts = {address: account, hex(ATTACKER_ADDRESS): attacker_account}
else:
self.accounts = {
address: account,
hex(CREATOR_ADDRESS): creator_account,
@ -106,7 +109,6 @@ class SymExecWrapper:
plugin_loader = LaserPluginLoader(self.laser)
plugin_loader.load(PluginFactory.build_mutation_pruner_plugin())
plugin_loader.load(PluginFactory.build_instruction_coverage_plugin())
plugin_loader.load(PluginFactory.build_set_initial_state_plugin())
self.laser.register_hooks(
hook_type="pre",

@ -24,11 +24,11 @@ In file: {{ issue.filename }}:{{ issue.lineno }}
{{ issue.code }}
```
{% endif %}
{% if verbose and issue.debug %}
{% if verbose and issue.tx_sequence %}
--------------------
### Debugging Information:
{{ issue.debug }}
{{ issue.tx_sequence }}
{% endif %}
{% endfor %}

@ -18,11 +18,11 @@ In file: {{ issue.filename }}:{{ issue.lineno }}
--------------------
{% endif %}
{% if verbose and issue.debug %}
{% if verbose and issue.tx_sequence %}
--------------------
Transaction Sequence:
{{ issue.debug }}
{{ issue.tx_sequence }}
{% endif %}
{% endfor %}

@ -433,6 +433,7 @@ def execute_command(
contract=analyzer.contracts[0],
enable_physics=args.enable_physics,
phrackify=args.phrack,
transaction_count=args.transaction_count,
)
try:
@ -507,7 +508,7 @@ def parse_args(parser: argparse.ArgumentParser, args: argparse.Namespace) -> Non
quick_commands(args)
config = set_config(args)
leveldb_search(config, args)
dissasembler = MythrilDisassembler(
disassembler = MythrilDisassembler(
eth=config.eth,
solc_version=args.solv,
solc_args=args.solc_args,
@ -515,16 +516,16 @@ def parse_args(parser: argparse.ArgumentParser, args: argparse.Namespace) -> Non
)
if args.truffle:
try:
dissasembler.analyze_truffle_project(args)
disassembler.analyze_truffle_project(args)
except FileNotFoundError:
print(
"Build directory not found. Make sure that you start the analysis from the project root, and that 'truffle compile' has executed successfully."
)
sys.exit()
address = get_code(dissasembler, args)
address = get_code(disassembler, args)
execute_command(
disassembler=dissasembler, address=address, parser=parser, args=args
disassembler=disassembler, address=address, parser=parser, args=args
)
except CriticalError as ce:
exit_with_error(args.outform, str(ce))

@ -49,7 +49,6 @@ def get_call_parameters(
callee_account = None
call_data = get_call_data(global_state, memory_input_offset, memory_input_size)
if int(callee_address, 16) >= 5 or int(callee_address, 16) == 0:
callee_account = get_callee_account(
global_state, callee_address, dynamic_loader

@ -1,47 +0,0 @@
from mythril.laser.ethereum.svm import LaserEVM
from mythril.laser.ethereum.plugins.plugin import LaserPlugin
from mythril.laser.ethereum.state.world_state import WorldState
from typing import List
import logging
log = logging.getLogger(__name__)
class SaveInitialWorldState(LaserPlugin):
"""SaveInitialWorldState
This plugin is used to save initial world state so it can be used for the output to display
"""
def __init__(self):
pass
def initialize(self, symbolic_vm: LaserEVM):
"""
:param symbolic_vm:
:return:
"""
@symbolic_vm.laser_hook("end_contract_creation")
def set_standard_initial_state(openstates: List[WorldState]):
"""
This function initializes the initial state to all the open states
:param openstates:
:return:
"""
accounts = openstates[0].accounts
initial_state = openstates[0].initial_state_account
initial_state[
"accounts"
] = {} # This variable persists for all world states.
for address, account in accounts.items():
if address == "0x" + "0" * 40:
continue
initial_state["accounts"][address] = {
"nounce": account.nonce,
"balance": "<ARBITRARY_BALANCE>",
"code": account.code.bytecode,
"storage": {},
}

@ -30,11 +30,3 @@ class PluginFactory:
)
return InstructionCoveragePlugin()
@staticmethod
def build_set_initial_state_plugin() -> LaserPlugin:
from mythril.laser.ethereum.plugins.implementations.save_initial_world_state import (
SaveInitialWorldState,
)
return SaveInitialWorldState()

@ -103,20 +103,8 @@ class LaserEVM:
self._start_sym_exec_hooks = [] # type: List[Callable]
self._stop_sym_exec_hooks = [] # type: List[Callable]
self._end_contract_creation_hooks = [] # type: List[Callable]
self.iprof = InstructionProfiler() if enable_iprof else None
self.laser_hooks_dict = {
"add_world_state": self._add_world_state_hooks,
"execute_state": self._execute_state_hooks,
"start_sym_exec": self._start_sym_exec_hooks,
"stop_sym_exec": self._stop_sym_exec_hooks,
"start_sym_trans": self._start_sym_trans_hooks,
"stop_sym_trans": self._stop_sym_trans_hooks,
"end_contract_creation": self._end_contract_creation_hooks,
}
log.info("LASER EVM initialized with dynamic loader: " + str(dynamic_loader))
@property
@ -127,11 +115,13 @@ class LaserEVM:
"""
return self.world_state.accounts
def set_standard_initial_state(self, accounts: Dict[str, Account]):
def set_standard_initial_state(
self, accounts: Dict[str, Account], ignore_addr=True
):
initial_state = self.world_state.initial_state_account
initial_state["accounts"] = {} # This variable persists for all world states.
for address, account in accounts.items():
if address == "0x" + "0" * 40:
if ignore_addr and address == "0x" + "0" * 40:
continue
initial_state["accounts"][address] = {
"nounce": account.nonce,
@ -158,11 +148,13 @@ class LaserEVM:
if main_address:
log.info("Starting message call transaction to {}".format(main_address))
self.set_standard_initial_state(self.world_state.accounts)
self._execute_transactions(main_address)
elif creation_code:
log.info("Starting contract creation transaction")
self.set_standard_initial_state(self.world_state.accounts)
created_account = execute_contract_creation(
self, creation_code, contract_name
)
@ -177,8 +169,9 @@ class LaserEVM:
"Increase the resources for creation execution (--max-depth or --create-timeout)"
)
else:
for hook in self._end_contract_creation_hooks:
hook(self.open_states)
self.set_standard_initial_state(
self.open_states[0].accounts, ignore_addr=True
)
self._execute_transactions(created_account.address)
@ -319,7 +312,7 @@ class LaserEVM:
)
except TransactionStartSignal as start_signal:
# Setup new global state
# Is a MessageCall to contract, setup new global state
new_global_state = start_signal.transaction.initial_global_state()
new_global_state.transaction_stack = copy(
@ -512,8 +505,18 @@ class LaserEVM:
def register_laser_hooks(self, hook_type: str, hook: Callable):
"""registers the hook with this Laser VM"""
if hook_type in self.laser_hooks_dict:
self.laser_hooks_dict[hook_type].append(hook)
if hook_type == "add_world_state":
self._add_world_state_hooks.append(hook)
elif hook_type == "execute_state":
self._execute_state_hooks.append(hook)
elif hook_type == "start_sym_exec":
self._start_sym_exec_hooks.append(hook)
elif hook_type == "stop_sym_exec":
self._stop_sym_exec_hooks.append(hook)
elif hook_type == "start_sym_trans":
self._start_sym_trans_hooks.append(hook)
elif hook_type == "stop_sym_trans":
self._stop_sym_trans_hooks.append(hook)
else:
raise ValueError(
"Invalid hook type %s. Must be one of {add_world_state}", hook_type

@ -17,7 +17,8 @@ def _fix_path(text):
def _fix_debug_data(json_str):
read_json = json.loads(json_str)
for issue in read_json["issues"]:
issue["debug"] = "<DEBUG-DATA>"
issue["tx_sequence"] = "<TX-DATA>"
return json.dumps(read_json, sort_keys=True, indent=4)
@ -25,6 +26,7 @@ def _add_jsonv2_stubs(json_str):
read_json = json.loads(json_str)
for issue in read_json[0]["issues"]:
issue["extra"]["discoveryTime"] = "<DISCOVERY-TIME-DATA>"
issue["extra"]["testCase"] = "<TEST-CASE>"
return json.dumps(read_json, sort_keys=True, indent=4)

@ -4,7 +4,6 @@
{
"address": 661,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The contract executes an external message call.\nAn external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully.",
"function": "thisisfine()",
"max_gas_used": 1254,
@ -12,12 +11,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "107",
"title": "External Call To Fixed Address"
"title": "External Call To Fixed Address",
"tx_sequence": "<TX-DATA>"
},
{
"address": 661,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The return value of a message call is not checked.\nExternal calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.",
"function": "thisisfine()",
"max_gas_used": 35972,
@ -25,12 +24,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "104",
"title": "Unchecked Call Return Value"
"title": "Unchecked Call Return Value",
"tx_sequence": "<TX-DATA>"
},
{
"address": 779,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The contract executes an external message call.\nAn external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully.",
"function": "callstoredaddress()",
"max_gas_used": 1298,
@ -38,12 +37,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "107",
"title": "External Call To Fixed Address"
"title": "External Call To Fixed Address",
"tx_sequence": "<TX-DATA>"
},
{
"address": 779,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The return value of a message call is not checked.\nExternal calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.",
"function": "callstoredaddress()",
"max_gas_used": 36016,
@ -51,12 +50,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "104",
"title": "Unchecked Call Return Value"
"title": "Unchecked Call Return Value",
"tx_sequence": "<TX-DATA>"
},
{
"address": 858,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The contract executes an external message call.\nAn external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully.",
"function": "reentrancy()",
"max_gas_used": 1320,
@ -64,12 +63,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "107",
"title": "External Call To Fixed Address"
"title": "External Call To Fixed Address",
"tx_sequence": "<TX-DATA>"
},
{
"address": 858,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The return value of a message call is not checked.\nExternal calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.",
"function": "reentrancy()",
"max_gas_used": 61052,
@ -77,12 +76,25 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "104",
"title": "Unchecked Call Return Value"
"title": "Unchecked Call Return Value",
"tx_sequence": "<TX-DATA>"
},
{
"address": 869,
"contract": "Unknown",
"description": "The contract account state is changed after an external call. \nConsider that the called contract could re-enter the function before this state change takes place. This can lead to business logic vulnerabilities.",
"function": "reentrancy()",
"max_gas_used": null,
"min_gas_used": null,
"severity": "Low",
"sourceMap": null,
"swc-id": "107",
"title": "State change after external call",
"tx_sequence": "<TX-DATA>"
},
{
"address": 912,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "A call to a user-supplied address is executed.\nThe callee address of an external message call can be set by the caller. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent averse effects on the contract state.",
"function": "calluseraddress(address)",
"max_gas_used": 616,
@ -90,12 +102,12 @@
"severity": "Medium",
"sourceMap": null,
"swc-id": "107",
"title": "External Call To User-Supplied Address"
"title": "External Call To User-Supplied Address",
"tx_sequence": "<TX-DATA>"
},
{
"address": 912,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The return value of a message call is not checked.\nExternal calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.",
"function": "calluseraddress(address)",
"max_gas_used": 35336,
@ -103,7 +115,8 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "104",
"title": "Unchecked Call Return Value"
"title": "Unchecked Call Return Value",
"tx_sequence": "<TX-DATA>"
}
],
"success": true

@ -7,7 +7,8 @@
"tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -24,7 +25,8 @@
"tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -41,7 +43,8 @@
"tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -58,7 +61,8 @@
"tail": "The callee address of an external message call can be set by the caller. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent averse effects on the contract state."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -69,13 +73,32 @@
"swcID": "SWC-107",
"swcTitle": "Reentrancy"
},
{
"description": {
"head": "The contract account state is changed after an external call. ",
"tail": "Consider that the called contract could re-enter the function before this state change takes place. This can lead to business logic vulnerabilities."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
"sourceMap": "869:1:0"
}
],
"severity": "Low",
"swcID": "SWC-107",
"swcTitle": "Reentrancy"
},
{
"description": {
"head": "The return value of a message call is not checked.",
"tail": "External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -92,7 +115,8 @@
"tail": "External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -109,7 +133,8 @@
"tail": "External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -126,7 +151,8 @@
"tail": "External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{

@ -78,6 +78,19 @@ An external function call to a fixed contract address is executed. Make sure tha
The return value of a message call is not checked.
External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.
## State change after external call
- SWC ID: 107
- Severity: Low
- Contract: Unknown
- Function name: `reentrancy()`
- PC address: 869
- Estimated Gas Usage: None - None
### Description
The contract account state is changed after an external call.
Consider that the called contract could re-enter the function before this state change takes place. This can lead to business logic vulnerabilities.
## External Call To User-Supplied Address
- SWC ID: 107
- Severity: Medium

@ -64,6 +64,17 @@ The return value of a message call is not checked.
External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.
--------------------
==== State change after external call ====
SWC ID: 107
Severity: Low
Contract: Unknown
Function name: reentrancy()
PC address: 869
Estimated Gas Usage: None - None
The contract account state is changed after an external call.
Consider that the called contract could re-enter the function before this state change takes place. This can lead to business logic vulnerabilities.
--------------------
==== External Call To User-Supplied Address ====
SWC ID: 107
Severity: Medium

@ -1 +1,11 @@
[{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x3746c7c2ae7b0d4c3f8b1905df9a7ea169b9f93bec68a10a00b4c9d27a18c6fb"], "sourceType": "raw-bytecode"}]
[
{
"issues": [],
"meta": {},
"sourceFormat": "evm-byzantium-bytecode",
"sourceList": [
"0x3746c7c2ae7b0d4c3f8b1905df9a7ea169b9f93bec68a10a00b4c9d27a18c6fb"
],
"sourceType": "raw-bytecode"
}
]

@ -4,7 +4,6 @@
{
"address": 446,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "A reachable exception has been detected.\nIt is possible to trigger an exception (opcode 0xfe). Exceptions can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking.",
"function": "assert3(uint256)",
"max_gas_used": 301,
@ -12,12 +11,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "110",
"title": "Exception State"
"title": "Exception State",
"tx_sequence": "<TX-DATA>"
},
{
"address": 484,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "A reachable exception has been detected.\nIt is possible to trigger an exception (opcode 0xfe). Exceptions can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking.",
"function": "arrayaccess(uint256)",
"max_gas_used": 351,
@ -25,12 +24,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "110",
"title": "Exception State"
"title": "Exception State",
"tx_sequence": "<TX-DATA>"
},
{
"address": 506,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "A reachable exception has been detected.\nIt is possible to trigger an exception (opcode 0xfe). Exceptions can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking.",
"function": "divisionby0(uint256)",
"max_gas_used": 367,
@ -38,12 +37,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "110",
"title": "Exception State"
"title": "Exception State",
"tx_sequence": "<TX-DATA>"
},
{
"address": 531,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "A reachable exception has been detected.\nIt is possible to trigger an exception (opcode 0xfe). Exceptions can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking.",
"function": "assert1()",
"max_gas_used": 363,
@ -51,7 +50,8 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "110",
"title": "Exception State"
"title": "Exception State",
"tx_sequence": "<TX-DATA>"
}
],
"success": true

@ -7,7 +7,8 @@
"tail": "It is possible to trigger an exception (opcode 0xfe). Exceptions can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -24,7 +25,8 @@
"tail": "It is possible to trigger an exception (opcode 0xfe). Exceptions can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -41,7 +43,8 @@
"tail": "It is possible to trigger an exception (opcode 0xfe). Exceptions can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -58,7 +61,8 @@
"tail": "It is possible to trigger an exception (opcode 0xfe). Exceptions can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{

@ -4,7 +4,6 @@
{
"address": 618,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The return value of a message call is not checked.\nExternal calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.",
"function": "_function_0x141f32ff",
"max_gas_used": 35865,
@ -12,12 +11,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "104",
"title": "Unchecked Call Return Value"
"title": "Unchecked Call Return Value",
"tx_sequence": "<TX-DATA>"
},
{
"address": 618,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "Use of callcode is deprecated.\nThe callcode method executes code of another contract in the context of the caller account. Due to a bug in the implementation it does not persist sender and value over the call. It was therefore deprecated and may be removed in the future. Use the delegatecall method instead.",
"function": "_function_0x141f32ff",
"max_gas_used": 1141,
@ -25,12 +24,12 @@
"severity": "Medium",
"sourceMap": null,
"swc-id": "111",
"title": "Use of callcode"
"title": "Use of callcode",
"tx_sequence": "<TX-DATA>"
},
{
"address": 849,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The return value of a message call is not checked.\nExternal calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.",
"function": "_function_0x9b58bc26",
"max_gas_used": 35928,
@ -38,12 +37,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "104",
"title": "Unchecked Call Return Value"
"title": "Unchecked Call Return Value",
"tx_sequence": "<TX-DATA>"
},
{
"address": 1038,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "A call to a user-supplied address is executed.\nThe callee address of an external message call can be set by the caller. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent averse effects on the contract state.",
"function": "_function_0xeea4c864",
"max_gas_used": 1229,
@ -51,12 +50,12 @@
"severity": "Medium",
"sourceMap": null,
"swc-id": "107",
"title": "External Call To User-Supplied Address"
"title": "External Call To User-Supplied Address",
"tx_sequence": "<TX-DATA>"
},
{
"address": 1038,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The return value of a message call is not checked.\nExternal calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.",
"function": "_function_0xeea4c864",
"max_gas_used": 35953,
@ -64,7 +63,8 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "104",
"title": "Unchecked Call Return Value"
"title": "Unchecked Call Return Value",
"tx_sequence": "<TX-DATA>"
}
],
"success": true

@ -7,7 +7,8 @@
"tail": "The callcode method executes code of another contract in the context of the caller account. Due to a bug in the implementation it does not persist sender and value over the call. It was therefore deprecated and may be removed in the future. Use the delegatecall method instead."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -24,7 +25,8 @@
"tail": "The callee address of an external message call can be set by the caller. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent averse effects on the contract state."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -41,7 +43,8 @@
"tail": "External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -58,7 +61,8 @@
"tail": "External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -75,7 +79,8 @@
"tail": "External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{

@ -1 +1,11 @@
[{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x0e6f727bb3301e02d3be831bf34357522fd2f1d40e90dff8e2214553b06b5f6c"], "sourceType": "raw-bytecode"}]
[
{
"issues": [],
"meta": {},
"sourceFormat": "evm-byzantium-bytecode",
"sourceList": [
"0x0e6f727bb3301e02d3be831bf34357522fd2f1d40e90dff8e2214553b06b5f6c"
],
"sourceType": "raw-bytecode"
}
]

@ -4,7 +4,6 @@
{
"address": 142,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "Anyone can withdraw ETH from the contract account.\nArbitrary senders other than the contract creator can withdraw ETH from the contract account without previously having sent an equivalent amount of ETH to it. This is likely to be a vulnerability.",
"function": "transfer()",
"max_gas_used": 467,
@ -12,7 +11,8 @@
"severity": "High",
"sourceMap": null,
"swc-id": "105",
"title": "Unprotected Ether Withdrawal"
"title": "Unprotected Ether Withdrawal",
"tx_sequence": "<TX-DATA>"
}
],
"success": true

@ -7,7 +7,8 @@
"tail": "Arbitrary senders other than the contract creator can withdraw ETH from the contract account without previously having sent an equivalent amount of ETH to it. This is likely to be a vulnerability."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{

@ -1 +1,11 @@
[{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x11a78eb09819f505ba4f10747e6d1f7a44480e602c67573b7abac2f733a85d93"], "sourceType": "raw-bytecode"}]
[
{
"issues": [],
"meta": {},
"sourceFormat": "evm-byzantium-bytecode",
"sourceList": [
"0x11a78eb09819f505ba4f10747e6d1f7a44480e602c67573b7abac2f733a85d93"
],
"sourceType": "raw-bytecode"
}
]

@ -4,7 +4,6 @@
{
"address": 317,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "Use of tx.origin is deprecated.\nThe smart contract retrieves the transaction origin (tx.origin) using msg.origin. Use of msg.origin is deprecated and the instruction may be removed in the future. Use msg.sender instead.\nSee also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin",
"function": "transferOwnership(address)",
"max_gas_used": 1051,
@ -12,7 +11,8 @@
"severity": "Medium",
"sourceMap": null,
"swc-id": "111",
"title": "Use of tx.origin"
"title": "Use of tx.origin",
"tx_sequence": "<TX-DATA>"
}
],
"success": true

@ -7,7 +7,8 @@
"tail": "The smart contract retrieves the transaction origin (tx.origin) using msg.origin. Use of msg.origin is deprecated and the instruction may be removed in the future. Use msg.sender instead.\nSee also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin"
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{

@ -4,7 +4,6 @@
{
"address": 567,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The binary subtraction can underflow.\nThe operands of the subtraction operation are not sufficiently constrained. The subtraction could therefore result in an integer underflow. Prevent the underflow by checking inputs or ensure sure that the underflow is caught by an assertion.",
"function": "sendeth(address,uint256)",
"max_gas_used": 78155,
@ -12,12 +11,12 @@
"severity": "High",
"sourceMap": null,
"swc-id": "101",
"title": "Integer Underflow"
"title": "Integer Underflow",
"tx_sequence": "<TX-DATA>"
},
{
"address": 649,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The binary subtraction can underflow.\nThe operands of the subtraction operation are not sufficiently constrained. The subtraction could therefore result in an integer underflow. Prevent the underflow by checking inputs or ensure sure that the underflow is caught by an assertion.",
"function": "sendeth(address,uint256)",
"max_gas_used": 78155,
@ -25,7 +24,8 @@
"severity": "High",
"sourceMap": null,
"swc-id": "101",
"title": "Integer Underflow"
"title": "Integer Underflow",
"tx_sequence": "<TX-DATA>"
}
],
"success": true

@ -7,7 +7,8 @@
"tail": "The operands of the subtraction operation are not sufficiently constrained. The subtraction could therefore result in an integer underflow. Prevent the underflow by checking inputs or ensure sure that the underflow is caught by an assertion."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -24,7 +25,8 @@
"tail": "The operands of the subtraction operation are not sufficiently constrained. The subtraction could therefore result in an integer underflow. Prevent the underflow by checking inputs or ensure sure that the underflow is caught by an assertion."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{

@ -4,7 +4,6 @@
{
"address": 196,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The contract executes an external message call.\nAn external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully.",
"function": "callchecked()",
"max_gas_used": 1210,
@ -12,12 +11,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "107",
"title": "External Call To Fixed Address"
"title": "External Call To Fixed Address",
"tx_sequence": "<TX-DATA>"
},
{
"address": 285,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The contract executes an external message call.\nAn external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully.",
"function": "callnotchecked()",
"max_gas_used": 1232,
@ -25,12 +24,12 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "107",
"title": "External Call To Fixed Address"
"title": "External Call To Fixed Address",
"tx_sequence": "<TX-DATA>"
},
{
"address": 285,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The return value of a message call is not checked.\nExternal calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states.",
"function": "callnotchecked()",
"max_gas_used": 35950,
@ -38,7 +37,8 @@
"severity": "Low",
"sourceMap": null,
"swc-id": "104",
"title": "Unchecked Call Return Value"
"title": "Unchecked Call Return Value",
"tx_sequence": "<TX-DATA>"
}
],
"success": true

@ -7,7 +7,8 @@
"tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -24,7 +25,8 @@
"tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -41,7 +43,8 @@
"tail": "External calls return a boolean value. If the callee contract halts with an exception, 'false' is returned and execution continues in the caller. It is usually recommended to wrap external calls into a require statement to prevent unexpected states."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{

@ -4,7 +4,6 @@
{
"address": 146,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The contract can be killed by anyone.\nAnyone can kill this contract and withdraw its balance to an arbitrary address.",
"function": "kill(address)",
"max_gas_used": 263,
@ -12,7 +11,8 @@
"severity": "High",
"sourceMap": null,
"swc-id": "106",
"title": "Unprotected Selfdestruct"
"title": "Unprotected Selfdestruct",
"tx_sequence": "<TX-DATA>"
}
],
"success": true

@ -7,7 +7,8 @@
"tail": "Anyone can kill this contract and withdraw its balance to an arbitrary address."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{

@ -4,7 +4,6 @@
{
"address": 567,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The binary subtraction can underflow.\nThe operands of the subtraction operation are not sufficiently constrained. The subtraction could therefore result in an integer underflow. Prevent the underflow by checking inputs or ensure sure that the underflow is caught by an assertion.",
"function": "sendeth(address,uint256)",
"max_gas_used": 52861,
@ -12,12 +11,12 @@
"severity": "High",
"sourceMap": null,
"swc-id": "101",
"title": "Integer Underflow"
"title": "Integer Underflow",
"tx_sequence": "<TX-DATA>"
},
{
"address": 649,
"contract": "Unknown",
"debug": "<DEBUG-DATA>",
"description": "The binary subtraction can underflow.\nThe operands of the subtraction operation are not sufficiently constrained. The subtraction could therefore result in an integer underflow. Prevent the underflow by checking inputs or ensure sure that the underflow is caught by an assertion.",
"function": "sendeth(address,uint256)",
"max_gas_used": 52861,
@ -25,7 +24,8 @@
"severity": "High",
"sourceMap": null,
"swc-id": "101",
"title": "Integer Underflow"
"title": "Integer Underflow",
"tx_sequence": "<TX-DATA>"
}
],
"success": true

@ -7,7 +7,8 @@
"tail": "The operands of the subtraction operation are not sufficiently constrained. The subtraction could therefore result in an integer underflow. Prevent the underflow by checking inputs or ensure sure that the underflow is caught by an assertion."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{
@ -24,7 +25,8 @@
"tail": "The operands of the subtraction operation are not sufficiently constrained. The subtraction could therefore result in an integer underflow. Prevent the underflow by checking inputs or ensure sure that the underflow is caught by an assertion."
},
"extra": {
"discoveryTime": "<DISCOVERY-TIME-DATA>"
"discoveryTime": "<DISCOVERY-TIME-DATA>",
"testCase": "<TEST-CASE>"
},
"locations": [
{

Loading…
Cancel
Save