From f9f8418688c5af10a35992a9432bd474b1b05a33 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Wed, 26 Dec 2018 16:35:06 +0530 Subject: [PATCH 01/56] Add the new json format --- mythril/analysis/report.py | 55 +++++++++++++++++++--------- mythril/analysis/swc_data.py | 27 +++++++++++++- mythril/disassembler/disassembly.py | 1 - mythril/ethereum/evmcontract.py | 13 +++++++ mythril/ethereum/util.py | 2 - mythril/laser/ethereum/svm.py | 1 + mythril/mythril.py | 10 +++-- mythril/solidity/soliditycontract.py | 25 ++++++++----- mythril/support/source_support.py | 32 ++++++++++++++++ mythril/support/truffle.py | 7 +++- 10 files changed, 138 insertions(+), 35 deletions(-) create mode 100644 mythril/support/source_support.py diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 18256122..56a6a8aa 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -5,6 +5,10 @@ from jinja2 import PackageLoader, Environment import _pysha3 as sha3 import hashlib +from mythril.solidity.soliditycontract import SolidityContract +from mythril.analysis.swc_data import SWC_TO_TITLE +from mythril.support.source_support import Source + log = logging.getLogger(__name__) @@ -35,16 +39,7 @@ class Issue: self.filename = None self.code = None self.lineno = None - - try: - keccak = sha3.keccak_256() - keccak.update(bytes.fromhex(bytecode)) - self.bytecode_hash = "0x" + keccak.hexdigest() - except ValueError: - log.debug( - "Unable to change the bytecode to bytes. Bytecode: {}".format(bytecode) - ) - self.bytecode_hash = "" + self.source_mapping = None @property def as_dict(self): @@ -60,6 +55,7 @@ class Issue: "debug": self.debug, "min_gas_used": self.min_gas_used, "max_gas_used": self.max_gas_used, + "SourceMap": self.source_mapping, } if self.filename and self.lineno: @@ -72,13 +68,16 @@ class Issue: return issue def add_code_info(self, contract): - if self.address: + if self.address and isinstance(self.contract, SolidityContract): codeinfo = contract.get_source_info( self.address, constructor=(self.function == "constructor") ) self.filename = codeinfo.filename self.code = codeinfo.code self.lineno = codeinfo.lineno + self.source_mapping = codeinfo.solc_mapping + else: + self.source_mapping = self.address class Report: @@ -86,10 +85,14 @@ class Report: loader=PackageLoader("mythril.analysis"), trim_blocks=True ) - def __init__(self, verbose=False): + def __init__(self, verbose=False, source=Source()): self.issues = {} self.verbose = verbose - pass + self.solc_version = "" + self.source_type = source.source_type + self.source_format = source.source_format + self.source_list = source.source_list + self.meta = source.meta def sorted_issues(self): issue_list = [issue.as_dict for key, issue in self.issues.items()] @@ -108,7 +111,21 @@ class Report: ) def as_json(self): - result = {"success": True, "error": None, "issues": self.sorted_issues()} + result = { + "issues": [ + { + "swcID": "SWC-{}".format(issue.swc_id), + "swcTitle": SWC_TO_TITLE[issue.swc_id], + "locations": [{"sourceMap": issue.source_mapping}], + "extra": "", + } + for issue in self.issues.values() + ], + "sourceType": self.source_type, + "sourceFormat": self.source_format, + "sourceList": self.source_list, + "meta": self.meta, + } return json.dumps(result, sort_keys=True) def as_swc_standard_format(self): @@ -116,12 +133,16 @@ class Report: result = { "issues": [ { - "swc-id": "SWC-{}".format(issue.swc_id), + "swcID": "SWC-{}".format(issue.swc_id), + "swcTitle": SWC_TO_TITLE[issue.swc_id], "bytecodeOffset": issue.address, - "codeHash": issue.bytecode_hash, } for issue in self.issues.values() - ] + ], + "sourceType": self.source_type, + "sourceFormat": self.source_format, + "sourceList": self.source_list, + "meta": self.meta, } return json.dumps(result, sort_keys=True) diff --git a/mythril/analysis/swc_data.py b/mythril/analysis/swc_data.py index 2f4d5ded..cb114054 100644 --- a/mythril/analysis/swc_data.py +++ b/mythril/analysis/swc_data.py @@ -15,7 +15,6 @@ MULTIPLE_SENDS = "113" TX_ORDER_DEPENDENCE = "114" TX_ORIGIN_USAGE = "115" TIMESTAMP_DEPENDENCE = "116" -# TODO: SWC ID 116 is missing, Add it if it's added to the https://github.com/SmartContractSecurity/SWC-registry INCORRECT_CONSTRUCTOR_NAME = "118" SHADOWING_STATE_VARIABLES = "119" WEAK_RANDOMNESS = "120" @@ -25,3 +24,29 @@ IMPROPER_VERIFICATION_BASED_ON_MSG_SENDER = "122" PREDICTABLE_VARS_DEPENDENCE = ( "N/A" ) # TODO: Add the swc id when this is added to the SWC Registry + +SWC_TO_TITLE = { + "100": "Function Default Visibility", + "101": "Integer Overflow and Underflow", + "102": "Outdated Compiler Version", + "103": "Floating Pragma", + "104": "Unchecked Call Return Value", + "105": "Unprotected Ether Withdrawal", + "106": "Unprotected SELFDESTRUCT Instruction", + "107": "Reentrancy", + "108": "State Variable Default Visibility", + "109": "Uninitialized Storage Pointer", + "110": "Assert Violation", + "111": "Use of Deprecated Solidity Functions", + "112": "Delegatecall to Untrusted Callee", + "113": "DoS with Failed Call", + "114": "Transaction Order Dependence", + "115": "Authorization through tx.origin", + "116": "Timestamp Dependence", + "117": "Signature Malleability", + "118": "Incorrect Constructor Name", + "119": "Shadowing State Variables", + "120": "Weak Sources of Randomness from Chain Attributes", + "121": "Missing Protection against Signature Replay Attacks", + "122": "Lack of Proper Signature Verification", +} diff --git a/mythril/disassembler/disassembly.py b/mythril/disassembler/disassembly.py index 0a937333..0ff70198 100644 --- a/mythril/disassembler/disassembly.py +++ b/mythril/disassembler/disassembly.py @@ -68,7 +68,6 @@ def get_function_info( # Append with missing 0s at the beginning function_hash = "0x" + instruction_list[index]["argument"][2:].rjust(8, "0") - function_names = signature_database.get(function_hash) if len(function_names) > 1: # In this case there was an ambiguous result diff --git a/mythril/ethereum/evmcontract.py b/mythril/ethereum/evmcontract.py index b0914a8f..26927b70 100644 --- a/mythril/ethereum/evmcontract.py +++ b/mythril/ethereum/evmcontract.py @@ -2,6 +2,10 @@ from mythril.disassembler.disassembly import Disassembly from ethereum import utils import persistent import re +import _pysha3 as sha3 +import logging + +log = logging.getLogger(__name__) class EVMContract(persistent.Persistent): @@ -23,6 +27,15 @@ class EVMContract(persistent.Persistent): self.creation_disassembly = Disassembly( creation_code, enable_online_lookup=enable_online_lookup ) + try: + keccak = sha3.keccak_256() + keccak.update(bytes.fromhex(self.code[2:])) + self.bytecode_hash = "0x" + keccak.hexdigest() + except ValueError: + log.debug( + "Unable to change the bytecode to bytes. Bytecode: {}".format(code) + ) + self.bytecode_hash = "" def as_dict(self): diff --git a/mythril/ethereum/util.py b/mythril/ethereum/util.py index 07537efc..78160b19 100644 --- a/mythril/ethereum/util.py +++ b/mythril/ethereum/util.py @@ -18,12 +18,10 @@ def safe_decode(hex_encoded_string): def get_solc_json(file, solc_binary="solc", solc_args=None): - cmd = [solc_binary, "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime"] if solc_args: cmd.extend(solc_args.split()) - if not "--allow-paths" in cmd: cmd.extend(["--allow-paths", "."]) else: diff --git a/mythril/laser/ethereum/svm.py b/mythril/laser/ethereum/svm.py index 085e3c14..0fdb14f2 100644 --- a/mythril/laser/ethereum/svm.py +++ b/mythril/laser/ethereum/svm.py @@ -200,6 +200,7 @@ class LaserEVM: self, global_state: GlobalState ) -> Tuple[List[GlobalState], Union[str, None]]: instructions = global_state.environment.code.instruction_list + try: op_code = instructions[global_state.mstate.pc]["opcode"] except IndexError: diff --git a/mythril/mythril.py b/mythril/mythril.py index 86bb4da0..f80780c3 100644 --- a/mythril/mythril.py +++ b/mythril/mythril.py @@ -25,6 +25,7 @@ from mythril.solidity.soliditycontract import SolidityContract, get_contracts_fr from mythril.ethereum.interface.rpc.client import EthJsonRpc from mythril.ethereum.interface.rpc.exceptions import ConnectionError from mythril.support import signatures +from mythril.support.source_support import Source from mythril.support.truffle import analyze_truffle_project from mythril.support.loader import DynLoader from mythril.exceptions import CompilerError, NoContractFoundError, CriticalError @@ -499,14 +500,15 @@ class Mythril(object): issues = fire_lasers(sym, modules) - if type(contract) == SolidityContract: - for issue in issues: - issue.add_code_info(contract) + for issue in issues: + issue.add_code_info(contract) all_issues += issues + source_data = Source() + source_data.get_source_from_contracts_list(self.contracts) # Finally, output the results - report = Report(verbose_report) + report = Report(verbose_report, source_data) for issue in all_issues: report.append_issue(issue) diff --git a/mythril/solidity/soliditycontract.py b/mythril/solidity/soliditycontract.py index 133a0b24..fbe74e09 100644 --- a/mythril/solidity/soliditycontract.py +++ b/mythril/solidity/soliditycontract.py @@ -5,11 +5,12 @@ from mythril.exceptions import NoContractFoundError class SourceMapping: - def __init__(self, solidity_file_idx, offset, length, lineno): + def __init__(self, solidity_file_idx, offset, length, lineno, mapping): self.solidity_file_idx = solidity_file_idx self.offset = offset self.length = length self.lineno = lineno + self.solc_mapping = mapping class SolidityFile: @@ -19,10 +20,11 @@ class SolidityFile: class SourceCodeInfo: - def __init__(self, filename, lineno, code): + def __init__(self, filename, lineno, code, mapping): self.filename = filename self.lineno = lineno self.code = code + self.solc_mapping = mapping def get_contracts_from_file(input_file, solc_args=None, solc_binary="solc"): @@ -43,8 +45,7 @@ def get_contracts_from_file(input_file, solc_args=None, solc_binary="solc"): class SolidityContract(EVMContract): - def __init__(self, input_file, name=None, solc_args=None, solc_binary="solc"): - + def __init__(self, input_file, name=None, solc_args=None, solc_binary="solc-0.5.2"): data = get_solc_json(input_file, solc_args=solc_args, solc_binary=solc_binary) self.solidity_files = [] @@ -104,8 +105,12 @@ class SolidityContract(EVMContract): disassembly = self.creation_disassembly if constructor else self.disassembly mappings = self.constructor_mappings if constructor else self.mappings index = helper.get_instruction_index(disassembly.instruction_list, address) + if index is None: + index = helper.get_instruction_index( + self.creation_disassembly.instruction_list, address + ) + mappings = self.constructor_mappings solidity_file = self.solidity_files[mappings[index].solidity_file_idx] - filename = solidity_file.filename offset = mappings[index].offset @@ -115,12 +120,14 @@ class SolidityContract(EVMContract): "utf-8", errors="ignore" ) lineno = mappings[index].lineno - - return SourceCodeInfo(filename, lineno, code) + return SourceCodeInfo(filename, lineno, code, mappings[index].solc_mapping) def _get_solc_mappings(self, srcmap, constructor=False): mappings = self.constructor_mappings if constructor else self.mappings + prev_item = "" for item in srcmap: + if item == "": + item = prev_item mapping = item.split(":") if len(mapping) > 0 and len(mapping[0]) > 0: @@ -137,5 +144,5 @@ class SolidityContract(EVMContract): .count("\n".encode("utf-8")) + 1 ) - - mappings.append(SourceMapping(idx, offset, length, lineno)) + prev_item = item + mappings.append(SourceMapping(idx, offset, length, lineno, item)) diff --git a/mythril/support/source_support.py b/mythril/support/source_support.py new file mode 100644 index 00000000..dbdccdd8 --- /dev/null +++ b/mythril/support/source_support.py @@ -0,0 +1,32 @@ +from mythril.solidity.soliditycontract import SolidityContract +from mythril.ethereum.evmcontract import EVMContract + + +class Source: + def __init__( + self, source_type=None, source_format=None, source_list=None, meta=None + ): + self.source_type = source_type + self.source_format = source_format + self.source_list = [] + self.meta = meta + + def get_source_from_contracts_list(self, contracts): + if contracts is None or len(contracts) == 0: + return + if isinstance(contracts[0], SolidityContract): + self.source_type = "solidity-file" + self.source_format = "text" + for contract in contracts: + self.source_list += [file.filename for file in contract.solidity_files] + elif isinstance(contracts[0], EVMContract): + self.source_format = "evm-byzantium-bytecode" + self.source_type = ( + "raw-bytecode" if contracts[0].name == "MAIN" else "ethereum-address" + ) + for contract in contracts: + self.source_list.append(contract.bytecode_hash) + + else: + assert False # Fail hard + self.meta = "" diff --git a/mythril/support/truffle.py b/mythril/support/truffle.py index d38d04de..39a18360 100644 --- a/mythril/support/truffle.py +++ b/mythril/support/truffle.py @@ -145,7 +145,11 @@ def get_sigs_from_truffle(sigs, contract_data): def get_mappings(source, deployed_source_map): mappings = [] + prev_item = "" for item in deployed_source_map: + if item == "": + item = prev_item + mapping = item.split(":") if len(mapping) > 0 and len(mapping[0]) > 0: @@ -158,7 +162,8 @@ def get_mappings(source, deployed_source_map): idx = int(mapping[2]) lineno = source.encode("utf-8")[0:offset].count("\n".encode("utf-8")) + 1 + prev_item = item - mappings.append(SourceMapping(idx, offset, length, lineno)) + mappings.append(SourceMapping(idx, offset, length, lineno, item)) return mappings From 298f7a8c9dcf88436a7c0f56ea882841afc83c6f Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Wed, 26 Dec 2018 16:39:41 +0530 Subject: [PATCH 02/56] use solc over solc-version --- mythril/solidity/soliditycontract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/solidity/soliditycontract.py b/mythril/solidity/soliditycontract.py index fbe74e09..5ebe9c24 100644 --- a/mythril/solidity/soliditycontract.py +++ b/mythril/solidity/soliditycontract.py @@ -45,7 +45,7 @@ def get_contracts_from_file(input_file, solc_args=None, solc_binary="solc"): class SolidityContract(EVMContract): - def __init__(self, input_file, name=None, solc_args=None, solc_binary="solc-0.5.2"): + def __init__(self, input_file, name=None, solc_args=None, solc_binary="solc"): data = get_solc_json(input_file, solc_args=solc_args, solc_binary=solc_binary) self.solidity_files = [] From bdf6c98feda72437102f8c3b59460423aa967c24 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 14:05:46 +0700 Subject: [PATCH 03/56] Fully implement standard format --- mythril/analysis/report.py | 46 +++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 56a6a8aa..dd023dfa 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -130,20 +130,44 @@ class Report: def as_swc_standard_format(self): """ Format defined for integration and correlation""" - result = { - "issues": [ + + _issues = [] + sourceList = [] + + for key, issue in self.issues.items(): + + if not issue.bytecode_hash in sourceList: + idx = len(sourceList) + sourceList.append(issue.bytecode_hash) + else: + idx = sourceList.index(issue.bytecode_hash) + + _issues.append( { - "swcID": "SWC-{}".format(issue.swc_id), - "swcTitle": SWC_TO_TITLE[issue.swc_id], - "bytecodeOffset": issue.address, + "swcID": issue.swc_id, + "swcTitle": issue.title, + "description": { + "head": "", + "tail": "" + }, + "severity": issue.type, + "locations": [ + { + "sourceMap": "%d:0:%d" % (issue.address, idx) + }, + ], + "extra": {} } - for issue in self.issues.values() - ], - "sourceType": self.source_type, - "sourceFormat": self.source_format, - "sourceList": self.source_list, - "meta": self.meta, + ) + + result = { + "issues": _issues, + "sourceType": "raw-bytecode", + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": sourceList, + "meta": {} } + return json.dumps(result, sort_keys=True) def as_markdown(self): From 3581d4e9bc37331ad45621bd8e416d87f1bab297 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 14:09:35 +0700 Subject: [PATCH 04/56] Add jsonv2 output format --- mythril/interfaces/cli.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mythril/interfaces/cli.py b/mythril/interfaces/cli.py index 77cd1d9c..868eb86f 100644 --- a/mythril/interfaces/cli.py +++ b/mythril/interfaces/cli.py @@ -106,7 +106,7 @@ def main(): outputs.add_argument( "-o", "--outform", - choices=["text", "markdown", "json"], + choices=["text", "markdown", "json", "jsonv2"], default="text", help="report output format", metavar="", @@ -423,6 +423,7 @@ def main(): ) outputs = { "json": report.as_json(), + "jsonv2": report.as_swc_standard_format(), "text": report.as_text(), "markdown": report.as_markdown(), } From 19aa4f2a1cbe566c431155e9dc42d5cc77a207c9 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 14:12:03 +0700 Subject: [PATCH 05/56] Compute bytecode hash on issue initialization --- mythril/analysis/report.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index dd023dfa..17ea4091 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -41,6 +41,16 @@ class Issue: self.lineno = None self.source_mapping = None + try: + keccak = sha3.keccak_256() + keccak.update(bytes.fromhex(bytecode)) + self.bytecode_hash = "0x" + keccak.hexdigest() + except ValueError: + log.debug( + "Unable to change the bytecode to bytes. Bytecode: {}".format(bytecode) + ) + self.bytecode_hash = "" + @property def as_dict(self): From 2de9c88c6e03064f177f91329ad44a1f7a16797e Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 14:18:22 +0700 Subject: [PATCH 06/56] Map SWC ID to title --- mythril/analysis/report.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 17ea4091..784cf25b 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -9,6 +9,7 @@ from mythril.solidity.soliditycontract import SolidityContract from mythril.analysis.swc_data import SWC_TO_TITLE from mythril.support.source_support import Source + log = logging.getLogger(__name__) @@ -152,10 +153,15 @@ class Report: else: idx = sourceList.index(issue.bytecode_hash) + try: + title = SWC_TO_TITLE[issue.swc_id] + except KeyError: + title = "Unspecified Security Issue" + _issues.append( { "swcID": issue.swc_id, - "swcTitle": issue.title, + "swcTitle": title, "description": { "head": "", "tail": "" From 4f413fda77dfdaa17ea5e32b3bed84d0248cdf6e Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 14:20:22 +0700 Subject: [PATCH 07/56] Change srcmap length value to '1' --- mythril/analysis/report.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 784cf25b..f058df3e 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -147,7 +147,7 @@ class Report: for key, issue in self.issues.items(): - if not issue.bytecode_hash in sourceList: + if issue.bytecode_hash not in sourceList: idx = len(sourceList) sourceList.append(issue.bytecode_hash) else: @@ -169,7 +169,7 @@ class Report: "severity": issue.type, "locations": [ { - "sourceMap": "%d:0:%d" % (issue.address, idx) + "sourceMap": "%d:1:%d" % (issue.address, idx) }, ], "extra": {} From e4dbb466e1cc3221eb1dcd9f4e87037c9e700145 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 14:46:17 +0700 Subject: [PATCH 08/56] Split descriptions into head and tail --- mythril/analysis/modules/delegatecall.py | 10 +++++--- .../modules/dependence_on_predictable_vars.py | 5 ++-- mythril/analysis/modules/deprecated_ops.py | 5 ++-- mythril/analysis/modules/ether_thief.py | 7 +++--- mythril/analysis/modules/exceptions.py | 5 ++-- mythril/analysis/modules/external_calls.py | 10 +++++--- mythril/analysis/modules/integer.py | 25 ++++++++++++------- mythril/analysis/modules/multiple_sends.py | 17 +++++++------ mythril/analysis/modules/suicide.py | 5 ++-- .../modules/transaction_order_dependence.py | 14 +++++++---- mythril/analysis/modules/unchecked_retval.py | 14 +++++++---- mythril/analysis/report.py | 11 +++++--- 12 files changed, 80 insertions(+), 48 deletions(-) diff --git a/mythril/analysis/modules/delegatecall.py b/mythril/analysis/modules/delegatecall.py index f9be0a6c..9ade31d7 100644 --- a/mythril/analysis/modules/delegatecall.py +++ b/mythril/analysis/modules/delegatecall.py @@ -78,13 +78,17 @@ def _concrete_call( address=address, swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, bytecode=state.environment.code.bytecode, - title="Call data forwarded with delegatecall()", - _type="Informational", + title="Delegatecall Proxy", + _type="Low", + description_head="This contract forwards its call data via Delegatecall in its fallback function.", + description_tail="The smart contract implements the Delegatecall proxy pattern. Note that callers can execute " + + "arbitrary functions in the callee contract and that the callee contract can access the storage of the " + + "calling contract. Make sure that the callee contract is audited properly.", gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) issue.description = ( - "This contract forwards its call data via DELEGATECALL in its fallback function. " + "" "This means that any function in the called contract can be executed. Note that the callee contract will have " "access to the storage of the calling contract.\n" ) diff --git a/mythril/analysis/modules/dependence_on_predictable_vars.py b/mythril/analysis/modules/dependence_on_predictable_vars.py index c4907bd9..bc6739b6 100644 --- a/mythril/analysis/modules/dependence_on_predictable_vars.py +++ b/mythril/analysis/modules/dependence_on_predictable_vars.py @@ -169,8 +169,9 @@ def _analyze_states(state: GlobalState) -> list: address=address, bytecode=call.state.environment.code.bytecode, title="Dependence on predictable variable", - _type="Informational", - description=description, + _type="Medium", + description_head="", + description_tail=description, swc_id=PREDICTABLE_VARS_DEPENDENCE, gas_used=( call.state.mstate.min_gas_used, diff --git a/mythril/analysis/modules/deprecated_ops.py b/mythril/analysis/modules/deprecated_ops.py index 60ad2be1..f6995333 100644 --- a/mythril/analysis/modules/deprecated_ops.py +++ b/mythril/analysis/modules/deprecated_ops.py @@ -42,9 +42,10 @@ def _analyze_state(state): address=instruction["address"], title=title, bytecode=state.environment.code.bytecode, - _type="Warning", swc_id=swc_id, - description=description, + _type="Medium", + description_head="", + description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) return [issue] diff --git a/mythril/analysis/modules/ether_thief.py b/mythril/analysis/modules/ether_thief.py index bc2bd57a..ac2de616 100644 --- a/mythril/analysis/modules/ether_thief.py +++ b/mythril/analysis/modules/ether_thief.py @@ -60,10 +60,11 @@ def _analyze_state(state): function_name=node.function_name, address=instruction["address"], swc_id=UNPROTECTED_ETHER_WITHDRAWAL, - title="Ether thief", - _type="Warning", + title="Unprotected Ether Withdrawal", + _type="High", bytecode=state.environment.code.bytecode, - description="Arbitrary senders other than the contract creator can withdraw ETH from the contract" + description_head="It appears that anyone can withdraw Ether from the contract account.", + 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, diff --git a/mythril/analysis/modules/exceptions.py b/mythril/analysis/modules/exceptions.py index 7d56ce36..a7870f5b 100644 --- a/mythril/analysis/modules/exceptions.py +++ b/mythril/analysis/modules/exceptions.py @@ -35,8 +35,9 @@ def _analyze_state(state) -> list: address=address, swc_id=ASSERT_VIOLATION, title="Exception state", - _type="Informational", - description=description, + _type="Low", + description_head="", + description_tail=description, bytecode=state.environment.code.bytecode, debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index 2386b3e2..d5f09f5f 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -51,9 +51,10 @@ def _analyze_state(state): address=address, swc_id=REENTRANCY, title="External call to user-supplied address", - _type="Warning", bytecode=state.environment.code.bytecode, - description=description, + _type="Medium", + description_head="", + description_tail=description, debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) @@ -76,9 +77,10 @@ def _analyze_state(state): address=address, swc_id=REENTRANCY, title="External call", - _type="Informational", bytecode=state.environment.code.bytecode, - description=description, + _type="Low", + description_head="", + description_tail=description, debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index c59e9982..f1ddd99d 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -135,20 +135,23 @@ class IntegerOverflowUnderflowModule(DetectionModule): ) ostate = annotation.overflowing_state node = ostate.node + + description = "This binary {} operation can result in {}.\n".format( + annotation.operator, title.lower() + ) + issue = Issue( contract=node.contract_name, function_name=node.function_name, address=ostate.get_current_instruction()["address"], swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, bytecode=ostate.environment.code.bytecode, - title=title, - _type="Warning", + _type="High", + description_head="", + description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) - issue.description = "This binary {} operation can result in {}.\n".format( - annotation.operator, title.lower() - ) try: issue.debug = str( solver.get_transaction_sequence( @@ -168,6 +171,11 @@ class IntegerOverflowUnderflowModule(DetectionModule): continue ostate = annotation.overflowing_state node = ostate.node + + description = "This binary {} operation can result in integer overflow.\n".format( + annotation.operator + ) + issue = Issue( contract=node.contract_name, function_name=node.function_name, @@ -175,13 +183,12 @@ class IntegerOverflowUnderflowModule(DetectionModule): swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, bytecode=ostate.environment.code.bytecode, title="Integer Overflow", - _type="Warning", + _type="High", + description_head="", + description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) - issue.description = "This binary {} operation can result in integer overflow.\n".format( - annotation.operator - ) try: issue.debug = str( solver.get_transaction_sequence( diff --git a/mythril/analysis/modules/multiple_sends.py b/mythril/analysis/modules/multiple_sends.py index b4178b25..70002f93 100644 --- a/mythril/analysis/modules/multiple_sends.py +++ b/mythril/analysis/modules/multiple_sends.py @@ -71,6 +71,13 @@ def _analyze_state(state: GlobalState): else: # RETURN or STOP if len(calls) > 1: + + description = ( + "Multiple sends are executed in a single transaction. " + "Try to isolate each external call into its own transaction," + " as external calls can fail accidentally or deliberately.\nConsecutive calls: \n" + ) + issue = Issue( contract=node.contract_name, function_name=node.function_name, @@ -78,16 +85,12 @@ def _analyze_state(state: GlobalState): swc_id=MULTIPLE_SENDS, bytecode=state.environment.code.bytecode, title="Multiple Calls", - _type="Informational", + _type="Medium", + description_head="", + description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) - issue.description = ( - "Multiple sends are executed in a single transaction. " - "Try to isolate each external call into its own transaction," - " as external calls can fail accidentally or deliberately.\nConsecutive calls: \n" - ) - for call in calls: issue.description += "Call at address: {}\n".format( call.state.get_current_instruction()["address"] diff --git a/mythril/analysis/modules/suicide.py b/mythril/analysis/modules/suicide.py index 701e850d..a5e9c9a6 100644 --- a/mythril/analysis/modules/suicide.py +++ b/mythril/analysis/modules/suicide.py @@ -46,8 +46,9 @@ def _analyze_state(state): swc_id=UNPROTECTED_SELFDESTRUCT, bytecode=state.environment.code.bytecode, title="Unchecked SUICIDE", - _type="Warning", - description=description, + _type="High", + description_head="", + description_tail=description, debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/mythril/analysis/modules/transaction_order_dependence.py b/mythril/analysis/modules/transaction_order_dependence.py index 665672ca..3952e0bb 100644 --- a/mythril/analysis/modules/transaction_order_dependence.py +++ b/mythril/analysis/modules/transaction_order_dependence.py @@ -39,6 +39,11 @@ class TxOrderDependenceModule(DetectionModule): self._get_influencing_sstores(statespace, interesting_storages) ) + description = ( + "Possible transaction order dependence vulnerability: The value or " + "direction of the call statement is determined from a tainted storage location." + ) + # Build issue if necessary if len(changing_sstores) > 0: node = call.node @@ -50,17 +55,16 @@ class TxOrderDependenceModule(DetectionModule): title="Transaction order dependence", bytecode=call.state.environment.code.bytecode, swc_id=TX_ORDER_DEPENDENCE, - _type="Warning", + _type="Medium", + description_head="", + description_tail=description, gas_used=( call.state.mstate.min_gas_used, call.state.mstate.max_gas_used, ), ) - issue.description = ( - "Possible transaction order dependence vulnerability: The value or " - "direction of the call statement is determined from a tainted storage location." - ) + issues.append(issue) return issues diff --git a/mythril/analysis/modules/unchecked_retval.py b/mythril/analysis/modules/unchecked_retval.py index 6af3088d..eb7a7108 100644 --- a/mythril/analysis/modules/unchecked_retval.py +++ b/mythril/analysis/modules/unchecked_retval.py @@ -67,10 +67,15 @@ def _analyze_state(state: GlobalState) -> list: issues = [] for retval in retvals: try: - model = solver.get_model(node.constraints + [retval["retval"] == 0]) + solver.get_model(node.constraints + [retval["retval"] == 0]) except UnsatError: continue + description = ( + "The return value of an external call is not checked. " + "Note that execution continue even if the called contract throws." + ) + issue = Issue( contract=node.contract_name, function_name=node.function_name, @@ -78,13 +83,12 @@ def _analyze_state(state: GlobalState) -> list: bytecode=state.environment.code.bytecode, title="Unchecked CALL return value", swc_id=UNCHECKED_RET_VAL, + _type="Low", + description_head="", + description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) - issue.description = ( - "The return value of an external call is not checked. " - "Note that execution continue even if the called contract throws." - ) issues.append(issue) return issues diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index f058df3e..e720eadc 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -24,7 +24,8 @@ class Issue: bytecode, gas_used=(None, None), _type="Informational", - description="", + description_head="", + description_tail="", debug="", ): @@ -32,7 +33,9 @@ class Issue: self.contract = contract self.function = function_name self.address = address - self.description = description + self.description_head = description_head, + self.description_tail = description_tail, + self.description = "%s %s" % (description_head, description_tail) self.type = _type self.debug = debug self.swc_id = swc_id @@ -163,8 +166,8 @@ class Report: "swcID": issue.swc_id, "swcTitle": title, "description": { - "head": "", - "tail": "" + "head": issue.description_head, + "tail": issue.description_tail }, "severity": issue.type, "locations": [ From 4f332df5c4a56c6b30e6c6748cc86ac03614dc90 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 14:53:15 +0700 Subject: [PATCH 09/56] Add missing title, fix title capitalization --- mythril/analysis/modules/dependence_on_predictable_vars.py | 7 ++++--- mythril/analysis/modules/deprecated_ops.py | 2 +- mythril/analysis/modules/exceptions.py | 2 +- mythril/analysis/modules/external_calls.py | 2 +- mythril/analysis/modules/integer.py | 1 + mythril/analysis/modules/multiple_sends.py | 2 +- mythril/analysis/modules/suicide.py | 4 ++-- mythril/analysis/modules/transaction_order_dependence.py | 2 +- mythril/analysis/modules/unchecked_retval.py | 2 +- 9 files changed, 13 insertions(+), 11 deletions(-) diff --git a/mythril/analysis/modules/dependence_on_predictable_vars.py b/mythril/analysis/modules/dependence_on_predictable_vars.py index bc6739b6..63f90a26 100644 --- a/mythril/analysis/modules/dependence_on_predictable_vars.py +++ b/mythril/analysis/modules/dependence_on_predictable_vars.py @@ -133,9 +133,10 @@ def _analyze_states(state: GlobalState) -> list: function_name=call.node.function_name, address=address, bytecode=call.state.environment.code.bytecode, - title="Dependence on predictable variable", + title="Dependence on Predictable Variable", _type="Warning", - description=description, + description_head="", + description_tail=description, swc_id=PREDICTABLE_VARS_DEPENDENCE, gas_used=( call.state.mstate.min_gas_used, @@ -168,7 +169,7 @@ def _analyze_states(state: GlobalState) -> list: function_name=call.node.function_name, address=address, bytecode=call.state.environment.code.bytecode, - title="Dependence on predictable variable", + title="Dependence on Predictable Variable", _type="Medium", description_head="", description_tail=description, diff --git a/mythril/analysis/modules/deprecated_ops.py b/mythril/analysis/modules/deprecated_ops.py index f6995333..9ede3751 100644 --- a/mythril/analysis/modules/deprecated_ops.py +++ b/mythril/analysis/modules/deprecated_ops.py @@ -29,7 +29,7 @@ def _analyze_state(state): elif instruction["opcode"] == "CALLCODE": log.debug("CALLCODE in function " + node.function_name) - title = "Use of callcode" + title = "Use of Callcode" description = ( "The function `{}` uses callcode. Callcode does not persist sender or value over the call. " "Use delegatecall instead.".format(node.function_name) diff --git a/mythril/analysis/modules/exceptions.py b/mythril/analysis/modules/exceptions.py index a7870f5b..1b2f58e6 100644 --- a/mythril/analysis/modules/exceptions.py +++ b/mythril/analysis/modules/exceptions.py @@ -34,7 +34,7 @@ def _analyze_state(state) -> list: function_name=node.function_name, address=address, swc_id=ASSERT_VIOLATION, - title="Exception state", + title="Exception State", _type="Low", description_head="", description_tail=description, diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index d5f09f5f..2c8fd119 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -50,7 +50,7 @@ def _analyze_state(state): function_name=node.function_name, address=address, swc_id=REENTRANCY, - title="External call to user-supplied address", + title="External Call to User-supplied Address", bytecode=state.environment.code.bytecode, _type="Medium", description_head="", diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index f1ddd99d..78ded8dd 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -146,6 +146,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): address=ostate.get_current_instruction()["address"], swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, bytecode=ostate.environment.code.bytecode, + title="Integer Underflow", _type="High", description_head="", description_tail=description, diff --git a/mythril/analysis/modules/multiple_sends.py b/mythril/analysis/modules/multiple_sends.py index 70002f93..4575a1d1 100644 --- a/mythril/analysis/modules/multiple_sends.py +++ b/mythril/analysis/modules/multiple_sends.py @@ -84,7 +84,7 @@ def _analyze_state(state: GlobalState): address=instruction["address"], swc_id=MULTIPLE_SENDS, bytecode=state.environment.code.bytecode, - title="Multiple Calls", + title="Multiple Calls in a Single Transaction", _type="Medium", description_head="", description_tail=description, diff --git a/mythril/analysis/modules/suicide.py b/mythril/analysis/modules/suicide.py index a5e9c9a6..3bf58b01 100644 --- a/mythril/analysis/modules/suicide.py +++ b/mythril/analysis/modules/suicide.py @@ -45,7 +45,7 @@ def _analyze_state(state): address=instruction["address"], swc_id=UNPROTECTED_SELFDESTRUCT, bytecode=state.environment.code.bytecode, - title="Unchecked SUICIDE", + title="Unprotected Selfdestruct", _type="High", description_head="", description_tail=description, @@ -62,7 +62,7 @@ def _analyze_state(state): class SuicideModule(DetectionModule): def __init__(self): super().__init__( - name="Unprotected Suicide", + name="Unprotected Selfdestruct", swc_id=UNPROTECTED_SELFDESTRUCT, description=(DESCRIPTION), entrypoint="callback", diff --git a/mythril/analysis/modules/transaction_order_dependence.py b/mythril/analysis/modules/transaction_order_dependence.py index 3952e0bb..9ed1eeca 100644 --- a/mythril/analysis/modules/transaction_order_dependence.py +++ b/mythril/analysis/modules/transaction_order_dependence.py @@ -52,7 +52,7 @@ class TxOrderDependenceModule(DetectionModule): contract=node.contract_name, function_name=node.function_name, address=instruction["address"], - title="Transaction order dependence", + title="Transaction Order Dependence", bytecode=call.state.environment.code.bytecode, swc_id=TX_ORDER_DEPENDENCE, _type="Medium", diff --git a/mythril/analysis/modules/unchecked_retval.py b/mythril/analysis/modules/unchecked_retval.py index eb7a7108..2ac892f9 100644 --- a/mythril/analysis/modules/unchecked_retval.py +++ b/mythril/analysis/modules/unchecked_retval.py @@ -81,7 +81,7 @@ def _analyze_state(state: GlobalState) -> list: function_name=node.function_name, address=retval["address"], bytecode=state.environment.code.bytecode, - title="Unchecked CALL return value", + title="Unchecked CALL Return Value", swc_id=UNCHECKED_RET_VAL, _type="Low", description_head="", From 666607cabfde9ea1f7353265fd06f50c05fc5ebc Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 15:01:26 +0700 Subject: [PATCH 10/56] Refactor '_type' to 'severity' --- mythril/analysis/modules/delegatecall.py | 2 +- .../analysis/modules/dependence_on_predictable_vars.py | 10 +++++----- mythril/analysis/modules/deprecated_ops.py | 2 +- mythril/analysis/modules/ether_thief.py | 2 +- mythril/analysis/modules/exceptions.py | 2 +- mythril/analysis/modules/external_calls.py | 4 ++-- mythril/analysis/modules/integer.py | 4 ++-- mythril/analysis/modules/multiple_sends.py | 2 +- mythril/analysis/modules/suicide.py | 2 +- .../analysis/modules/transaction_order_dependence.py | 2 +- mythril/analysis/modules/unchecked_retval.py | 2 +- mythril/analysis/report.py | 8 ++++---- mythril/analysis/templates/report_as_markdown.jinja2 | 2 +- mythril/analysis/templates/report_as_text.jinja2 | 2 +- 14 files changed, 23 insertions(+), 23 deletions(-) diff --git a/mythril/analysis/modules/delegatecall.py b/mythril/analysis/modules/delegatecall.py index 9ade31d7..ef84b190 100644 --- a/mythril/analysis/modules/delegatecall.py +++ b/mythril/analysis/modules/delegatecall.py @@ -79,7 +79,7 @@ def _concrete_call( swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, bytecode=state.environment.code.bytecode, title="Delegatecall Proxy", - _type="Low", + severity="Low", description_head="This contract forwards its call data via Delegatecall in its fallback function.", description_tail="The smart contract implements the Delegatecall proxy pattern. Note that callers can execute " + "arbitrary functions in the callee contract and that the callee contract can access the storage of the " diff --git a/mythril/analysis/modules/dependence_on_predictable_vars.py b/mythril/analysis/modules/dependence_on_predictable_vars.py index 63f90a26..777d0493 100644 --- a/mythril/analysis/modules/dependence_on_predictable_vars.py +++ b/mythril/analysis/modules/dependence_on_predictable_vars.py @@ -72,7 +72,7 @@ def _analyze_states(state: GlobalState) -> list: for item in found: description += "- block.{}\n".format(item) if solve(call): - swc_type = ( + swc_id = ( TIMESTAMP_DEPENDENCE if item == "timestamp" else PREDICTABLE_VARS_DEPENDENCE @@ -81,10 +81,10 @@ def _analyze_states(state: GlobalState) -> list: contract=call.node.contract_name, function_name=call.node.function_name, address=address, - swc_id=swc_type, + swc_id=swc_id, bytecode=call.state.environment.code.bytecode, title="Dependence on predictable environment variable", - _type="Warning", + severity="Warning", description=description, gas_used=( call.state.mstate.min_gas_used, @@ -134,7 +134,7 @@ def _analyze_states(state: GlobalState) -> list: address=address, bytecode=call.state.environment.code.bytecode, title="Dependence on Predictable Variable", - _type="Warning", + severity="Warning", description_head="", description_tail=description, swc_id=PREDICTABLE_VARS_DEPENDENCE, @@ -170,7 +170,7 @@ def _analyze_states(state: GlobalState) -> list: address=address, bytecode=call.state.environment.code.bytecode, title="Dependence on Predictable Variable", - _type="Medium", + severity="Medium", description_head="", description_tail=description, swc_id=PREDICTABLE_VARS_DEPENDENCE, diff --git a/mythril/analysis/modules/deprecated_ops.py b/mythril/analysis/modules/deprecated_ops.py index 9ede3751..b3e24e47 100644 --- a/mythril/analysis/modules/deprecated_ops.py +++ b/mythril/analysis/modules/deprecated_ops.py @@ -43,7 +43,7 @@ def _analyze_state(state): title=title, bytecode=state.environment.code.bytecode, swc_id=swc_id, - _type="Medium", + severity="Medium", description_head="", description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), diff --git a/mythril/analysis/modules/ether_thief.py b/mythril/analysis/modules/ether_thief.py index ac2de616..b9e5ea85 100644 --- a/mythril/analysis/modules/ether_thief.py +++ b/mythril/analysis/modules/ether_thief.py @@ -61,7 +61,7 @@ def _analyze_state(state): address=instruction["address"], swc_id=UNPROTECTED_ETHER_WITHDRAWAL, title="Unprotected Ether Withdrawal", - _type="High", + severity="High", bytecode=state.environment.code.bytecode, description_head="It appears that anyone can withdraw Ether from the contract account.", description_tail="Arbitrary senders other than the contract creator can withdraw ETH from the contract" diff --git a/mythril/analysis/modules/exceptions.py b/mythril/analysis/modules/exceptions.py index 1b2f58e6..42488418 100644 --- a/mythril/analysis/modules/exceptions.py +++ b/mythril/analysis/modules/exceptions.py @@ -35,7 +35,7 @@ def _analyze_state(state) -> list: address=address, swc_id=ASSERT_VIOLATION, title="Exception State", - _type="Low", + severity="Low", description_head="", description_tail=description, bytecode=state.environment.code.bytecode, diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index 2c8fd119..59cd2a05 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -52,7 +52,7 @@ def _analyze_state(state): swc_id=REENTRANCY, title="External Call to User-supplied Address", bytecode=state.environment.code.bytecode, - _type="Medium", + severity="Medium", description_head="", description_tail=description, debug=debug, @@ -78,7 +78,7 @@ def _analyze_state(state): swc_id=REENTRANCY, title="External call", bytecode=state.environment.code.bytecode, - _type="Low", + severity="Low", description_head="", description_tail=description, debug=debug, diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 78ded8dd..5af8c614 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -147,7 +147,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, bytecode=ostate.environment.code.bytecode, title="Integer Underflow", - _type="High", + severity="High", description_head="", description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), @@ -184,7 +184,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, bytecode=ostate.environment.code.bytecode, title="Integer Overflow", - _type="High", + severity="High", description_head="", description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), diff --git a/mythril/analysis/modules/multiple_sends.py b/mythril/analysis/modules/multiple_sends.py index 4575a1d1..e20a2695 100644 --- a/mythril/analysis/modules/multiple_sends.py +++ b/mythril/analysis/modules/multiple_sends.py @@ -85,7 +85,7 @@ def _analyze_state(state: GlobalState): swc_id=MULTIPLE_SENDS, bytecode=state.environment.code.bytecode, title="Multiple Calls in a Single Transaction", - _type="Medium", + severity="Medium", description_head="", description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), diff --git a/mythril/analysis/modules/suicide.py b/mythril/analysis/modules/suicide.py index 3bf58b01..15afe732 100644 --- a/mythril/analysis/modules/suicide.py +++ b/mythril/analysis/modules/suicide.py @@ -46,7 +46,7 @@ def _analyze_state(state): swc_id=UNPROTECTED_SELFDESTRUCT, bytecode=state.environment.code.bytecode, title="Unprotected Selfdestruct", - _type="High", + severity="High", description_head="", description_tail=description, debug=debug, diff --git a/mythril/analysis/modules/transaction_order_dependence.py b/mythril/analysis/modules/transaction_order_dependence.py index 9ed1eeca..781e6aca 100644 --- a/mythril/analysis/modules/transaction_order_dependence.py +++ b/mythril/analysis/modules/transaction_order_dependence.py @@ -55,7 +55,7 @@ class TxOrderDependenceModule(DetectionModule): title="Transaction Order Dependence", bytecode=call.state.environment.code.bytecode, swc_id=TX_ORDER_DEPENDENCE, - _type="Medium", + severity="Medium", description_head="", description_tail=description, gas_used=( diff --git a/mythril/analysis/modules/unchecked_retval.py b/mythril/analysis/modules/unchecked_retval.py index 2ac892f9..1abc21f9 100644 --- a/mythril/analysis/modules/unchecked_retval.py +++ b/mythril/analysis/modules/unchecked_retval.py @@ -83,7 +83,7 @@ def _analyze_state(state: GlobalState) -> list: bytecode=state.environment.code.bytecode, title="Unchecked CALL Return Value", swc_id=UNCHECKED_RET_VAL, - _type="Low", + severity="Low", description_head="", description_tail=description, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index e720eadc..9ee8f1c1 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -23,7 +23,7 @@ class Issue: title, bytecode, gas_used=(None, None), - _type="Informational", + severity=None, description_head="", description_tail="", debug="", @@ -36,7 +36,7 @@ class Issue: self.description_head = description_head, self.description_tail = description_tail, self.description = "%s %s" % (description_head, description_tail) - self.type = _type + self.severity = severity self.debug = debug self.swc_id = swc_id self.min_gas_used, self.max_gas_used = gas_used @@ -64,7 +64,7 @@ class Issue: "contract": self.contract, "description": self.description, "function": self.function, - "type": self.type, + "severity": self.severity, "address": self.address, "debug": self.debug, "min_gas_used": self.min_gas_used, @@ -169,7 +169,7 @@ class Report: "head": issue.description_head, "tail": issue.description_tail }, - "severity": issue.type, + "severity": issue.severity, "locations": [ { "sourceMap": "%d:1:%d" % (issue.address, idx) diff --git a/mythril/analysis/templates/report_as_markdown.jinja2 b/mythril/analysis/templates/report_as_markdown.jinja2 index b3efd687..e6952535 100644 --- a/mythril/analysis/templates/report_as_markdown.jinja2 +++ b/mythril/analysis/templates/report_as_markdown.jinja2 @@ -4,7 +4,7 @@ ## {{ issue.title }} - SWC ID: {{ issue['swc-id'] }} -- Type: {{ issue.type }} +- Severity: {{ issue.severity }} - Contract: {{ issue.contract | default("Unknown") }} - Function name: `{{ issue.function }}` - PC address: {{ issue.address }} diff --git a/mythril/analysis/templates/report_as_text.jinja2 b/mythril/analysis/templates/report_as_text.jinja2 index 05adda1b..32d3cf02 100644 --- a/mythril/analysis/templates/report_as_text.jinja2 +++ b/mythril/analysis/templates/report_as_text.jinja2 @@ -2,7 +2,7 @@ {% for issue in issues %} ==== {{ issue.title }} ==== SWC ID: {{ issue['swc-id'] }} -Type: {{ issue.type }} +Severity: {{ issue.severity }} Contract: {{ issue.contract | default("Unknown") }} Function name: {{ issue.function }} PC address: {{ issue.address }} From 55be0cf8fac5c269cebb6564167afabbd473290d Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 15:14:09 +0700 Subject: [PATCH 11/56] Rewrite issue descriptions (WIP) --- mythril/analysis/modules/external_calls.py | 29 +++++++++++----------- mythril/analysis/modules/integer.py | 21 ++++++---------- mythril/analysis/modules/suicide.py | 8 +++--- 3 files changed, 25 insertions(+), 33 deletions(-) diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index 59cd2a05..95f1d098 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -39,22 +39,22 @@ def _analyze_state(state): transaction_sequence = solver.get_transaction_sequence(state, constraints) debug = str(transaction_sequence) - description = ( - "The contract executes a function call with high gas to a user-supplied address. " - "Note that the callee can contain arbitrary code and may re-enter any function in this contract. " - "Review the business logic carefully to prevent unanticipated effects on the contract state." - ) + description_head = "The contract executes a function call to a user-supplied address." + description_tail = "An external function call is executed. The callee address 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." issue = Issue( contract=node.contract_name, function_name=node.function_name, address=address, swc_id=REENTRANCY, - title="External Call to User-supplied Address", + title="External Call To User-Supplied Address", bytecode=state.environment.code.bytecode, severity="Medium", - description_head="", - description_tail=description, + description_head=description_head, + description_tail=description_tail, debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) @@ -66,21 +66,20 @@ def _analyze_state(state): ) debug = str(transaction_sequence) - description = ( - "The contract executes a function call to an external address. " - "Verify that the code at this address is trusted and immutable." - ) + description_head = "The contract executes a function call to an external address." + description_tail = "An external function call to a fixed contract address is executed. Note" \ + "that the callee contract should be reviewed carefully." issue = Issue( contract=node.contract_name, function_name=state.node.function_name, address=address, swc_id=REENTRANCY, - title="External call", + title="External Call To Fixed Address", bytecode=state.environment.code.bytecode, severity="Low", - description_head="", - description_tail=description, + description_head=description_head , + description_tail=description_tail, debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 5af8c614..e5d50bd8 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -129,17 +129,13 @@ class IntegerOverflowUnderflowModule(DetectionModule): continue title = ( - "Integer Underflow" + "integer underflow" if annotation.operator == "subtraction" - else "Integer Overflow" + else "integer overflow" ) ostate = annotation.overflowing_state node = ostate.node - description = "This binary {} operation can result in {}.\n".format( - annotation.operator, title.lower() - ) - issue = Issue( contract=node.contract_name, function_name=node.function_name, @@ -148,8 +144,9 @@ class IntegerOverflowUnderflowModule(DetectionModule): bytecode=ostate.environment.code.bytecode, title="Integer Underflow", severity="High", - description_head="", - description_tail=description, + description_head= "The binary {} operation can result in an {}.\n".format( + annotation.operator, title.lower()), + description_tail="", gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) @@ -173,10 +170,6 @@ class IntegerOverflowUnderflowModule(DetectionModule): ostate = annotation.overflowing_state node = ostate.node - description = "This binary {} operation can result in integer overflow.\n".format( - annotation.operator - ) - issue = Issue( contract=node.contract_name, function_name=node.function_name, @@ -185,8 +178,8 @@ class IntegerOverflowUnderflowModule(DetectionModule): bytecode=ostate.environment.code.bytecode, title="Integer Overflow", severity="High", - description_head="", - description_tail=description, + description_head="The binary {} operation can result in an integer overflow.\n".format(annotation.operator), + description_tail="", gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/mythril/analysis/modules/suicide.py b/mythril/analysis/modules/suicide.py index 15afe732..67de3e1a 100644 --- a/mythril/analysis/modules/suicide.py +++ b/mythril/analysis/modules/suicide.py @@ -28,12 +28,12 @@ def _analyze_state(state): state, node.constraints + [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF], ) - description = "Anyone can kill this contract and withdraw its balance to their own account." + description_head = "Anyone can kill this contract and withdraw its balance to their own account." except UnsatError: transaction_sequence = solver.get_transaction_sequence( state, node.constraints ) - description = ( + description_head = ( "The contract can be killed by anyone. Don't accidentally kill it." ) @@ -47,8 +47,8 @@ def _analyze_state(state): bytecode=state.environment.code.bytecode, title="Unprotected Selfdestruct", severity="High", - description_head="", - description_tail=description, + description_head=description_head, + description_tail="", debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) From c1fafb85a8e27c35147fff9e5c7397a58d4d03ad Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 17:18:00 +0700 Subject: [PATCH 12/56] Update report texts --- mythril/analysis/modules/delegatecall.py | 9 ++-- .../modules/dependence_on_predictable_vars.py | 48 ++++++++++--------- mythril/analysis/modules/external_calls.py | 2 +- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/mythril/analysis/modules/delegatecall.py b/mythril/analysis/modules/delegatecall.py index ef84b190..b7c96e76 100644 --- a/mythril/analysis/modules/delegatecall.py +++ b/mythril/analysis/modules/delegatecall.py @@ -80,10 +80,11 @@ def _concrete_call( bytecode=state.environment.code.bytecode, title="Delegatecall Proxy", severity="Low", - description_head="This contract forwards its call data via Delegatecall in its fallback function.", - description_tail="The smart contract implements the Delegatecall proxy pattern. Note that callers can execute " - + "arbitrary functions in the callee contract and that the callee contract can access the storage of the " - + "calling contract. Make sure that the callee contract is audited properly.", + description_head="The contract implements a delegatecall proxy.", + description_tail="The smart contract forwards the received calldata via delegatecall. Note that callers" + "can execute arbitrary functions in the callee contract and that the callee contract " + "can access the storage of the calling contract. " + "Make sure that the callee contract is audited properly.", gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/mythril/analysis/modules/dependence_on_predictable_vars.py b/mythril/analysis/modules/dependence_on_predictable_vars.py index 777d0493..117c92b9 100644 --- a/mythril/analysis/modules/dependence_on_predictable_vars.py +++ b/mythril/analysis/modules/dependence_on_predictable_vars.py @@ -4,7 +4,7 @@ from mythril.analysis.ops import Call, VarType from mythril.analysis import solver from mythril.analysis.report import Issue from mythril.analysis.call_helpers import get_call_from_state -from mythril.analysis.swc_data import TIMESTAMP_DEPENDENCE, PREDICTABLE_VARS_DEPENDENCE +from mythril.analysis.swc_data import TIMESTAMP_DEPENDENCE, WEAK_RANDOMNESS from mythril.analysis.modules.base import DetectionModule from mythril.exceptions import UnsatError import logging @@ -16,7 +16,7 @@ class PredictableDependenceModule(DetectionModule): def __init__(self): super().__init__( name="Dependence of Predictable Variables", - swc_id="{} {}".format(TIMESTAMP_DEPENDENCE, PREDICTABLE_VARS_DEPENDENCE), + swc_id="{} {}".format(TIMESTAMP_DEPENDENCE, WEAK_RANDOMNESS), description=( "Check for CALLs that send >0 Ether as a result of computation " "based on predictable variables such as block.coinbase, " @@ -55,8 +55,7 @@ def _analyze_states(state: GlobalState) -> list: address = call.state.get_current_instruction()["address"] - description = "In the function `" + call.node.function_name + "` " - description += "the following predictable state variables are used to determine Ether recipient:\n" + description = "The contract sends Ether depending on the values of the following variables:\n" # First check: look for predictable state variables in node & call recipient constraints @@ -75,8 +74,13 @@ def _analyze_states(state: GlobalState) -> list: swc_id = ( TIMESTAMP_DEPENDENCE if item == "timestamp" - else PREDICTABLE_VARS_DEPENDENCE + else WEAK_RANDOMNESS ) + + description += "Note that the values of variables like coinbase, gaslimit, block number and timestamp " \ + "are predictable and/or can be manipulated by a malicious miner. "\ + "Don't use them for random number generation or to make critical decisions." + issue = Issue( contract=call.node.contract_name, function_name=call.node.function_name, @@ -84,8 +88,9 @@ def _analyze_states(state: GlobalState) -> list: swc_id=swc_id, bytecode=call.state.environment.code.bytecode, title="Dependence on predictable environment variable", - severity="Warning", - description=description, + severity="Low", + description_head="Sending of Ether depends on a predictable variable.", + description_tail=description, gas_used=( call.state.mstate.min_gas_used, call.state.mstate.max_gas_used, @@ -97,7 +102,6 @@ def _analyze_states(state: GlobalState) -> list: for constraint in call.node.constraints[:] + [call.to]: if "blockhash" in str(constraint): - description = "In the function `" + call.node.function_name + "` " if "number" in str(constraint): m = re.search(r"blockhash\w+(\s-\s(\d+))*", str(constraint)) if m and solve(call): @@ -105,8 +109,8 @@ def _analyze_states(state: GlobalState) -> list: found = m.group(1) if found: # block.blockhash(block.number - N) - description += ( - "predictable expression 'block.blockhash(block.number - " + description = ( + "The predictable expression 'block.blockhash(block.number - " + m.group(2) + ")' is used to determine Ether recipient" ) @@ -117,13 +121,13 @@ def _analyze_states(state: GlobalState) -> list: elif "storage" in str( constraint ): # block.blockhash(block.number - storage_0) - description += ( - "predictable expression 'block.blockhash(block.number - " + description = ( + "The predictable expression 'block.blockhash(block.number - " + "some_storage_var)' is used to determine Ether recipient" ) else: # block.blockhash(block.number) - description += ( - "predictable expression 'block.blockhash(block.number)'" + description = ( + "The predictable expression 'block.blockhash(block.number)'" + " is used to determine Ether recipient" ) description += ", this expression will always be equal to zero." @@ -134,10 +138,10 @@ def _analyze_states(state: GlobalState) -> list: address=address, bytecode=call.state.environment.code.bytecode, title="Dependence on Predictable Variable", - severity="Warning", - description_head="", + severity="Low", + description_head="Sending of Ether depends on the blockhash.", description_tail=description, - swc_id=PREDICTABLE_VARS_DEPENDENCE, + swc_id=WEAK_RANDOMNESS, gas_used=( call.state.mstate.min_gas_used, call.state.mstate.max_gas_used, @@ -160,8 +164,8 @@ def _analyze_states(state: GlobalState) -> list: index = r.group(1) if index and solve(call): - description += ( - "block.blockhash() is calculated using a value from storage " + description = ( + "Block.blockhash() is calculated using a value from storage " "at index {}".format(index) ) issue = Issue( @@ -170,10 +174,10 @@ def _analyze_states(state: GlobalState) -> list: address=address, bytecode=call.state.environment.code.bytecode, title="Dependence on Predictable Variable", - severity="Medium", - description_head="", + severity="Low", + description_head="Sending of Ether depends on the blockhash.", description_tail=description, - swc_id=PREDICTABLE_VARS_DEPENDENCE, + swc_id=WEAK_RANDOMNESS, gas_used=( call.state.mstate.min_gas_used, call.state.mstate.max_gas_used, diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index 95f1d098..af31225e 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -78,7 +78,7 @@ def _analyze_state(state): title="External Call To Fixed Address", bytecode=state.environment.code.bytecode, severity="Low", - description_head=description_head , + description_head=description_head, description_tail=description_tail, debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), From 1831ff359932091a00b44ce583adde08c47da30a Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 27 Dec 2018 18:02:56 +0700 Subject: [PATCH 13/56] Complete refactor to head and tail --- mythril/analysis/modules/deprecated_ops.py | 14 ++++++----- mythril/analysis/modules/ether_thief.py | 2 +- mythril/analysis/modules/exceptions.py | 10 ++++---- mythril/analysis/modules/external_calls.py | 6 ++--- mythril/analysis/modules/integer.py | 23 ++++++++++------- mythril/analysis/modules/multiple_sends.py | 25 ++++++++++--------- mythril/analysis/modules/suicide.py | 11 +++++--- .../modules/transaction_order_dependence.py | 10 ++++---- mythril/analysis/modules/unchecked_retval.py | 13 +++++----- 9 files changed, 63 insertions(+), 51 deletions(-) diff --git a/mythril/analysis/modules/deprecated_ops.py b/mythril/analysis/modules/deprecated_ops.py index b3e24e47..05c77bc0 100644 --- a/mythril/analysis/modules/deprecated_ops.py +++ b/mythril/analysis/modules/deprecated_ops.py @@ -17,8 +17,9 @@ def _analyze_state(state): if instruction["opcode"] == "ORIGIN": log.debug("ORIGIN in function " + node.function_name) - title = "Use of tx.origin" - description = ( + title = "Use of tx.origin is deprecated." + description_head = "Use of tx.origin is deprecated." + description_tail = ( "The function `{}` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. " "Use msg.sender instead.\nSee also: " "https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin".format( @@ -30,8 +31,9 @@ def _analyze_state(state): elif instruction["opcode"] == "CALLCODE": log.debug("CALLCODE in function " + node.function_name) title = "Use of Callcode" - description = ( - "The function `{}` uses callcode. Callcode does not persist sender or value over the call. " + description_head = "Use of callcode is deprecated." + description_tail = ( + "The function `{}` uses the callcode function. Callcode does not persist sender or value over the call. " "Use delegatecall instead.".format(node.function_name) ) swc_id = DEPRICATED_FUNCTIONS_USAGE @@ -44,8 +46,8 @@ def _analyze_state(state): bytecode=state.environment.code.bytecode, swc_id=swc_id, severity="Medium", - description_head="", - description_tail=description, + description_head=description_head, + description_tail=description_tail, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) return [issue] diff --git a/mythril/analysis/modules/ether_thief.py b/mythril/analysis/modules/ether_thief.py index b9e5ea85..69a291c9 100644 --- a/mythril/analysis/modules/ether_thief.py +++ b/mythril/analysis/modules/ether_thief.py @@ -63,7 +63,7 @@ def _analyze_state(state): title="Unprotected Ether Withdrawal", severity="High", bytecode=state.environment.code.bytecode, - description_head="It appears that anyone can withdraw Ether from the contract account.", + description_head="Anyone can withdraw ETH from the contract account.", 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.", diff --git a/mythril/analysis/modules/exceptions.py b/mythril/analysis/modules/exceptions.py index 42488418..83e959cb 100644 --- a/mythril/analysis/modules/exceptions.py +++ b/mythril/analysis/modules/exceptions.py @@ -19,9 +19,9 @@ def _analyze_state(state) -> list: try: address = state.get_current_instruction()["address"] - description = ( - "A reachable exception (opcode 0xfe) has been detected. " - "This can be caused by type errors, division by zero, " + description_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." @@ -36,8 +36,8 @@ def _analyze_state(state) -> list: swc_id=ASSERT_VIOLATION, title="Exception State", severity="Low", - description_head="", - description_tail=description, + description_head="A reachable exception has been detected.", + description_tail=description_tail, bytecode=state.environment.code.bytecode, debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index af31225e..48c74816 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -39,8 +39,8 @@ def _analyze_state(state): transaction_sequence = solver.get_transaction_sequence(state, constraints) debug = str(transaction_sequence) - description_head = "The contract executes a function call to a user-supplied address." - description_tail = "An external function call is executed. The callee address can be set by " \ + 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 " \ "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." @@ -66,7 +66,7 @@ def _analyze_state(state): ) debug = str(transaction_sequence) - description_head = "The contract executes a function call to an external address." + description_head = "The contract executes an external message call." description_tail = "An external function call to a fixed contract address is executed. Note" \ "that the callee contract should be reviewed carefully." diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index e5d50bd8..a7f4cb62 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -128,25 +128,27 @@ class IntegerOverflowUnderflowModule(DetectionModule): if not isinstance(annotation, OverUnderflowAnnotation): continue - title = ( - "integer underflow" + _type = ( + "Underflow" if annotation.operator == "subtraction" - else "integer overflow" + else "Overflow" ) ostate = annotation.overflowing_state node = ostate.node + description_tail = "The binary {} operation can result in an integer {}.\n" \ + .format(annotation.operator, _type.lower()) + issue = Issue( contract=node.contract_name, function_name=node.function_name, address=ostate.get_current_instruction()["address"], swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, bytecode=ostate.environment.code.bytecode, - title="Integer Underflow", + title="Integer {}".format(_type), severity="High", - description_head= "The binary {} operation can result in an {}.\n".format( - annotation.operator, title.lower()), - description_tail="", + description_head= "The {} can {}." .format(annotation.operator, _type.lower()), + description_tail=description_tail, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) @@ -170,6 +172,9 @@ class IntegerOverflowUnderflowModule(DetectionModule): ostate = annotation.overflowing_state node = ostate.node + description_tail = "The binary {} operation can result in an integer overflow.\n" \ + .format(annotation.operator) + issue = Issue( contract=node.contract_name, function_name=node.function_name, @@ -178,8 +183,8 @@ class IntegerOverflowUnderflowModule(DetectionModule): bytecode=ostate.environment.code.bytecode, title="Integer Overflow", severity="High", - description_head="The binary {} operation can result in an integer overflow.\n".format(annotation.operator), - description_tail="", + description_head= "The {} can overflow.".format(annotation.operator), + description_tail=description_tail, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/mythril/analysis/modules/multiple_sends.py b/mythril/analysis/modules/multiple_sends.py index e20a2695..365a4ec1 100644 --- a/mythril/analysis/modules/multiple_sends.py +++ b/mythril/analysis/modules/multiple_sends.py @@ -72,11 +72,17 @@ def _analyze_state(state: GlobalState): else: # RETURN or STOP if len(calls) > 1: - description = ( - "Multiple sends are executed in a single transaction. " - "Try to isolate each external call into its own transaction," - " as external calls can fail accidentally or deliberately.\nConsecutive calls: \n" - ) + description_tail = "Consecutive calls are executed at the following bytecode offsets:\n" + + for call in calls: + description_tail += "Offset: {}\n".format( + call.state.get_current_instruction()["address"] + ) + + description_tail = ( + "Try to isolate each external call into its own transaction," + " as external calls can fail accidentally or deliberately.\n" + ) issue = Issue( contract=node.contract_name, @@ -86,16 +92,11 @@ def _analyze_state(state: GlobalState): bytecode=state.environment.code.bytecode, title="Multiple Calls in a Single Transaction", severity="Medium", - description_head="", - description_tail=description, + description_head="Multiple sends are executed in one transaction.", + description_tail=description_tail, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) - for call in calls: - issue.description += "Call at address: {}\n".format( - call.state.get_current_instruction()["address"] - ) - return [issue] return [] diff --git a/mythril/analysis/modules/suicide.py b/mythril/analysis/modules/suicide.py index 67de3e1a..ad32aeca 100644 --- a/mythril/analysis/modules/suicide.py +++ b/mythril/analysis/modules/suicide.py @@ -22,19 +22,22 @@ def _analyze_state(state): log.debug("[SUICIDE] SUICIDE in function " + node.function_name) + description_head = "The contract can be killed by anyone." + try: try: transaction_sequence = solver.get_transaction_sequence( state, node.constraints + [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF], ) - description_head = "Anyone can kill this contract and withdraw its balance to their own account." + description_tail = "Arbitrary senders can kill this contract and withdraw its balance to their own account." except UnsatError: transaction_sequence = solver.get_transaction_sequence( state, node.constraints ) - description_head = ( - "The contract can be killed by anyone. Don't accidentally kill it." + description_tail = ( + "Arbitrary senders can kill this contract but it is not possible to set the target address to which" + "the contract balance is sent." ) debug = str(transaction_sequence) @@ -48,7 +51,7 @@ def _analyze_state(state): title="Unprotected Selfdestruct", severity="High", description_head=description_head, - description_tail="", + description_tail=description_tail, debug=debug, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/mythril/analysis/modules/transaction_order_dependence.py b/mythril/analysis/modules/transaction_order_dependence.py index 781e6aca..83b9bc43 100644 --- a/mythril/analysis/modules/transaction_order_dependence.py +++ b/mythril/analysis/modules/transaction_order_dependence.py @@ -39,9 +39,9 @@ class TxOrderDependenceModule(DetectionModule): self._get_influencing_sstores(statespace, interesting_storages) ) - description = ( - "Possible transaction order dependence vulnerability: The value or " - "direction of the call statement is determined from a tainted storage location." + description_tail = ( + "A transaction order dependence vulnerability may exist in this contract. The value or " + "target of the call statement is loaded from a writable storage location." ) # Build issue if necessary @@ -56,8 +56,8 @@ class TxOrderDependenceModule(DetectionModule): bytecode=call.state.environment.code.bytecode, swc_id=TX_ORDER_DEPENDENCE, severity="Medium", - description_head="", - description_tail=description, + description_head="The call outcome may depend on transaction order.", + description_tail=description_tail, gas_used=( call.state.mstate.min_gas_used, call.state.mstate.max_gas_used, diff --git a/mythril/analysis/modules/unchecked_retval.py b/mythril/analysis/modules/unchecked_retval.py index 1abc21f9..c13d9da9 100644 --- a/mythril/analysis/modules/unchecked_retval.py +++ b/mythril/analysis/modules/unchecked_retval.py @@ -71,9 +71,10 @@ def _analyze_state(state: GlobalState) -> list: except UnsatError: continue - description = ( - "The return value of an external call is not checked. " - "Note that execution continue even if the called contract throws." + description_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." ) issue = Issue( @@ -81,11 +82,11 @@ def _analyze_state(state: GlobalState) -> list: function_name=node.function_name, address=retval["address"], bytecode=state.environment.code.bytecode, - title="Unchecked CALL Return Value", + title="Unchecked Call Return Value", swc_id=UNCHECKED_RET_VAL, severity="Low", - description_head="", - description_tail=description, + description_head="The return value of a message call is not checked.", + description_tail=description_tail, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) From a37e72745f6ef2dc032599b1c24a849d38560f14 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Thu, 27 Dec 2018 20:24:13 +0530 Subject: [PATCH 14/56] Display the source code and reformat files with black --- mythril/analysis/modules/delegatecall.py | 6 ++--- .../modules/dependence_on_predictable_vars.py | 18 +++++++-------- mythril/analysis/modules/external_calls.py | 12 ++++++---- mythril/analysis/modules/integer.py | 22 +++++++++---------- mythril/analysis/modules/multiple_sends.py | 4 +++- .../modules/transaction_order_dependence.py | 1 - mythril/analysis/modules/unchecked_retval.py | 2 +- mythril/analysis/report.py | 18 ++++++--------- 8 files changed, 42 insertions(+), 41 deletions(-) diff --git a/mythril/analysis/modules/delegatecall.py b/mythril/analysis/modules/delegatecall.py index b7c96e76..e59ff8a8 100644 --- a/mythril/analysis/modules/delegatecall.py +++ b/mythril/analysis/modules/delegatecall.py @@ -82,9 +82,9 @@ def _concrete_call( severity="Low", description_head="The contract implements a delegatecall proxy.", description_tail="The smart contract forwards the received calldata via delegatecall. Note that callers" - "can execute arbitrary functions in the callee contract and that the callee contract " - "can access the storage of the calling contract. " - "Make sure that the callee contract is audited properly.", + "can execute arbitrary functions in the callee contract and that the callee contract " + "can access the storage of the calling contract. " + "Make sure that the callee contract is audited properly.", gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/mythril/analysis/modules/dependence_on_predictable_vars.py b/mythril/analysis/modules/dependence_on_predictable_vars.py index 117c92b9..272fa447 100644 --- a/mythril/analysis/modules/dependence_on_predictable_vars.py +++ b/mythril/analysis/modules/dependence_on_predictable_vars.py @@ -55,7 +55,9 @@ def _analyze_states(state: GlobalState) -> list: address = call.state.get_current_instruction()["address"] - description = "The contract sends Ether depending on the values of the following variables:\n" + description = ( + "The contract sends Ether depending on the values of the following variables:\n" + ) # First check: look for predictable state variables in node & call recipient constraints @@ -71,15 +73,13 @@ def _analyze_states(state: GlobalState) -> list: for item in found: description += "- block.{}\n".format(item) if solve(call): - swc_id = ( - TIMESTAMP_DEPENDENCE - if item == "timestamp" - else WEAK_RANDOMNESS - ) + swc_id = TIMESTAMP_DEPENDENCE if item == "timestamp" else WEAK_RANDOMNESS - description += "Note that the values of variables like coinbase, gaslimit, block number and timestamp " \ - "are predictable and/or can be manipulated by a malicious miner. "\ - "Don't use them for random number generation or to make critical decisions." + description += ( + "Note that the values of variables like coinbase, gaslimit, block number and timestamp " + "are predictable and/or can be manipulated by a malicious miner. " + "Don't use them for random number generation or to make critical decisions." + ) issue = Issue( contract=call.node.contract_name, diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index 48c74816..246122ed 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -40,10 +40,12 @@ def _analyze_state(state): debug = str(transaction_sequence) 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 " \ - "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" \ + description_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." + ) issue = Issue( contract=node.contract_name, @@ -67,8 +69,10 @@ def _analyze_state(state): debug = str(transaction_sequence) description_head = "The contract executes an external message call." - description_tail = "An external function call to a fixed contract address is executed. Note" \ + description_tail = ( + "An external function call to a fixed contract address is executed. Note" "that the callee contract should be reviewed carefully." + ) issue = Issue( contract=node.contract_name, diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index a7f4cb62..a2b6cca2 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -128,16 +128,13 @@ class IntegerOverflowUnderflowModule(DetectionModule): if not isinstance(annotation, OverUnderflowAnnotation): continue - _type = ( - "Underflow" - if annotation.operator == "subtraction" - else "Overflow" - ) + _type = "Underflow" if annotation.operator == "subtraction" else "Overflow" ostate = annotation.overflowing_state node = ostate.node - description_tail = "The binary {} operation can result in an integer {}.\n" \ - .format(annotation.operator, _type.lower()) + description_tail = "The binary {} operation can result in an integer {}.\n".format( + annotation.operator, _type.lower() + ) issue = Issue( contract=node.contract_name, @@ -147,7 +144,9 @@ class IntegerOverflowUnderflowModule(DetectionModule): bytecode=ostate.environment.code.bytecode, title="Integer {}".format(_type), severity="High", - description_head= "The {} can {}." .format(annotation.operator, _type.lower()), + description_head="The {} can {}.".format( + annotation.operator, _type.lower() + ), description_tail=description_tail, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) @@ -172,8 +171,9 @@ class IntegerOverflowUnderflowModule(DetectionModule): ostate = annotation.overflowing_state node = ostate.node - description_tail = "The binary {} operation can result in an integer overflow.\n" \ - .format(annotation.operator) + description_tail = "The binary {} operation can result in an integer overflow.\n".format( + annotation.operator + ) issue = Issue( contract=node.contract_name, @@ -183,7 +183,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): bytecode=ostate.environment.code.bytecode, title="Integer Overflow", severity="High", - description_head= "The {} can overflow.".format(annotation.operator), + description_head="The {} can overflow.".format(annotation.operator), description_tail=description_tail, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/mythril/analysis/modules/multiple_sends.py b/mythril/analysis/modules/multiple_sends.py index 365a4ec1..6ea8d529 100644 --- a/mythril/analysis/modules/multiple_sends.py +++ b/mythril/analysis/modules/multiple_sends.py @@ -72,7 +72,9 @@ def _analyze_state(state: GlobalState): else: # RETURN or STOP if len(calls) > 1: - description_tail = "Consecutive calls are executed at the following bytecode offsets:\n" + description_tail = ( + "Consecutive calls are executed at the following bytecode offsets:\n" + ) for call in calls: description_tail += "Offset: {}\n".format( diff --git a/mythril/analysis/modules/transaction_order_dependence.py b/mythril/analysis/modules/transaction_order_dependence.py index 83b9bc43..f11936c4 100644 --- a/mythril/analysis/modules/transaction_order_dependence.py +++ b/mythril/analysis/modules/transaction_order_dependence.py @@ -64,7 +64,6 @@ class TxOrderDependenceModule(DetectionModule): ), ) - issues.append(issue) return issues diff --git a/mythril/analysis/modules/unchecked_retval.py b/mythril/analysis/modules/unchecked_retval.py index c13d9da9..72b1dc3e 100644 --- a/mythril/analysis/modules/unchecked_retval.py +++ b/mythril/analysis/modules/unchecked_retval.py @@ -67,7 +67,7 @@ def _analyze_state(state: GlobalState) -> list: issues = [] for retval in retvals: try: - solver.get_model(node.constraints + [retval["retval"] == 0]) + solver.get_model(node.constraints + [retval["retval"] == 0]) except UnsatError: continue diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 9ee8f1c1..194d2ab2 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -33,8 +33,8 @@ class Issue: self.contract = contract self.function = function_name self.address = address - self.description_head = description_head, - self.description_tail = description_tail, + self.description_head = (description_head,) + self.description_tail = (description_tail,) self.description = "%s %s" % (description_head, description_tail) self.severity = severity self.debug = debug @@ -82,7 +82,7 @@ class Issue: return issue def add_code_info(self, contract): - if self.address and isinstance(self.contract, SolidityContract): + if self.address and isinstance(contract, SolidityContract): codeinfo = contract.get_source_info( self.address, constructor=(self.function == "constructor") ) @@ -167,15 +167,11 @@ class Report: "swcTitle": title, "description": { "head": issue.description_head, - "tail": issue.description_tail + "tail": issue.description_tail, }, "severity": issue.severity, - "locations": [ - { - "sourceMap": "%d:1:%d" % (issue.address, idx) - }, - ], - "extra": {} + "locations": [{"sourceMap": "%d:1:%d" % (issue.address, idx)}], + "extra": {}, } ) @@ -184,7 +180,7 @@ class Report: "sourceType": "raw-bytecode", "sourceFormat": "evm-byzantium-bytecode", "sourceList": sourceList, - "meta": {} + "meta": {}, } return json.dumps(result, sort_keys=True) From 8f04960d4ea41338698f5d40e6a68ab897df5d18 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Fri, 28 Dec 2018 13:41:59 +0700 Subject: [PATCH 15/56] Improve text report formatting --- mythril/analysis/report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 194d2ab2..3af57363 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -35,7 +35,7 @@ class Issue: self.address = address self.description_head = (description_head,) self.description_tail = (description_tail,) - self.description = "%s %s" % (description_head, description_tail) + self.description = "%s\n%s" % (description_head, description_tail) self.severity = severity self.debug = debug self.swc_id = swc_id From 0299e12cceda44f3da4800aaba1692668d20a9d0 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Fri, 28 Dec 2018 13:42:43 +0700 Subject: [PATCH 16/56] Fix typo --- mythril/analysis/modules/external_calls.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index 246122ed..351421c3 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -70,8 +70,8 @@ def _analyze_state(state): debug = str(transaction_sequence) description_head = "The contract executes an external message call." description_tail = ( - "An external function call to a fixed contract address is executed. Note" - "that the callee contract should be reviewed carefully." + "An external function call to a fixed contract address is executed. Make sure " + "that the callee contract has been reviewed carefully." ) issue = Issue( From a488f0645745ec89be042709c30cb3851181cbac Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Fri, 28 Dec 2018 14:00:31 +0700 Subject: [PATCH 17/56] Update tests --- tests/cmd_line_test.py | 2 +- .../outputs_expected/calls.sol.o.json | 103 +----------------- .../outputs_expected/calls.sol.o.markdown | 56 ++++++---- .../outputs_expected/calls.sol.o.text | 56 ++++++---- .../outputs_expected/ether_send.sol.o.json | 6 +- .../outputs_expected/exceptions.sol.o.json | 55 +--------- .../exceptions.sol.o.markdown | 28 +++-- .../outputs_expected/exceptions.sol.o.text | 28 +++-- .../kinds_of_calls.sol.o.json | 67 +----------- .../kinds_of_calls.sol.o.markdown | 35 +++--- .../kinds_of_calls.sol.o.text | 35 +++--- .../outputs_expected/metacoin.sol.o.json | 6 +- .../multi_contracts.sol.o.json | 19 +--- .../multi_contracts.sol.o.markdown | 5 +- .../multi_contracts.sol.o.text | 5 +- .../outputs_expected/nonascii.sol.o.json | 6 +- .../outputs_expected/origin.sol.o.json | 19 +--- .../outputs_expected/origin.sol.o.markdown | 5 +- .../outputs_expected/origin.sol.o.text | 5 +- .../outputs_expected/overflow.sol.o.json | 43 +------- .../outputs_expected/overflow.sol.o.markdown | 15 ++- .../outputs_expected/overflow.sol.o.text | 15 ++- .../outputs_expected/returnvalue.sol.o.json | 43 +------- .../returnvalue.sol.o.markdown | 21 ++-- .../outputs_expected/returnvalue.sol.o.text | 21 ++-- .../outputs_expected/suicide.sol.o.json | 19 +--- .../outputs_expected/suicide.sol.o.markdown | 7 +- .../outputs_expected/suicide.sol.o.text | 7 +- .../outputs_expected/underflow.sol.o.json | 43 +------- .../outputs_expected/underflow.sol.o.markdown | 15 ++- .../outputs_expected/underflow.sol.o.text | 15 ++- 31 files changed, 229 insertions(+), 576 deletions(-) diff --git a/tests/cmd_line_test.py b/tests/cmd_line_test.py index 26545eac..ae8e4f7c 100644 --- a/tests/cmd_line_test.py +++ b/tests/cmd_line_test.py @@ -29,7 +29,7 @@ class TruffleTestCase(BaseTestCase): command = "cd {}; truffle compile; python3 {} --truffle -t 2".format( truffle_project_root, MYTH ) - self.assertIn("=== Ether thief ====", output_of(command)) + self.assertIn("=== Unprotected Ether Withdrawal ====", output_of(command)) class InfuraTestCase(BaseTestCase): diff --git a/tests/testdata/outputs_expected/calls.sol.o.json b/tests/testdata/outputs_expected/calls.sol.o.json index 404801ff..68317bed 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.json +++ b/tests/testdata/outputs_expected/calls.sol.o.json @@ -1,102 +1 @@ -{ - "error": null, - "issues": [ - { - "address": 661, - "contract": "Unknown", - "debug": "", - "description": "The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable.", - "function": "thisisfine()", - "max_gas_used": 1254, - "min_gas_used": 643, - "swc-id": "107", - "title": "External call", - "type": "Informational" - }, - { - "address": 661, - "contract": "Unknown", - "debug": "", - "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", - "function": "thisisfine()", - "max_gas_used": 35972, - "min_gas_used": 1361, - "swc-id": "104", - "title": "Unchecked CALL return value", - "type": "Informational" - }, - { - "address": 779, - "contract": "Unknown", - "debug": "", - "description": "The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable.", - "function": "callstoredaddress()", - "max_gas_used": 1298, - "min_gas_used": 687, - "swc-id": "107", - "title": "External call", - "type": "Informational" - }, - { - "address": 779, - "contract": "Unknown", - "debug": "", - "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", - "function": "callstoredaddress()", - "max_gas_used": 36016, - "min_gas_used": 1405, - "swc-id": "104", - "title": "Unchecked CALL return value", - "type": "Informational" - }, - { - "address": 858, - "contract": "Unknown", - "debug": "", - "description": "The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable.", - "function": "reentrancy()", - "max_gas_used": 1320, - "min_gas_used": 709, - "swc-id": "107", - "title": "External call", - "type": "Informational" - }, - { - "address": 858, - "contract": "Unknown", - "debug": "", - "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", - "function": "reentrancy()", - "max_gas_used": 61052, - "min_gas_used": 6441, - "swc-id": "104", - "title": "Unchecked CALL return value", - "type": "Informational" - }, - { - "address": 912, - "contract": "Unknown", - "debug": "", - "description": "The contract executes a function call with high gas to a user-supplied address. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent unanticipated effects on the contract state.", - "function": "calluseraddress(address)", - "max_gas_used": 616, - "min_gas_used": 335, - "swc-id": "107", - "title": "External call to user-supplied address", - "type": "Warning" - }, - { - "address": 912, - "contract": "Unknown", - "debug": "", - "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", - "function": "calluseraddress(address)", - "max_gas_used": 35336, - "min_gas_used": 1055, - "swc-id": "104", - "title": "Unchecked CALL return value", - "type": "Informational" - } - ], - "success": true -} +{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/calls.sol.o.markdown b/tests/testdata/outputs_expected/calls.sol.o.markdown index 34e48962..2edd13d7 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.markdown +++ b/tests/testdata/outputs_expected/calls.sol.o.markdown @@ -1,8 +1,8 @@ # Analysis results for test-filename.sol -## External call +## External Call To Fixed Address - SWC ID: 107 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `thisisfine()` - PC address: 661 @@ -10,11 +10,12 @@ ### Description -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -## Unchecked CALL return value +## Unchecked Call Return Value - SWC ID: 104 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `thisisfine()` - PC address: 661 @@ -22,11 +23,12 @@ The contract executes a function call to an external address. Verify that the co ### Description -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -## External call +## External Call To Fixed Address - SWC ID: 107 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `callstoredaddress()` - PC address: 779 @@ -34,11 +36,12 @@ The return value of an external call is not checked. Note that execution continu ### Description -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -## Unchecked CALL return value +## Unchecked Call Return Value - SWC ID: 104 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `callstoredaddress()` - PC address: 779 @@ -46,11 +49,12 @@ The contract executes a function call to an external address. Verify that the co ### Description -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -## External call +## External Call To Fixed Address - SWC ID: 107 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `reentrancy()` - PC address: 858 @@ -58,11 +62,12 @@ The return value of an external call is not checked. Note that execution continu ### Description -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -## Unchecked CALL return value +## Unchecked Call Return Value - SWC ID: 104 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `reentrancy()` - PC address: 858 @@ -70,11 +75,12 @@ The contract executes a function call to an external address. Verify that the co ### Description -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -## External call to user-supplied address +## External Call To User-Supplied Address - SWC ID: 107 -- Type: Warning +- Severity: Medium - Contract: Unknown - Function name: `calluseraddress(address)` - PC address: 912 @@ -82,11 +88,12 @@ The return value of an external call is not checked. Note that execution continu ### Description -The contract executes a function call with high gas to a user-supplied address. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent unanticipated effects on the contract state. +A call to a user-supplied address is executed. +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 thecontract state. -## Unchecked CALL return value +## Unchecked Call Return Value - SWC ID: 104 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `calluseraddress(address)` - PC address: 912 @@ -94,4 +101,5 @@ The contract executes a function call with high gas to a user-supplied address. ### Description -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. diff --git a/tests/testdata/outputs_expected/calls.sol.o.text b/tests/testdata/outputs_expected/calls.sol.o.text index 69dc3d29..9e53ca4e 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.text +++ b/tests/testdata/outputs_expected/calls.sol.o.text @@ -1,80 +1,88 @@ -==== External call ==== +==== External Call To Fixed Address ==== SWC ID: 107 -Type: Informational +Severity: Low Contract: Unknown Function name: thisisfine() PC address: 661 Estimated Gas Usage: 643 - 1254 -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -------------------- -==== Unchecked CALL return value ==== +==== Unchecked Call Return Value ==== SWC ID: 104 -Type: Informational +Severity: Low Contract: Unknown Function name: thisisfine() PC address: 661 Estimated Gas Usage: 1361 - 35972 -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -------------------- -==== External call ==== +==== External Call To Fixed Address ==== SWC ID: 107 -Type: Informational +Severity: Low Contract: Unknown Function name: callstoredaddress() PC address: 779 Estimated Gas Usage: 687 - 1298 -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -------------------- -==== Unchecked CALL return value ==== +==== Unchecked Call Return Value ==== SWC ID: 104 -Type: Informational +Severity: Low Contract: Unknown Function name: callstoredaddress() PC address: 779 Estimated Gas Usage: 1405 - 36016 -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -------------------- -==== External call ==== +==== External Call To Fixed Address ==== SWC ID: 107 -Type: Informational +Severity: Low Contract: Unknown Function name: reentrancy() PC address: 858 Estimated Gas Usage: 709 - 1320 -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -------------------- -==== Unchecked CALL return value ==== +==== Unchecked Call Return Value ==== SWC ID: 104 -Type: Informational +Severity: Low Contract: Unknown Function name: reentrancy() PC address: 858 Estimated Gas Usage: 6441 - 61052 -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -------------------- -==== External call to user-supplied address ==== +==== External Call To User-Supplied Address ==== SWC ID: 107 -Type: Warning +Severity: Medium Contract: Unknown Function name: calluseraddress(address) PC address: 912 Estimated Gas Usage: 335 - 616 -The contract executes a function call with high gas to a user-supplied address. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent unanticipated effects on the contract state. +A call to a user-supplied address is executed. +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 thecontract state. -------------------- -==== Unchecked CALL return value ==== +==== Unchecked Call Return Value ==== SWC ID: 104 -Type: Informational +Severity: Low Contract: Unknown Function name: calluseraddress(address) PC address: 912 Estimated Gas Usage: 1055 - 35336 -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -------------------- diff --git a/tests/testdata/outputs_expected/ether_send.sol.o.json b/tests/testdata/outputs_expected/ether_send.sol.o.json index 179ed787..87eb5313 100644 --- a/tests/testdata/outputs_expected/ether_send.sol.o.json +++ b/tests/testdata/outputs_expected/ether_send.sol.o.json @@ -1,5 +1 @@ -{ - "error": null, - "issues": [], - "success": true -} +{"issues": [], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.json b/tests/testdata/outputs_expected/exceptions.sol.o.json index c0324b17..dc634a5a 100644 --- a/tests/testdata/outputs_expected/exceptions.sol.o.json +++ b/tests/testdata/outputs_expected/exceptions.sol.o.json @@ -1,54 +1 @@ -{ - "error": null, - "issues": [ - { - "address": 446, - "contract": "Unknown", - "debug": "", - "description": "A reachable exception (opcode 0xfe) has been detected. This 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, - "min_gas_used": 206, - "swc-id": "110", - "title": "Exception state", - "type": "Informational" - }, - { - "address": 484, - "contract": "Unknown", - "debug": "", - "description": "A reachable exception (opcode 0xfe) has been detected. This 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, - "min_gas_used": 256, - "swc-id": "110", - "title": "Exception state", - "type": "Informational" - }, - { - "address": 506, - "contract": "Unknown", - "debug": "", - "description": "A reachable exception (opcode 0xfe) has been detected. This 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, - "min_gas_used": 272, - "swc-id": "110", - "title": "Exception state", - "type": "Informational" - }, - { - "address": 531, - "contract": "Unknown", - "debug": "", - "description": "A reachable exception (opcode 0xfe) has been detected. This 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, - "min_gas_used": 268, - "swc-id": "110", - "title": "Exception state", - "type": "Informational" - } - ], - "success": true -} +{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-110", "swcTitle": "Assert Violation"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.markdown b/tests/testdata/outputs_expected/exceptions.sol.o.markdown index 64d4ed2b..c5da9834 100644 --- a/tests/testdata/outputs_expected/exceptions.sol.o.markdown +++ b/tests/testdata/outputs_expected/exceptions.sol.o.markdown @@ -1,8 +1,8 @@ # Analysis results for test-filename.sol -## Exception state +## Exception State - SWC ID: 110 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `assert3(uint256)` - PC address: 446 @@ -10,11 +10,12 @@ ### Description -A reachable exception (opcode 0xfe) has been detected. This 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. +A reachable exception has been detected. +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. -## Exception state +## Exception State - SWC ID: 110 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `arrayaccess(uint256)` - PC address: 484 @@ -22,11 +23,12 @@ A reachable exception (opcode 0xfe) has been detected. This can be caused by typ ### Description -A reachable exception (opcode 0xfe) has been detected. This 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. +A reachable exception has been detected. +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. -## Exception state +## Exception State - SWC ID: 110 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `divisionby0(uint256)` - PC address: 506 @@ -34,11 +36,12 @@ A reachable exception (opcode 0xfe) has been detected. This can be caused by typ ### Description -A reachable exception (opcode 0xfe) has been detected. This 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. +A reachable exception has been detected. +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. -## Exception state +## Exception State - SWC ID: 110 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `assert1()` - PC address: 531 @@ -46,4 +49,5 @@ A reachable exception (opcode 0xfe) has been detected. This can be caused by typ ### Description -A reachable exception (opcode 0xfe) has been detected. This 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. +A reachable exception has been detected. +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. diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.text b/tests/testdata/outputs_expected/exceptions.sol.o.text index 6eaa9c6f..cfee4d39 100644 --- a/tests/testdata/outputs_expected/exceptions.sol.o.text +++ b/tests/testdata/outputs_expected/exceptions.sol.o.text @@ -1,40 +1,44 @@ -==== Exception state ==== +==== Exception State ==== SWC ID: 110 -Type: Informational +Severity: Low Contract: Unknown Function name: assert3(uint256) PC address: 446 Estimated Gas Usage: 206 - 301 -A reachable exception (opcode 0xfe) has been detected. This 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. +A reachable exception has been detected. +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. -------------------- -==== Exception state ==== +==== Exception State ==== SWC ID: 110 -Type: Informational +Severity: Low Contract: Unknown Function name: arrayaccess(uint256) PC address: 484 Estimated Gas Usage: 256 - 351 -A reachable exception (opcode 0xfe) has been detected. This 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. +A reachable exception has been detected. +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. -------------------- -==== Exception state ==== +==== Exception State ==== SWC ID: 110 -Type: Informational +Severity: Low Contract: Unknown Function name: divisionby0(uint256) PC address: 506 Estimated Gas Usage: 272 - 367 -A reachable exception (opcode 0xfe) has been detected. This 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. +A reachable exception has been detected. +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. -------------------- -==== Exception state ==== +==== Exception State ==== SWC ID: 110 -Type: Informational +Severity: Low Contract: Unknown Function name: assert1() PC address: 531 Estimated Gas Usage: 268 - 363 -A reachable exception (opcode 0xfe) has been detected. This 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. +A reachable exception has been detected. +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. -------------------- diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json index 26366268..67536da1 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json @@ -1,66 +1 @@ -{ - "error": null, - "issues": [ - { - "address": 618, - "contract": "Unknown", - "debug": "", - "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", - "function": "_function_0x141f32ff", - "max_gas_used": 35865, - "min_gas_used": 1113, - "swc-id": "104", - "title": "Unchecked CALL return value", - "type": "Informational" - }, - { - "address": 618, - "contract": "Unknown", - "debug": "", - "description": "The function `_function_0x141f32ff` uses callcode. Callcode does not persist sender or value over the call. Use delegatecall instead.", - "function": "_function_0x141f32ff", - "max_gas_used": 1141, - "min_gas_used": 389, - "swc-id": "111", - "title": "Use of callcode", - "type": "Warning" - }, - { - "address": 849, - "contract": "Unknown", - "debug": "", - "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", - "function": "_function_0x9b58bc26", - "max_gas_used": 35922, - "min_gas_used": 1170, - "swc-id": "104", - "title": "Unchecked CALL return value", - "type": "Informational" - }, - { - "address": 1038, - "contract": "Unknown", - "debug": "", - "description": "The contract executes a function call with high gas to a user-supplied address. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent unanticipated effects on the contract state.", - "function": "_function_0xeea4c864", - "max_gas_used": 1223, - "min_gas_used": 471, - "swc-id": "107", - "title": "External call to user-supplied address", - "type": "Warning" - }, - { - "address": 1038, - "contract": "Unknown", - "debug": "", - "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", - "function": "_function_0xeea4c864", - "max_gas_used": 35947, - "min_gas_used": 1195, - "swc-id": "104", - "title": "Unchecked CALL return value", - "type": "Informational" - } - ], - "success": true -} +{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown index 2b16432e..bf30348e 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown @@ -1,8 +1,8 @@ # Analysis results for test-filename.sol -## Unchecked CALL return value +## Unchecked Call Return Value - SWC ID: 104 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `_function_0x141f32ff` - PC address: 618 @@ -10,11 +10,12 @@ ### Description -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -## Use of callcode +## Use of Callcode - SWC ID: 111 -- Type: Warning +- Severity: Medium - Contract: Unknown - Function name: `_function_0x141f32ff` - PC address: 618 @@ -22,11 +23,12 @@ The return value of an external call is not checked. Note that execution continu ### Description -The function `_function_0x141f32ff` uses callcode. Callcode does not persist sender or value over the call. Use delegatecall instead. +Use of callcode is deprecated. +The function `_function_0x141f32ff` uses the callcode function. Callcode does not persist sender or value over the call. Use delegatecall instead. -## Unchecked CALL return value +## Unchecked Call Return Value - SWC ID: 104 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `_function_0x9b58bc26` - PC address: 849 @@ -34,11 +36,12 @@ The function `_function_0x141f32ff` uses callcode. Callcode does not persist sen ### Description -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -## External call to user-supplied address +## External Call To User-Supplied Address - SWC ID: 107 -- Type: Warning +- Severity: Medium - Contract: Unknown - Function name: `_function_0xeea4c864` - PC address: 1038 @@ -46,11 +49,12 @@ The return value of an external call is not checked. Note that execution continu ### Description -The contract executes a function call with high gas to a user-supplied address. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent unanticipated effects on the contract state. +A call to a user-supplied address is executed. +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 thecontract state. -## Unchecked CALL return value +## Unchecked Call Return Value - SWC ID: 104 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `_function_0xeea4c864` - PC address: 1038 @@ -58,4 +62,5 @@ The contract executes a function call with high gas to a user-supplied address. ### Description -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text index b4bba9ca..19e00cf9 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text @@ -1,50 +1,55 @@ -==== Unchecked CALL return value ==== +==== Unchecked Call Return Value ==== SWC ID: 104 -Type: Informational +Severity: Low Contract: Unknown Function name: _function_0x141f32ff PC address: 618 Estimated Gas Usage: 1113 - 35865 -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -------------------- -==== Use of callcode ==== +==== Use of Callcode ==== SWC ID: 111 -Type: Warning +Severity: Medium Contract: Unknown Function name: _function_0x141f32ff PC address: 618 Estimated Gas Usage: 389 - 1141 -The function `_function_0x141f32ff` uses callcode. Callcode does not persist sender or value over the call. Use delegatecall instead. +Use of callcode is deprecated. +The function `_function_0x141f32ff` uses the callcode function. Callcode does not persist sender or value over the call. Use delegatecall instead. -------------------- -==== Unchecked CALL return value ==== +==== Unchecked Call Return Value ==== SWC ID: 104 -Type: Informational +Severity: Low Contract: Unknown Function name: _function_0x9b58bc26 PC address: 849 Estimated Gas Usage: 1170 - 35922 -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -------------------- -==== External call to user-supplied address ==== +==== External Call To User-Supplied Address ==== SWC ID: 107 -Type: Warning +Severity: Medium Contract: Unknown Function name: _function_0xeea4c864 PC address: 1038 Estimated Gas Usage: 471 - 1223 -The contract executes a function call with high gas to a user-supplied address. Note that the callee can contain arbitrary code and may re-enter any function in this contract. Review the business logic carefully to prevent unanticipated effects on the contract state. +A call to a user-supplied address is executed. +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 thecontract state. -------------------- -==== Unchecked CALL return value ==== +==== Unchecked Call Return Value ==== SWC ID: 104 -Type: Informational +Severity: Low Contract: Unknown Function name: _function_0xeea4c864 PC address: 1038 Estimated Gas Usage: 1195 - 35947 -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -------------------- diff --git a/tests/testdata/outputs_expected/metacoin.sol.o.json b/tests/testdata/outputs_expected/metacoin.sol.o.json index 179ed787..87eb5313 100644 --- a/tests/testdata/outputs_expected/metacoin.sol.o.json +++ b/tests/testdata/outputs_expected/metacoin.sol.o.json @@ -1,5 +1 @@ -{ - "error": null, - "issues": [], - "success": true -} +{"issues": [], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.json b/tests/testdata/outputs_expected/multi_contracts.sol.o.json index c4d6e54c..95705ffc 100644 --- a/tests/testdata/outputs_expected/multi_contracts.sol.o.json +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.json @@ -1,18 +1 @@ -{ - "error": null, - "issues": [ - { - "address": 142, - "contract": "Unknown", - "debug": "", - "description": "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.", - "function": "transfer()", - "max_gas_used": 467, - "min_gas_used": 186, - "swc-id": "105", - "title": "Ether thief", - "type": "Warning" - } - ], - "success": true -} +{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-105", "swcTitle": "Unprotected Ether Withdrawal"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.markdown b/tests/testdata/outputs_expected/multi_contracts.sol.o.markdown index fdec9b80..a7eac008 100644 --- a/tests/testdata/outputs_expected/multi_contracts.sol.o.markdown +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.markdown @@ -1,8 +1,8 @@ # Analysis results for test-filename.sol -## Ether thief +## Unprotected Ether Withdrawal - SWC ID: 105 -- Type: Warning +- Severity: High - Contract: Unknown - Function name: `transfer()` - PC address: 142 @@ -10,4 +10,5 @@ ### Description +Anyone can withdraw ETH from the contract account. 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. diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.text b/tests/testdata/outputs_expected/multi_contracts.sol.o.text index b229eda4..a8388020 100644 --- a/tests/testdata/outputs_expected/multi_contracts.sol.o.text +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.text @@ -1,10 +1,11 @@ -==== Ether thief ==== +==== Unprotected Ether Withdrawal ==== SWC ID: 105 -Type: Warning +Severity: High Contract: Unknown Function name: transfer() PC address: 142 Estimated Gas Usage: 186 - 467 +Anyone can withdraw ETH from the contract account. 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. -------------------- diff --git a/tests/testdata/outputs_expected/nonascii.sol.o.json b/tests/testdata/outputs_expected/nonascii.sol.o.json index 179ed787..87eb5313 100644 --- a/tests/testdata/outputs_expected/nonascii.sol.o.json +++ b/tests/testdata/outputs_expected/nonascii.sol.o.json @@ -1,5 +1 @@ -{ - "error": null, - "issues": [], - "success": true -} +{"issues": [], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.json b/tests/testdata/outputs_expected/origin.sol.o.json index 11a5212c..2f2eec19 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.json +++ b/tests/testdata/outputs_expected/origin.sol.o.json @@ -1,18 +1 @@ -{ - "error": null, - "issues": [ - { - "address": 317, - "contract": "Unknown", - "debug": "", - "description": "The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead.\nSee also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin", - "function": "transferOwnership(address)", - "max_gas_used": 1051, - "min_gas_used": 626, - "swc-id": "111", - "title": "Use of tx.origin", - "type": "Warning" - } - ], - "success": true -} +{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.markdown b/tests/testdata/outputs_expected/origin.sol.o.markdown index 1e0ad30c..e9603d8c 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.markdown +++ b/tests/testdata/outputs_expected/origin.sol.o.markdown @@ -1,8 +1,8 @@ # Analysis results for test-filename.sol -## Use of tx.origin +## Use of tx.origin is deprecated. - SWC ID: 111 -- Type: Warning +- Severity: Medium - Contract: Unknown - Function name: `transferOwnership(address)` - PC address: 317 @@ -10,5 +10,6 @@ ### Description +Use of tx.origin is deprecated. The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead. See also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin diff --git a/tests/testdata/outputs_expected/origin.sol.o.text b/tests/testdata/outputs_expected/origin.sol.o.text index acf08a93..2b96e50f 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.text +++ b/tests/testdata/outputs_expected/origin.sol.o.text @@ -1,10 +1,11 @@ -==== Use of tx.origin ==== +==== Use of tx.origin is deprecated. ==== SWC ID: 111 -Type: Warning +Severity: Medium Contract: Unknown Function name: transferOwnership(address) PC address: 317 Estimated Gas Usage: 626 - 1051 +Use of tx.origin is deprecated. The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead. See also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin -------------------- diff --git a/tests/testdata/outputs_expected/overflow.sol.o.json b/tests/testdata/outputs_expected/overflow.sol.o.json index aefffb2b..6e2c9a2c 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.json +++ b/tests/testdata/outputs_expected/overflow.sol.o.json @@ -1,42 +1 @@ -{ - "error":null, - "issues":[ - { - "address":567, - "contract":"Unknown", - "debug":"", - "description":"This binary subtraction operation can result in integer overflow.\n", - "function":"sendeth(address,uint256)", - "max_gas_used":1053, - "min_gas_used":768, - "swc-id":"101", - "title":"Integer Overflow", - "type":"Warning" - }, - { - "address":567, - "contract":"Unknown", - "debug":"", - "description":"This binary subtraction operation can result in integer underflow.\n", - "function":"sendeth(address,uint256)", - "max_gas_used":1774, - "min_gas_used":1299, - "swc-id":"101", - "title":"Integer Underflow", - "type":"Warning" - }, - { - "address":649, - "contract":"Unknown", - "debug":"", - "description":"This binary subtraction operation can result in integer underflow.\n", - "function":"sendeth(address,uint256)", - "max_gas_used":1774, - "min_gas_used":1299, - "swc-id":"101", - "title":"Integer Underflow", - "type":"Warning" - } - ], - "success":true -} +{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/overflow.sol.o.markdown b/tests/testdata/outputs_expected/overflow.sol.o.markdown index ce87c901..63c84af1 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.markdown +++ b/tests/testdata/outputs_expected/overflow.sol.o.markdown @@ -2,7 +2,7 @@ ## Integer Overflow - SWC ID: 101 -- Type: Warning +- Severity: High - Contract: Unknown - Function name: `sendeth(address,uint256)` - PC address: 567 @@ -10,11 +10,12 @@ ### Description -This binary subtraction operation can result in integer overflow. +The subtraction can overflow. +The binary subtraction operation can result in an integer overflow. ## Integer Underflow - SWC ID: 101 -- Type: Warning +- Severity: High - Contract: Unknown - Function name: `sendeth(address,uint256)` - PC address: 567 @@ -22,11 +23,12 @@ This binary subtraction operation can result in integer overflow. ### Description -This binary subtraction operation can result in integer underflow. +The subtraction can underflow. +The binary subtraction operation can result in an integer underflow. ## Integer Underflow - SWC ID: 101 -- Type: Warning +- Severity: High - Contract: Unknown - Function name: `sendeth(address,uint256)` - PC address: 649 @@ -34,4 +36,5 @@ This binary subtraction operation can result in integer underflow. ### Description -This binary subtraction operation can result in integer underflow. +The subtraction can underflow. +The binary subtraction operation can result in an integer underflow. diff --git a/tests/testdata/outputs_expected/overflow.sol.o.text b/tests/testdata/outputs_expected/overflow.sol.o.text index fdea1818..72467aeb 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.text +++ b/tests/testdata/outputs_expected/overflow.sol.o.text @@ -1,33 +1,36 @@ ==== Integer Overflow ==== SWC ID: 101 -Type: Warning +Severity: High Contract: Unknown Function name: sendeth(address,uint256) PC address: 567 Estimated Gas Usage: 768 - 1053 -This binary subtraction operation can result in integer overflow. +The subtraction can overflow. +The binary subtraction operation can result in an integer overflow. -------------------- ==== Integer Underflow ==== SWC ID: 101 -Type: Warning +Severity: High Contract: Unknown Function name: sendeth(address,uint256) PC address: 567 Estimated Gas Usage: 1299 - 1774 -This binary subtraction operation can result in integer underflow. +The subtraction can underflow. +The binary subtraction operation can result in an integer underflow. -------------------- ==== Integer Underflow ==== SWC ID: 101 -Type: Warning +Severity: High Contract: Unknown Function name: sendeth(address,uint256) PC address: 649 Estimated Gas Usage: 1299 - 1774 -This binary subtraction operation can result in integer underflow. +The subtraction can underflow. +The binary subtraction operation can result in an integer underflow. -------------------- diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.json b/tests/testdata/outputs_expected/returnvalue.sol.o.json index 17d61c3f..ab1f619c 100644 --- a/tests/testdata/outputs_expected/returnvalue.sol.o.json +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.json @@ -1,42 +1 @@ -{ - "error": null, - "issues": [ - { - "address": 196, - "contract": "Unknown", - "debug": "", - "description": "The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable.", - "function": "callchecked()", - "max_gas_used": 1210, - "min_gas_used": 599, - "swc-id": "107", - "title": "External call", - "type": "Informational" - }, - { - "address": 285, - "contract": "Unknown", - "debug": "", - "description": "The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable.", - "function": "callnotchecked()", - "max_gas_used": 1232, - "min_gas_used": 621, - "swc-id": "107", - "title": "External call", - "type": "Informational" - }, - { - "address": 285, - "contract": "Unknown", - "debug": "", - "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", - "function": "callnotchecked()", - "max_gas_used": 35950, - "min_gas_used": 1339, - "swc-id": "104", - "title": "Unchecked CALL return value", - "type": "Informational" - } - ], - "success": true -} +{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.markdown b/tests/testdata/outputs_expected/returnvalue.sol.o.markdown index 6b34840f..fcbd0a1b 100644 --- a/tests/testdata/outputs_expected/returnvalue.sol.o.markdown +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.markdown @@ -1,8 +1,8 @@ # Analysis results for test-filename.sol -## External call +## External Call To Fixed Address - SWC ID: 107 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `callchecked()` - PC address: 196 @@ -10,11 +10,12 @@ ### Description -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -## External call +## External Call To Fixed Address - SWC ID: 107 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `callnotchecked()` - PC address: 285 @@ -22,11 +23,12 @@ The contract executes a function call to an external address. Verify that the co ### Description -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -## Unchecked CALL return value +## Unchecked Call Return Value - SWC ID: 104 -- Type: Informational +- Severity: Low - Contract: Unknown - Function name: `callnotchecked()` - PC address: 285 @@ -34,4 +36,5 @@ The contract executes a function call to an external address. Verify that the co ### Description -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.text b/tests/testdata/outputs_expected/returnvalue.sol.o.text index 320b0420..2678bf80 100644 --- a/tests/testdata/outputs_expected/returnvalue.sol.o.text +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.text @@ -1,30 +1,33 @@ -==== External call ==== +==== External Call To Fixed Address ==== SWC ID: 107 -Type: Informational +Severity: Low Contract: Unknown Function name: callchecked() PC address: 196 Estimated Gas Usage: 599 - 1210 -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -------------------- -==== External call ==== +==== External Call To Fixed Address ==== SWC ID: 107 -Type: Informational +Severity: Low Contract: Unknown Function name: callnotchecked() PC address: 285 Estimated Gas Usage: 621 - 1232 -The contract executes a function call to an external address. Verify that the code at this address is trusted and immutable. +The contract executes an external message call. +An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully. -------------------- -==== Unchecked CALL return value ==== +==== Unchecked Call Return Value ==== SWC ID: 104 -Type: Informational +Severity: Low Contract: Unknown Function name: callnotchecked() PC address: 285 Estimated Gas Usage: 1339 - 35950 -The return value of an external call is not checked. Note that execution continue even if the called contract throws. +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. -------------------- diff --git a/tests/testdata/outputs_expected/suicide.sol.o.json b/tests/testdata/outputs_expected/suicide.sol.o.json index 1cb84c82..1bca940f 100644 --- a/tests/testdata/outputs_expected/suicide.sol.o.json +++ b/tests/testdata/outputs_expected/suicide.sol.o.json @@ -1,18 +1 @@ -{ - "error": null, - "issues": [ - { - "address": 146, - "contract": "Unknown", - "debug": "", - "description": "Anyone can kill this contract and withdraw its balance to their own account.", - "function": "kill(address)", - "max_gas_used": 263, - "min_gas_used": 168, - "swc-id": "106", - "title": "Unchecked SUICIDE", - "type": "Warning" - } - ], - "success": true -} +{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-106", "swcTitle": "Unprotected SELFDESTRUCT Instruction"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/suicide.sol.o.markdown b/tests/testdata/outputs_expected/suicide.sol.o.markdown index cea3af81..3325269d 100644 --- a/tests/testdata/outputs_expected/suicide.sol.o.markdown +++ b/tests/testdata/outputs_expected/suicide.sol.o.markdown @@ -1,8 +1,8 @@ # Analysis results for test-filename.sol -## Unchecked SUICIDE +## Unprotected Selfdestruct - SWC ID: 106 -- Type: Warning +- Severity: High - Contract: Unknown - Function name: `kill(address)` - PC address: 146 @@ -10,4 +10,5 @@ ### Description -Anyone can kill this contract and withdraw its balance to their own account. +The contract can be killed by anyone. +Arbitrary senders can kill this contract and withdraw its balance to their own account. diff --git a/tests/testdata/outputs_expected/suicide.sol.o.text b/tests/testdata/outputs_expected/suicide.sol.o.text index 20a5bd24..5072a942 100644 --- a/tests/testdata/outputs_expected/suicide.sol.o.text +++ b/tests/testdata/outputs_expected/suicide.sol.o.text @@ -1,10 +1,11 @@ -==== Unchecked SUICIDE ==== +==== Unprotected Selfdestruct ==== SWC ID: 106 -Type: Warning +Severity: High Contract: Unknown Function name: kill(address) PC address: 146 Estimated Gas Usage: 168 - 263 -Anyone can kill this contract and withdraw its balance to their own account. +The contract can be killed by anyone. +Arbitrary senders can kill this contract and withdraw its balance to their own account. -------------------- diff --git a/tests/testdata/outputs_expected/underflow.sol.o.json b/tests/testdata/outputs_expected/underflow.sol.o.json index aefffb2b..6e2c9a2c 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.json +++ b/tests/testdata/outputs_expected/underflow.sol.o.json @@ -1,42 +1 @@ -{ - "error":null, - "issues":[ - { - "address":567, - "contract":"Unknown", - "debug":"", - "description":"This binary subtraction operation can result in integer overflow.\n", - "function":"sendeth(address,uint256)", - "max_gas_used":1053, - "min_gas_used":768, - "swc-id":"101", - "title":"Integer Overflow", - "type":"Warning" - }, - { - "address":567, - "contract":"Unknown", - "debug":"", - "description":"This binary subtraction operation can result in integer underflow.\n", - "function":"sendeth(address,uint256)", - "max_gas_used":1774, - "min_gas_used":1299, - "swc-id":"101", - "title":"Integer Underflow", - "type":"Warning" - }, - { - "address":649, - "contract":"Unknown", - "debug":"", - "description":"This binary subtraction operation can result in integer underflow.\n", - "function":"sendeth(address,uint256)", - "max_gas_used":1774, - "min_gas_used":1299, - "swc-id":"101", - "title":"Integer Underflow", - "type":"Warning" - } - ], - "success":true -} +{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.markdown b/tests/testdata/outputs_expected/underflow.sol.o.markdown index ce87c901..63c84af1 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.markdown +++ b/tests/testdata/outputs_expected/underflow.sol.o.markdown @@ -2,7 +2,7 @@ ## Integer Overflow - SWC ID: 101 -- Type: Warning +- Severity: High - Contract: Unknown - Function name: `sendeth(address,uint256)` - PC address: 567 @@ -10,11 +10,12 @@ ### Description -This binary subtraction operation can result in integer overflow. +The subtraction can overflow. +The binary subtraction operation can result in an integer overflow. ## Integer Underflow - SWC ID: 101 -- Type: Warning +- Severity: High - Contract: Unknown - Function name: `sendeth(address,uint256)` - PC address: 567 @@ -22,11 +23,12 @@ This binary subtraction operation can result in integer overflow. ### Description -This binary subtraction operation can result in integer underflow. +The subtraction can underflow. +The binary subtraction operation can result in an integer underflow. ## Integer Underflow - SWC ID: 101 -- Type: Warning +- Severity: High - Contract: Unknown - Function name: `sendeth(address,uint256)` - PC address: 649 @@ -34,4 +36,5 @@ This binary subtraction operation can result in integer underflow. ### Description -This binary subtraction operation can result in integer underflow. +The subtraction can underflow. +The binary subtraction operation can result in an integer underflow. diff --git a/tests/testdata/outputs_expected/underflow.sol.o.text b/tests/testdata/outputs_expected/underflow.sol.o.text index fdea1818..72467aeb 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.text +++ b/tests/testdata/outputs_expected/underflow.sol.o.text @@ -1,33 +1,36 @@ ==== Integer Overflow ==== SWC ID: 101 -Type: Warning +Severity: High Contract: Unknown Function name: sendeth(address,uint256) PC address: 567 Estimated Gas Usage: 768 - 1053 -This binary subtraction operation can result in integer overflow. +The subtraction can overflow. +The binary subtraction operation can result in an integer overflow. -------------------- ==== Integer Underflow ==== SWC ID: 101 -Type: Warning +Severity: High Contract: Unknown Function name: sendeth(address,uint256) PC address: 567 Estimated Gas Usage: 1299 - 1774 -This binary subtraction operation can result in integer underflow. +The subtraction can underflow. +The binary subtraction operation can result in an integer underflow. -------------------- ==== Integer Underflow ==== SWC ID: 101 -Type: Warning +Severity: High Contract: Unknown Function name: sendeth(address,uint256) PC address: 649 Estimated Gas Usage: 1299 - 1774 -This binary subtraction operation can result in integer underflow. +The subtraction can underflow. +The binary subtraction operation can result in an integer underflow. -------------------- From 2fe3fb36a47881d79198484fabd57039b96feb20 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 28 Dec 2018 22:46:24 +0530 Subject: [PATCH 18/56] Revert json to the previous format --- mythril/analysis/report.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 3af57363..65d0d90a 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -125,21 +125,7 @@ class Report: ) def as_json(self): - result = { - "issues": [ - { - "swcID": "SWC-{}".format(issue.swc_id), - "swcTitle": SWC_TO_TITLE[issue.swc_id], - "locations": [{"sourceMap": issue.source_mapping}], - "extra": "", - } - for issue in self.issues.values() - ], - "sourceType": self.source_type, - "sourceFormat": self.source_format, - "sourceList": self.source_list, - "meta": self.meta, - } + result = {"success": True, "error": None, "issues": self.sorted_issues()} return json.dumps(result, sort_keys=True) def as_swc_standard_format(self): From ff11d7236a7168f23503c4d0bab53899d194dc71 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 28 Dec 2018 23:00:00 +0530 Subject: [PATCH 19/56] Change the json tests --- tests/testdata/outputs_expected/calls.sol.o.json | 2 +- tests/testdata/outputs_expected/ether_send.sol.o.json | 2 +- tests/testdata/outputs_expected/exceptions.sol.o.json | 2 +- tests/testdata/outputs_expected/kinds_of_calls.sol.o.json | 2 +- tests/testdata/outputs_expected/metacoin.sol.o.json | 2 +- tests/testdata/outputs_expected/multi_contracts.sol.o.json | 2 +- tests/testdata/outputs_expected/nonascii.sol.o.json | 2 +- tests/testdata/outputs_expected/origin.sol.o.json | 2 +- tests/testdata/outputs_expected/overflow.sol.o.json | 2 +- tests/testdata/outputs_expected/returnvalue.sol.o.json | 2 +- tests/testdata/outputs_expected/suicide.sol.o.json | 2 +- tests/testdata/outputs_expected/underflow.sol.o.json | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/testdata/outputs_expected/calls.sol.o.json b/tests/testdata/outputs_expected/calls.sol.o.json index 68317bed..d5545e15 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.json +++ b/tests/testdata/outputs_expected/calls.sol.o.json @@ -1 +1 @@ -{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 661, "contract": "Unknown", "debug": "", "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, "min_gas_used": 643, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 661, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1361, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 779, "contract": "Unknown", "debug": "", "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, "min_gas_used": 687, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 779, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1405, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 858, "contract": "Unknown", "debug": "", "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, "min_gas_used": 709, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 858, "contract": "Unknown", "debug": "", "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, "min_gas_used": 6441, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 912, "contract": "Unknown", "debug": "", "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 thecontract state.", "function": "calluseraddress(address)", "max_gas_used": 616, "min_gas_used": 335, "severity": "Medium", "swc-id": "107", "title": "External Call To User-Supplied Address"}, {"SourceMap": null, "address": 912, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1055, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/ether_send.sol.o.json b/tests/testdata/outputs_expected/ether_send.sol.o.json index 87eb5313..237b1c1e 100644 --- a/tests/testdata/outputs_expected/ether_send.sol.o.json +++ b/tests/testdata/outputs_expected/ether_send.sol.o.json @@ -1 +1 @@ -{"issues": [], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.json b/tests/testdata/outputs_expected/exceptions.sol.o.json index dc634a5a..31d12ee6 100644 --- a/tests/testdata/outputs_expected/exceptions.sol.o.json +++ b/tests/testdata/outputs_expected/exceptions.sol.o.json @@ -1 +1 @@ -{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-110", "swcTitle": "Assert Violation"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 446, "contract": "Unknown", "debug": "", "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, "min_gas_used": 206, "severity": "Low", "swc-id": "110", "title": "Exception State"}, {"SourceMap": null, "address": 484, "contract": "Unknown", "debug": "", "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, "min_gas_used": 256, "severity": "Low", "swc-id": "110", "title": "Exception State"}, {"SourceMap": null, "address": 506, "contract": "Unknown", "debug": "", "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, "min_gas_used": 272, "severity": "Low", "swc-id": "110", "title": "Exception State"}, {"SourceMap": null, "address": 531, "contract": "Unknown", "debug": "", "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, "min_gas_used": 268, "severity": "Low", "swc-id": "110", "title": "Exception State"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json index 67536da1..9e38db02 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json @@ -1 +1 @@ -{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 618, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1113, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 618, "contract": "Unknown", "debug": "", "description": "Use of callcode is deprecated.\nThe function `_function_0x141f32ff` uses the callcode function. Callcode does not persist sender or value over the call. Use delegatecall instead.", "function": "_function_0x141f32ff", "max_gas_used": 1141, "min_gas_used": 389, "severity": "Medium", "swc-id": "111", "title": "Use of Callcode"}, {"SourceMap": null, "address": 849, "contract": "Unknown", "debug": "", "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": 35922, "min_gas_used": 1170, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 1038, "contract": "Unknown", "debug": "", "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 thecontract state.", "function": "_function_0xeea4c864", "max_gas_used": 1223, "min_gas_used": 471, "severity": "Medium", "swc-id": "107", "title": "External Call To User-Supplied Address"}, {"SourceMap": null, "address": 1038, "contract": "Unknown", "debug": "", "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": 35947, "min_gas_used": 1195, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/metacoin.sol.o.json b/tests/testdata/outputs_expected/metacoin.sol.o.json index 87eb5313..237b1c1e 100644 --- a/tests/testdata/outputs_expected/metacoin.sol.o.json +++ b/tests/testdata/outputs_expected/metacoin.sol.o.json @@ -1 +1 @@ -{"issues": [], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.json b/tests/testdata/outputs_expected/multi_contracts.sol.o.json index 95705ffc..8153bf38 100644 --- a/tests/testdata/outputs_expected/multi_contracts.sol.o.json +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.json @@ -1 +1 @@ -{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-105", "swcTitle": "Unprotected Ether Withdrawal"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 142, "contract": "Unknown", "debug": "", "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, "min_gas_used": 186, "severity": "High", "swc-id": "105", "title": "Unprotected Ether Withdrawal"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/nonascii.sol.o.json b/tests/testdata/outputs_expected/nonascii.sol.o.json index 87eb5313..237b1c1e 100644 --- a/tests/testdata/outputs_expected/nonascii.sol.o.json +++ b/tests/testdata/outputs_expected/nonascii.sol.o.json @@ -1 +1 @@ -{"issues": [], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.json b/tests/testdata/outputs_expected/origin.sol.o.json index 2f2eec19..f8fa7dce 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.json +++ b/tests/testdata/outputs_expected/origin.sol.o.json @@ -1 +1 @@ -{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 317, "contract": "Unknown", "debug": "", "description": "Use of tx.origin is deprecated.\nThe function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead.\nSee also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin", "function": "transferOwnership(address)", "max_gas_used": 1051, "min_gas_used": 626, "severity": "Medium", "swc-id": "111", "title": "Use of tx.origin is deprecated."}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/overflow.sol.o.json b/tests/testdata/outputs_expected/overflow.sol.o.json index 6e2c9a2c..1ef38e4d 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.json +++ b/tests/testdata/outputs_expected/overflow.sol.o.json @@ -1 +1 @@ -{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1053, "min_gas_used": 768, "severity": "High", "swc-id": "101", "title": "Integer Overflow"}, {"SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "swc-id": "101", "title": "Integer Underflow"}, {"SourceMap": null, "address": 649, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "swc-id": "101", "title": "Integer Underflow"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.json b/tests/testdata/outputs_expected/returnvalue.sol.o.json index ab1f619c..ebe87f67 100644 --- a/tests/testdata/outputs_expected/returnvalue.sol.o.json +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.json @@ -1 +1 @@ -{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 196, "contract": "Unknown", "debug": "", "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, "min_gas_used": 599, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 285, "contract": "Unknown", "debug": "", "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, "min_gas_used": 621, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 285, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1339, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/suicide.sol.o.json b/tests/testdata/outputs_expected/suicide.sol.o.json index 1bca940f..a2a1e640 100644 --- a/tests/testdata/outputs_expected/suicide.sol.o.json +++ b/tests/testdata/outputs_expected/suicide.sol.o.json @@ -1 +1 @@ -{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-106", "swcTitle": "Unprotected SELFDESTRUCT Instruction"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 146, "contract": "Unknown", "debug": "", "description": "The contract can be killed by anyone.\nArbitrary senders can kill this contract and withdraw its balance to their own account.", "function": "kill(address)", "max_gas_used": 263, "min_gas_used": 168, "severity": "High", "swc-id": "106", "title": "Unprotected Selfdestruct"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.json b/tests/testdata/outputs_expected/underflow.sol.o.json index 6e2c9a2c..1ef38e4d 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.json +++ b/tests/testdata/outputs_expected/underflow.sol.o.json @@ -1 +1 @@ -{"issues": [{"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"debug": "", "extra": "", "locations": [{"sourceMap": null}], "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": null, "sourceFormat": null, "sourceList": [], "sourceType": null} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1053, "min_gas_used": 768, "severity": "High", "swc-id": "101", "title": "Integer Overflow"}, {"SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "swc-id": "101", "title": "Integer Underflow"}, {"SourceMap": null, "address": 649, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "swc-id": "101", "title": "Integer Underflow"}], "success": true} \ No newline at end of file From 907845c4d1b3b6ec01ff66613d6db2b3414b0cce Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 28 Dec 2018 23:59:40 +0530 Subject: [PATCH 20/56] Add the standard json format tests --- tests/report_test.py | 12 +++++++++++- tests/testdata/outputs_expected/calls.sol.o.jsonv2 | 1 + .../outputs_expected/ether_send.sol.o.jsonv2 | 1 + .../outputs_expected/exceptions.sol.o.jsonv2 | 1 + .../outputs_expected/kinds_of_calls.sol.o.jsonv2 | 1 + .../testdata/outputs_expected/metacoin.sol.o.jsonv2 | 1 + .../outputs_expected/multi_contracts.sol.o.jsonv2 | 1 + .../testdata/outputs_expected/nonascii.sol.o.jsonv2 | 1 + tests/testdata/outputs_expected/origin.sol.o.jsonv2 | 1 + .../testdata/outputs_expected/overflow.sol.o.jsonv2 | 1 + .../outputs_expected/returnvalue.sol.o.jsonv2 | 1 + tests/testdata/outputs_expected/suicide.sol.o.jsonv2 | 1 + .../testdata/outputs_expected/underflow.sol.o.jsonv2 | 1 + 13 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/testdata/outputs_expected/calls.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/origin.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/overflow.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/suicide.sol.o.jsonv2 create mode 100644 tests/testdata/outputs_expected/underflow.sol.o.jsonv2 diff --git a/tests/report_test.py b/tests/report_test.py index 39493ae9..096f1aa3 100644 --- a/tests/report_test.py +++ b/tests/report_test.py @@ -117,7 +117,6 @@ def _get_changed_files(postfix, report_builder, reports): output_expected = TESTDATA_OUTPUTS_EXPECTED / (input_file.name + postfix) output_current = TESTDATA_OUTPUTS_CURRENT / (input_file.name + postfix) output_current.write_text(report_builder(report)) - if not (output_expected.read_text() == output_current.read_text()): yield input_file @@ -168,3 +167,14 @@ def test_text_report(reports): ), ".text", ) + + +def test_jsonv2_report(reports): + _assert_empty( + _get_changed_files( + ".jsonv2", + lambda report: _fix_path(report.as_swc_standard_format()), + reports, + ), + ".jsonv2", + ) diff --git a/tests/testdata/outputs_expected/calls.sol.o.jsonv2 b/tests/testdata/outputs_expected/calls.sol.o.jsonv2 new file mode 100644 index 00000000..d90aad54 --- /dev/null +++ b/tests/testdata/outputs_expected/calls.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [{"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "107", "swcTitle": "Reentrancy"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Medium", "swcID": "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": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x7cbb77986c6b1bf6e945cd3fba06d3ea3d28cfc49cdfdc9571ec30703ac5862f"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 b/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 new file mode 100644 index 00000000..c1512195 --- /dev/null +++ b/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": [], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 b/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 new file mode 100644 index 00000000..3ec3217c --- /dev/null +++ b/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [{"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "446:1:0"}], "severity": "Low", "swcID": "110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "484:1:0"}], "severity": "Low", "swcID": "110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "506:1:0"}], "severity": "Low", "swcID": "110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "531:1:0"}], "severity": "Low", "swcID": "110", "swcTitle": "Assert Violation"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x4a773a86bc6fb269f88bf09bb3094de29b6073cf13b1760e9d01d957f50a9dfd"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 new file mode 100644 index 00000000..6ebacfcc --- /dev/null +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [{"description": {"head": ["Use of callcode is deprecated."], "tail": ["The function `_function_0x141f32ff` uses the callcode function. Callcode does not persist sender or value over the call. Use delegatecall instead."]}, "extra": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Medium", "swcID": "111", "swcTitle": "Use of Deprecated Solidity Functions"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Medium", "swcID": "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "849:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x6daec61d05d8f1210661e7e7d1ed6d72bd6ade639398fac1e867aff50abfc1c1"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 b/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 new file mode 100644 index 00000000..c1512195 --- /dev/null +++ b/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": [], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 b/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 new file mode 100644 index 00000000..c3c890ba --- /dev/null +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [{"description": {"head": ["Anyone can withdraw ETH from the contract account."], "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": {}, "locations": [{"sourceMap": "142:1:0"}], "severity": "High", "swcID": "105", "swcTitle": "Unprotected Ether Withdrawal"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xbc9c3d9db56d20cf4ca3b6fd88ff9215cf728a092cca1ed8edb83272b933ff5b"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 b/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 new file mode 100644 index 00000000..c1512195 --- /dev/null +++ b/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": [], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.jsonv2 b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 new file mode 100644 index 00000000..8d023d47 --- /dev/null +++ b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [{"description": {"head": ["Use of tx.origin is deprecated."], "tail": ["The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead.\nSee also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin"]}, "extra": {}, "locations": [{"sourceMap": "317:1:0"}], "severity": "Medium", "swcID": "111", "swcTitle": "Use of Deprecated Solidity Functions"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x25b20ef097dfc0aa56a932c4e09f06ee02a69c005767df86877f48c6c2412f03"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 new file mode 100644 index 00000000..e8016642 --- /dev/null +++ b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [{"description": {"head": ["The subtraction can overflow."], "tail": ["The binary subtraction operation can result in an integer overflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xf230bec502569e8b7e7737616d0ad0f200c436624e3c223e5398c0615cd2d6b9"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 b/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 new file mode 100644 index 00000000..5a0d1908 --- /dev/null +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [{"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "196:1:0"}], "severity": "Low", "swcID": "107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "285:1:0"}], "severity": "Low", "swcID": "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": {}, "locations": [{"sourceMap": "285:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xb191cf6cc0d8cc37a91c9d88019cc011b932169fb5776df616e2bb9cd93b4039"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 b/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 new file mode 100644 index 00000000..e16aae95 --- /dev/null +++ b/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [{"description": {"head": ["The contract can be killed by anyone."], "tail": ["Arbitrary senders can kill this contract and withdraw its balance to their own account."]}, "extra": {}, "locations": [{"sourceMap": "146:1:0"}], "severity": "High", "swcID": "106", "swcTitle": "Unprotected SELFDESTRUCT Instruction"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x2fb801366b61a05b30550481a1c8f7d5f20de0b93d9f2f2ce2b28c4e322033c9"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 new file mode 100644 index 00000000..7e354795 --- /dev/null +++ b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 @@ -0,0 +1 @@ +{"issues": [{"description": {"head": ["The subtraction can overflow."], "tail": ["The binary subtraction operation can result in an integer overflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xabef56740bf7795a9f8732e4781ebd27f2977f8a4997e3ff11cee79a4ba6c0ce"], "sourceType": "raw-bytecode"} \ No newline at end of file From eb19d8a1701e00b809caebcb8586d65b708a3b28 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sat, 29 Dec 2018 00:31:40 +0530 Subject: [PATCH 21/56] Fix the standard json tests for json check --- tests/report_test.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/report_test.py b/tests/report_test.py index 096f1aa3..4bfa13cf 100644 --- a/tests/report_test.py +++ b/tests/report_test.py @@ -75,9 +75,8 @@ def _assert_empty(changed_files, postfix): assert message == "", message -def _assert_empty_json(changed_files): +def _assert_empty_json(changed_files, postfix=".json"): """ Asserts there are no changed files and otherwise builds error message""" - postfix = ".json" expected = [] actual = [] @@ -121,9 +120,7 @@ def _get_changed_files(postfix, report_builder, reports): yield input_file -def _get_changed_files_json(report_builder, reports): - postfix = ".json" - +def _get_changed_files_json(report_builder, reports, postfix=".json"): def ordered(obj): if isinstance(obj, dict): return sorted((k, ordered(v)) for k, v in obj.items()) @@ -170,11 +167,11 @@ def test_text_report(reports): def test_jsonv2_report(reports): - _assert_empty( - _get_changed_files( - ".jsonv2", - lambda report: _fix_path(report.as_swc_standard_format()), + _assert_empty_json( + _get_changed_files_json( + lambda report: _fix_path(report.as_swc_standard_format()).strip(), reports, + ".jsonv2", ), ".jsonv2", ) From 792ef1c058b00c886b1558fa23db12ace5b566c3 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Tue, 1 Jan 2019 10:31:16 +0700 Subject: [PATCH 22/56] Remove reassignment of description in delegatecall.py --- mythril/analysis/modules/delegatecall.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mythril/analysis/modules/delegatecall.py b/mythril/analysis/modules/delegatecall.py index e59ff8a8..86aef343 100644 --- a/mythril/analysis/modules/delegatecall.py +++ b/mythril/analysis/modules/delegatecall.py @@ -88,12 +88,6 @@ def _concrete_call( gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) - issue.description = ( - "" - "This means that any function in the called contract can be executed. Note that the callee contract will have " - "access to the storage of the calling contract.\n" - ) - target = hex(call.to.val) if call.to.type == VarType.CONCRETE else str(call.to) issue.description += "DELEGATECALL target: {}".format(target) From 20e57903375731351ca3e7d16b3cbb66200f531c Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Tue, 1 Jan 2019 10:46:57 +0700 Subject: [PATCH 23/56] Improve report descriptions in deprecated ops module --- mythril/analysis/modules/deprecated_ops.py | 10 ++++++---- .../outputs_expected/kinds_of_calls.sol.o.json | 2 +- .../outputs_expected/kinds_of_calls.sol.o.jsonv2 | 2 +- .../outputs_expected/kinds_of_calls.sol.o.markdown | 2 +- .../outputs_expected/kinds_of_calls.sol.o.text | 2 +- tests/testdata/outputs_expected/origin.sol.o.json | 2 +- tests/testdata/outputs_expected/origin.sol.o.jsonv2 | 2 +- tests/testdata/outputs_expected/origin.sol.o.markdown | 4 ++-- tests/testdata/outputs_expected/origin.sol.o.text | 4 ++-- 9 files changed, 16 insertions(+), 14 deletions(-) diff --git a/mythril/analysis/modules/deprecated_ops.py b/mythril/analysis/modules/deprecated_ops.py index 05c77bc0..114a050b 100644 --- a/mythril/analysis/modules/deprecated_ops.py +++ b/mythril/analysis/modules/deprecated_ops.py @@ -17,10 +17,11 @@ def _analyze_state(state): if instruction["opcode"] == "ORIGIN": log.debug("ORIGIN in function " + node.function_name) - title = "Use of tx.origin is deprecated." + title = "Use of tx.origin" description_head = "Use of tx.origin is deprecated." description_tail = ( - "The function `{}` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. " + "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".format( node.function_name @@ -33,8 +34,9 @@ def _analyze_state(state): title = "Use of Callcode" description_head = "Use of callcode is deprecated." description_tail = ( - "The function `{}` uses the callcode function. Callcode does not persist sender or value over the call. " - "Use delegatecall instead.".format(node.function_name) + "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." ) swc_id = DEPRICATED_FUNCTIONS_USAGE diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json index 9e38db02..73280f56 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json @@ -1 +1 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 618, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1113, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 618, "contract": "Unknown", "debug": "", "description": "Use of callcode is deprecated.\nThe function `_function_0x141f32ff` uses the callcode function. Callcode does not persist sender or value over the call. Use delegatecall instead.", "function": "_function_0x141f32ff", "max_gas_used": 1141, "min_gas_used": 389, "severity": "Medium", "swc-id": "111", "title": "Use of Callcode"}, {"SourceMap": null, "address": 849, "contract": "Unknown", "debug": "", "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": 35922, "min_gas_used": 1170, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 1038, "contract": "Unknown", "debug": "", "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 thecontract state.", "function": "_function_0xeea4c864", "max_gas_used": 1223, "min_gas_used": 471, "severity": "Medium", "swc-id": "107", "title": "External Call To User-Supplied Address"}, {"SourceMap": null, "address": 1038, "contract": "Unknown", "debug": "", "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": 35947, "min_gas_used": 1195, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 618, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1113, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 618, "contract": "Unknown", "debug": "", "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, "min_gas_used": 389, "severity": "Medium", "swc-id": "111", "title": "Use of Callcode"}, {"SourceMap": null, "address": 849, "contract": "Unknown", "debug": "", "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": 35922, "min_gas_used": 1170, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 1038, "contract": "Unknown", "debug": "", "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 thecontract state.", "function": "_function_0xeea4c864", "max_gas_used": 1223, "min_gas_used": 471, "severity": "Medium", "swc-id": "107", "title": "External Call To User-Supplied Address"}, {"SourceMap": null, "address": 1038, "contract": "Unknown", "debug": "", "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": 35947, "min_gas_used": 1195, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 index 6ebacfcc..5e8133d1 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["Use of callcode is deprecated."], "tail": ["The function `_function_0x141f32ff` uses the callcode function. Callcode does not persist sender or value over the call. Use delegatecall instead."]}, "extra": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Medium", "swcID": "111", "swcTitle": "Use of Deprecated Solidity Functions"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Medium", "swcID": "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "849:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x6daec61d05d8f1210661e7e7d1ed6d72bd6ade639398fac1e867aff50abfc1c1"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": ["Use of callcode is deprecated."], "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Medium", "swcID": "111", "swcTitle": "Use of Deprecated Solidity Functions"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Medium", "swcID": "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "849:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x6daec61d05d8f1210661e7e7d1ed6d72bd6ade639398fac1e867aff50abfc1c1"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown index bf30348e..5ea1cb47 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown @@ -24,7 +24,7 @@ External calls return a boolean value. If the callee contract halts with an exce ### Description Use of callcode is deprecated. -The function `_function_0x141f32ff` uses the callcode function. Callcode does not persist sender or value over the call. Use delegatecall instead. +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. ## Unchecked Call Return Value - SWC ID: 104 diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text index 19e00cf9..05a399f3 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text @@ -17,7 +17,7 @@ Function name: _function_0x141f32ff PC address: 618 Estimated Gas Usage: 389 - 1141 Use of callcode is deprecated. -The function `_function_0x141f32ff` uses the callcode function. Callcode does not persist sender or value over the call. Use delegatecall instead. +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. -------------------- ==== Unchecked Call Return Value ==== diff --git a/tests/testdata/outputs_expected/origin.sol.o.json b/tests/testdata/outputs_expected/origin.sol.o.json index f8fa7dce..93603018 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.json +++ b/tests/testdata/outputs_expected/origin.sol.o.json @@ -1 +1 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 317, "contract": "Unknown", "debug": "", "description": "Use of tx.origin is deprecated.\nThe function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead.\nSee also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin", "function": "transferOwnership(address)", "max_gas_used": 1051, "min_gas_used": 626, "severity": "Medium", "swc-id": "111", "title": "Use of tx.origin is deprecated."}], "success": true} \ No newline at end of file +{"error": null, "issues": [{"SourceMap": null, "address": 317, "contract": "Unknown", "debug": "", "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, "min_gas_used": 626, "severity": "Medium", "swc-id": "111", "title": "Use of tx.origin"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.jsonv2 b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 index 8d023d47..8591ceee 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["Use of tx.origin is deprecated."], "tail": ["The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead.\nSee also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin"]}, "extra": {}, "locations": [{"sourceMap": "317:1:0"}], "severity": "Medium", "swcID": "111", "swcTitle": "Use of Deprecated Solidity Functions"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x25b20ef097dfc0aa56a932c4e09f06ee02a69c005767df86877f48c6c2412f03"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": ["Use of tx.origin is deprecated."], "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": {}, "locations": [{"sourceMap": "317:1:0"}], "severity": "Medium", "swcID": "111", "swcTitle": "Use of Deprecated Solidity Functions"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x25b20ef097dfc0aa56a932c4e09f06ee02a69c005767df86877f48c6c2412f03"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.markdown b/tests/testdata/outputs_expected/origin.sol.o.markdown index e9603d8c..cbacdae3 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.markdown +++ b/tests/testdata/outputs_expected/origin.sol.o.markdown @@ -1,6 +1,6 @@ # Analysis results for test-filename.sol -## Use of tx.origin is deprecated. +## Use of tx.origin - SWC ID: 111 - Severity: Medium - Contract: Unknown @@ -11,5 +11,5 @@ ### Description Use of tx.origin is deprecated. -The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead. +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. See also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin diff --git a/tests/testdata/outputs_expected/origin.sol.o.text b/tests/testdata/outputs_expected/origin.sol.o.text index 2b96e50f..5b62a208 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.text +++ b/tests/testdata/outputs_expected/origin.sol.o.text @@ -1,4 +1,4 @@ -==== Use of tx.origin is deprecated. ==== +==== Use of tx.origin ==== SWC ID: 111 Severity: Medium Contract: Unknown @@ -6,7 +6,7 @@ Function name: transferOwnership(address) PC address: 317 Estimated Gas Usage: 626 - 1051 Use of tx.origin is deprecated. -The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead. +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. See also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin -------------------- From 6f1aba646fd42cc77c27a54f45a8c98350dc3fb3 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Tue, 1 Jan 2019 11:18:10 +0700 Subject: [PATCH 24/56] Beautifully format all JSON files --- .../modules/dependence_on_predictable_vars.py | 4 +- mythril/analysis/modules/deprecated_ops.py | 4 +- .../outputs_expected/calls.sol.o.json | 111 +++++++++++- .../outputs_expected/calls.sol.o.jsonv2 | 163 +++++++++++++++++- .../outputs_expected/environments.sol.o.json | 12 +- .../outputs_expected/ether_send.sol.o.json | 6 +- .../outputs_expected/ether_send.sol.o.jsonv2 | 8 +- .../outputs_expected/exceptions.sol.o.json | 59 ++++++- .../outputs_expected/exceptions.sol.o.jsonv2 | 87 +++++++++- .../kinds_of_calls.sol.o.json | 72 +++++++- .../kinds_of_calls.sol.o.jsonv2 | 106 +++++++++++- .../kinds_of_calls.sol.o.markdown | 2 +- .../kinds_of_calls.sol.o.text | 2 +- .../outputs_expected/metacoin.sol.o.json | 6 +- .../outputs_expected/metacoin.sol.o.jsonv2 | 8 +- .../multi_contracts.sol.o.json | 20 ++- .../multi_contracts.sol.o.jsonv2 | 30 +++- .../outputs_expected/nonascii.sol.o.json | 6 +- .../outputs_expected/nonascii.sol.o.jsonv2 | 8 +- .../outputs_expected/origin.sol.o.json | 20 ++- .../outputs_expected/origin.sol.o.jsonv2 | 30 +++- .../outputs_expected/origin.sol.o.markdown | 2 +- .../outputs_expected/origin.sol.o.text | 2 +- .../outputs_expected/overflow.sol.o.json | 46 ++++- .../outputs_expected/overflow.sol.o.jsonv2 | 68 +++++++- .../outputs_expected/returnvalue.sol.o.json | 46 ++++- .../outputs_expected/returnvalue.sol.o.jsonv2 | 68 +++++++- .../outputs_expected/rubixi.sol.o.json | 46 ++--- .../outputs_expected/suicide.sol.o.json | 20 ++- .../outputs_expected/suicide.sol.o.jsonv2 | 30 +++- .../outputs_expected/underflow.sol.o.json | 46 ++++- .../outputs_expected/underflow.sol.o.jsonv2 | 68 +++++++- .../outputs_expected/weak_random.sol.o.json | 16 +- 33 files changed, 1153 insertions(+), 69 deletions(-) diff --git a/mythril/analysis/modules/dependence_on_predictable_vars.py b/mythril/analysis/modules/dependence_on_predictable_vars.py index 272fa447..5807dad0 100644 --- a/mythril/analysis/modules/dependence_on_predictable_vars.py +++ b/mythril/analysis/modules/dependence_on_predictable_vars.py @@ -165,8 +165,8 @@ def _analyze_states(state: GlobalState) -> list: index = r.group(1) if index and solve(call): description = ( - "Block.blockhash() is calculated using a value from storage " - "at index {}".format(index) + "A block hash is calculated using the block.blockhash(uint blockNumber) method. " + "The block number is obtained from storage index {}".format(index) ) issue = Issue( contract=call.node.contract_name, diff --git a/mythril/analysis/modules/deprecated_ops.py b/mythril/analysis/modules/deprecated_ops.py index 114a050b..60591195 100644 --- a/mythril/analysis/modules/deprecated_ops.py +++ b/mythril/analysis/modules/deprecated_ops.py @@ -21,7 +21,7 @@ def _analyze_state(state): description_head = "Use of tx.origin is deprecated." description_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 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".format( node.function_name @@ -31,7 +31,7 @@ def _analyze_state(state): elif instruction["opcode"] == "CALLCODE": log.debug("CALLCODE in function " + node.function_name) - title = "Use of Callcode" + title = "Use of callcode" description_head = "Use of callcode is deprecated." description_tail = ( "The callcode method executes code of another contract in the context of the caller account. " diff --git a/tests/testdata/outputs_expected/calls.sol.o.json b/tests/testdata/outputs_expected/calls.sol.o.json index d5545e15..9d7bb2b0 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.json +++ b/tests/testdata/outputs_expected/calls.sol.o.json @@ -1 +1,110 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 661, "contract": "Unknown", "debug": "", "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, "min_gas_used": 643, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 661, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1361, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 779, "contract": "Unknown", "debug": "", "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, "min_gas_used": 687, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 779, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1405, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 858, "contract": "Unknown", "debug": "", "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, "min_gas_used": 709, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 858, "contract": "Unknown", "debug": "", "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, "min_gas_used": 6441, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 912, "contract": "Unknown", "debug": "", "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 thecontract state.", "function": "calluseraddress(address)", "max_gas_used": 616, "min_gas_used": 335, "severity": "Medium", "swc-id": "107", "title": "External Call To User-Supplied Address"}, {"SourceMap": null, "address": 912, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1055, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file +{ + "success": true, + "error": null, + "issues": [ + { + "debug": "", + "function": "thisisfine()", + "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.", + "title": "External Call To Fixed Address", + "min_gas_used": 643, + "severity": "Low", + "SourceMap": null, + "contract": "Unknown", + "swc-id": "107", + "max_gas_used": 1254, + "address": 661 + }, + { + "function": "thisisfine()", + "debug": "", + "title": "Unchecked Call Return Value", + "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.", + "SourceMap": null, + "severity": "Low", + "min_gas_used": 1361, + "address": 661, + "max_gas_used": 35972, + "swc-id": "104", + "contract": "Unknown" + }, + { + "max_gas_used": 1298, + "address": 779, + "contract": "Unknown", + "swc-id": "107", + "severity": "Low", + "SourceMap": null, + "min_gas_used": 687, + "title": "External Call To Fixed Address", + "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()", + "debug": "" + }, + { + "title": "Unchecked Call Return Value", + "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()", + "debug": "", + "max_gas_used": 36016, + "address": 779, + "contract": "Unknown", + "swc-id": "104", + "severity": "Low", + "SourceMap": null, + "min_gas_used": 1405 + }, + { + "contract": "Unknown", + "swc-id": "107", + "max_gas_used": 1320, + "address": 858, + "min_gas_used": 709, + "severity": "Low", + "SourceMap": null, + "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.", + "title": "External Call To Fixed Address", + "debug": "", + "function": "reentrancy()" + }, + { + "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.", + "title": "Unchecked Call Return Value", + "debug": "", + "function": "reentrancy()", + "contract": "Unknown", + "swc-id": "104", + "max_gas_used": 61052, + "address": 858, + "min_gas_used": 6441, + "severity": "Low", + "SourceMap": null + }, + { + "severity": "Medium", + "SourceMap": null, + "min_gas_used": 335, + "max_gas_used": 616, + "address": 912, + "contract": "Unknown", + "swc-id": "107", + "function": "calluseraddress(address)", + "debug": "", + "title": "External Call To User-Supplied Address", + "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 thecontract state." + }, + { + "min_gas_used": 1055, + "SourceMap": null, + "severity": "Low", + "swc-id": "104", + "contract": "Unknown", + "address": 912, + "max_gas_used": 35336, + "debug": "", + "function": "calluseraddress(address)", + "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.", + "title": "Unchecked Call Return Value" + } + ] +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/calls.sol.o.jsonv2 b/tests/testdata/outputs_expected/calls.sol.o.jsonv2 index d90aad54..580400f4 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/calls.sol.o.jsonv2 @@ -1 +1,162 @@ -{"issues": [{"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "107", "swcTitle": "Reentrancy"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Medium", "swcID": "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": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x7cbb77986c6b1bf6e945cd3fba06d3ea3d28cfc49cdfdc9571ec30703ac5862f"], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "sourceFormat": "evm-byzantium-bytecode", + "issues": [ + { + "locations": [ + { + "sourceMap": "661:1:0" + } + ], + "description": { + "tail": [ + "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." + ], + "head": [ + "The contract executes an external message call." + ] + }, + "severity": "Low", + "swcID": "107", + "extra": {}, + "swcTitle": "Reentrancy" + }, + { + "swcID": "107", + "extra": {}, + "swcTitle": "Reentrancy", + "locations": [ + { + "sourceMap": "779:1:0" + } + ], + "description": { + "tail": [ + "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." + ], + "head": [ + "The contract executes an external message call." + ] + }, + "severity": "Low" + }, + { + "swcID": "107", + "extra": {}, + "swcTitle": "Reentrancy", + "locations": [ + { + "sourceMap": "858:1:0" + } + ], + "description": { + "head": [ + "The contract executes an external message call." + ], + "tail": [ + "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." + ] + }, + "severity": "Low" + }, + { + "swcTitle": "Reentrancy", + "extra": {}, + "swcID": "107", + "severity": "Medium", + "description": { + "head": [ + "A call to a user-supplied address is executed." + ], + "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 thecontract state." + ] + }, + "locations": [ + { + "sourceMap": "912:1:0" + } + ] + }, + { + "swcTitle": "Unchecked Call Return Value", + "extra": {}, + "swcID": "104", + "severity": "Low", + "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." + ] + }, + "locations": [ + { + "sourceMap": "661:1:0" + } + ] + }, + { + "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." + ] + }, + "severity": "Low", + "locations": [ + { + "sourceMap": "779:1:0" + } + ], + "swcTitle": "Unchecked Call Return Value", + "swcID": "104", + "extra": {} + }, + { + "locations": [ + { + "sourceMap": "858:1:0" + } + ], + "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." + ] + }, + "severity": "Low", + "swcID": "104", + "extra": {}, + "swcTitle": "Unchecked Call Return Value" + }, + { + "severity": "Low", + "description": { + "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." + ], + "head": [ + "The return value of a message call is not checked." + ] + }, + "locations": [ + { + "sourceMap": "912:1:0" + } + ], + "swcTitle": "Unchecked Call Return Value", + "extra": {}, + "swcID": "104" + } + ], + "sourceType": "raw-bytecode", + "sourceList": [ + "0x7cbb77986c6b1bf6e945cd3fba06d3ea3d28cfc49cdfdc9571ec30703ac5862f" + ], + "meta": {} +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/environments.sol.o.json b/tests/testdata/outputs_expected/environments.sol.o.json index 5cd8f4db..d4ae2a37 100644 --- a/tests/testdata/outputs_expected/environments.sol.o.json +++ b/tests/testdata/outputs_expected/environments.sol.o.json @@ -9,7 +9,7 @@ "function": "_function_0x83f12fec", "swc-id": "101", "title": "Integer Overflow", - "type": "Warning", + "type": "Warning" }, { "address": 278, @@ -19,7 +19,7 @@ "function": "_function_0x83f12fec", "swc-id": "101", "title": "Integer Overflow", - "type": "Warning", + "type": "Warning" }, { "address": 378, @@ -29,8 +29,8 @@ "function": "_function_0x83f12fec", "swc-id": "101", "title": "Integer Underflow", - "type": "Warning", - }, + "type": "Warning" + } ], - "success": true, -} + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/ether_send.sol.o.json b/tests/testdata/outputs_expected/ether_send.sol.o.json index 237b1c1e..712f50c1 100644 --- a/tests/testdata/outputs_expected/ether_send.sol.o.json +++ b/tests/testdata/outputs_expected/ether_send.sol.o.json @@ -1 +1,5 @@ -{"error": null, "issues": [], "success": true} \ No newline at end of file +{ + "error": null, + "issues": [], + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 b/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 index c1512195..5e1c5ee1 100644 --- a/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 @@ -1 +1,7 @@ -{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": [], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "issues": [], + "meta": {}, + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": [], + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.json b/tests/testdata/outputs_expected/exceptions.sol.o.json index 31d12ee6..fc75823e 100644 --- a/tests/testdata/outputs_expected/exceptions.sol.o.json +++ b/tests/testdata/outputs_expected/exceptions.sol.o.json @@ -1 +1,58 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 446, "contract": "Unknown", "debug": "", "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, "min_gas_used": 206, "severity": "Low", "swc-id": "110", "title": "Exception State"}, {"SourceMap": null, "address": 484, "contract": "Unknown", "debug": "", "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, "min_gas_used": 256, "severity": "Low", "swc-id": "110", "title": "Exception State"}, {"SourceMap": null, "address": 506, "contract": "Unknown", "debug": "", "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, "min_gas_used": 272, "severity": "Low", "swc-id": "110", "title": "Exception State"}, {"SourceMap": null, "address": 531, "contract": "Unknown", "debug": "", "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, "min_gas_used": 268, "severity": "Low", "swc-id": "110", "title": "Exception State"}], "success": true} \ No newline at end of file +{ + "success": true, + "error": null, + "issues": [ + { + "title": "Exception State", + "severity": "Low", + "max_gas_used": 301, + "function": "assert3(uint256)", + "address": 446, + "min_gas_used": 206, + "contract": "Unknown", + "swc-id": "110", + "SourceMap": null, + "debug": "", + "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." + }, + { + "swc-id": "110", + "min_gas_used": 256, + "contract": "Unknown", + "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.", + "debug": "", + "SourceMap": null, + "severity": "Low", + "max_gas_used": 351, + "title": "Exception State", + "address": 484, + "function": "arrayaccess(uint256)" + }, + { + "max_gas_used": 367, + "severity": "Low", + "title": "Exception State", + "address": 506, + "function": "divisionby0(uint256)", + "swc-id": "110", + "min_gas_used": 272, + "contract": "Unknown", + "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.", + "debug": "", + "SourceMap": null + }, + { + "title": "Exception State", + "max_gas_used": 363, + "severity": "Low", + "function": "assert1()", + "address": 531, + "min_gas_used": 268, + "contract": "Unknown", + "swc-id": "110", + "SourceMap": null, + "debug": "", + "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." + } + ] +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 b/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 index 3ec3217c..e6b6849e 100644 --- a/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 @@ -1 +1,86 @@ -{"issues": [{"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "446:1:0"}], "severity": "Low", "swcID": "110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "484:1:0"}], "severity": "Low", "swcID": "110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "506:1:0"}], "severity": "Low", "swcID": "110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "531:1:0"}], "severity": "Low", "swcID": "110", "swcTitle": "Assert Violation"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x4a773a86bc6fb269f88bf09bb3094de29b6073cf13b1760e9d01d957f50a9dfd"], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "meta": {}, + "issues": [ + { + "swcTitle": "Assert Violation", + "swcID": "110", + "description": { + "head": [ + "A reachable exception has been detected." + ], + "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." + ] + }, + "locations": [ + { + "sourceMap": "446:1:0" + } + ], + "extra": {}, + "severity": "Low" + }, + { + "severity": "Low", + "extra": {}, + "locations": [ + { + "sourceMap": "484:1:0" + } + ], + "swcID": "110", + "swcTitle": "Assert Violation", + "description": { + "head": [ + "A reachable exception has been detected." + ], + "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." + ] + } + }, + { + "swcTitle": "Assert Violation", + "swcID": "110", + "description": { + "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." + ], + "head": [ + "A reachable exception has been detected." + ] + }, + "locations": [ + { + "sourceMap": "506:1:0" + } + ], + "extra": {}, + "severity": "Low" + }, + { + "description": { + "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." + ], + "head": [ + "A reachable exception has been detected." + ] + }, + "swcTitle": "Assert Violation", + "swcID": "110", + "extra": {}, + "locations": [ + { + "sourceMap": "531:1:0" + } + ], + "severity": "Low" + } + ], + "sourceList": [ + "0x4a773a86bc6fb269f88bf09bb3094de29b6073cf13b1760e9d01d957f50a9dfd" + ], + "sourceFormat": "evm-byzantium-bytecode", + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json index 73280f56..2ff55cc7 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json @@ -1 +1,71 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 618, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1113, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 618, "contract": "Unknown", "debug": "", "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, "min_gas_used": 389, "severity": "Medium", "swc-id": "111", "title": "Use of Callcode"}, {"SourceMap": null, "address": 849, "contract": "Unknown", "debug": "", "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": 35922, "min_gas_used": 1170, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}, {"SourceMap": null, "address": 1038, "contract": "Unknown", "debug": "", "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 thecontract state.", "function": "_function_0xeea4c864", "max_gas_used": 1223, "min_gas_used": 471, "severity": "Medium", "swc-id": "107", "title": "External Call To User-Supplied Address"}, {"SourceMap": null, "address": 1038, "contract": "Unknown", "debug": "", "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": 35947, "min_gas_used": 1195, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file +{ + "issues": [ + { + "contract": "Unknown", + "debug": "", + "min_gas_used": 1113, + "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.", + "severity": "Low", + "SourceMap": null, + "swc-id": "104", + "max_gas_used": 35865, + "function": "_function_0x141f32ff", + "title": "Unchecked Call Return Value", + "address": 618 + }, + { + "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.", + "severity": "Medium", + "SourceMap": null, + "min_gas_used": 389, + "debug": "", + "contract": "Unknown", + "address": 618, + "swc-id": "111", + "title": "Use of callcode", + "function": "_function_0x141f32ff", + "max_gas_used": 1141 + }, + { + "address": 849, + "max_gas_used": 35922, + "title": "Unchecked Call Return Value", + "function": "_function_0x9b58bc26", + "swc-id": "104", + "SourceMap": null, + "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.", + "severity": "Low", + "contract": "Unknown", + "debug": "", + "min_gas_used": 1170 + }, + { + "min_gas_used": 471, + "debug": "", + "contract": "Unknown", + "SourceMap": null, + "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 thecontract state.", + "severity": "Medium", + "function": "_function_0xeea4c864", + "title": "External Call To User-Supplied Address", + "max_gas_used": 1223, + "swc-id": "107", + "address": 1038 + }, + { + "swc-id": "104", + "title": "Unchecked Call Return Value", + "function": "_function_0xeea4c864", + "max_gas_used": 35947, + "address": 1038, + "debug": "", + "min_gas_used": 1195, + "contract": "Unknown", + "severity": "Low", + "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.", + "SourceMap": null + } + ], + "success": true, + "error": null +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 index 5e8133d1..f22d7019 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 @@ -1 +1,105 @@ -{"issues": [{"description": {"head": ["Use of callcode is deprecated."], "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Medium", "swcID": "111", "swcTitle": "Use of Deprecated Solidity Functions"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Medium", "swcID": "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "849:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x6daec61d05d8f1210661e7e7d1ed6d72bd6ade639398fac1e867aff50abfc1c1"], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "issues": [ + { + "swcTitle": "Use of Deprecated Solidity Functions", + "swcID": "111", + "extra": {}, + "severity": "Medium", + "description": { + "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." + ], + "head": [ + "Use of callcode is deprecated." + ] + }, + "locations": [ + { + "sourceMap": "618:1:0" + } + ] + }, + { + "severity": "Medium", + "locations": [ + { + "sourceMap": "1038:1:0" + } + ], + "description": { + "head": [ + "A call to a user-supplied address is executed." + ], + "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 thecontract state." + ] + }, + "extra": {}, + "swcTitle": "Reentrancy", + "swcID": "107" + }, + { + "swcTitle": "Unchecked Call Return Value", + "swcID": "104", + "extra": {}, + "severity": "Low", + "description": { + "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." + ], + "head": [ + "The return value of a message call is not checked." + ] + }, + "locations": [ + { + "sourceMap": "618:1:0" + } + ] + }, + { + "extra": {}, + "severity": "Low", + "locations": [ + { + "sourceMap": "849:1:0" + } + ], + "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." + ] + }, + "swcTitle": "Unchecked Call Return Value", + "swcID": "104" + }, + { + "swcID": "104", + "swcTitle": "Unchecked Call Return Value", + "locations": [ + { + "sourceMap": "1038:1:0" + } + ], + "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." + ] + }, + "severity": "Low", + "extra": {} + } + ], + "sourceList": [ + "0x6daec61d05d8f1210661e7e7d1ed6d72bd6ade639398fac1e867aff50abfc1c1" + ], + "sourceFormat": "evm-byzantium-bytecode", + "sourceType": "raw-bytecode", + "meta": {} +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown index 5ea1cb47..95011cec 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.markdown @@ -13,7 +13,7 @@ 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. -## Use of Callcode +## Use of callcode - SWC ID: 111 - Severity: Medium - Contract: Unknown diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text index 05a399f3..1c922c71 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.text @@ -9,7 +9,7 @@ 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. -------------------- -==== Use of Callcode ==== +==== Use of callcode ==== SWC ID: 111 Severity: Medium Contract: Unknown diff --git a/tests/testdata/outputs_expected/metacoin.sol.o.json b/tests/testdata/outputs_expected/metacoin.sol.o.json index 237b1c1e..712f50c1 100644 --- a/tests/testdata/outputs_expected/metacoin.sol.o.json +++ b/tests/testdata/outputs_expected/metacoin.sol.o.json @@ -1 +1,5 @@ -{"error": null, "issues": [], "success": true} \ No newline at end of file +{ + "error": null, + "issues": [], + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 b/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 index c1512195..5e1c5ee1 100644 --- a/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 @@ -1 +1,7 @@ -{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": [], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "issues": [], + "meta": {}, + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": [], + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.json b/tests/testdata/outputs_expected/multi_contracts.sol.o.json index 8153bf38..a446616c 100644 --- a/tests/testdata/outputs_expected/multi_contracts.sol.o.json +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.json @@ -1 +1,19 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 142, "contract": "Unknown", "debug": "", "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, "min_gas_used": 186, "severity": "High", "swc-id": "105", "title": "Unprotected Ether Withdrawal"}], "success": true} \ No newline at end of file +{ + "success": true, + "issues": [ + { + "min_gas_used": 186, + "contract": "Unknown", + "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.", + "SourceMap": null, + "max_gas_used": 467, + "function": "transfer()", + "title": "Unprotected Ether Withdrawal", + "address": 142, + "debug": "", + "severity": "High", + "swc-id": "105" + } + ], + "error": null +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 b/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 index c3c890ba..afd053dd 100644 --- a/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 @@ -1 +1,29 @@ -{"issues": [{"description": {"head": ["Anyone can withdraw ETH from the contract account."], "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": {}, "locations": [{"sourceMap": "142:1:0"}], "severity": "High", "swcID": "105", "swcTitle": "Unprotected Ether Withdrawal"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xbc9c3d9db56d20cf4ca3b6fd88ff9215cf728a092cca1ed8edb83272b933ff5b"], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "sourceFormat": "evm-byzantium-bytecode", + "issues": [ + { + "locations": [ + { + "sourceMap": "142:1:0" + } + ], + "swcID": "105", + "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." + ], + "head": [ + "Anyone can withdraw ETH from the contract account." + ] + }, + "extra": {}, + "severity": "High", + "swcTitle": "Unprotected Ether Withdrawal" + } + ], + "sourceList": [ + "0xbc9c3d9db56d20cf4ca3b6fd88ff9215cf728a092cca1ed8edb83272b933ff5b" + ], + "meta": {}, + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/nonascii.sol.o.json b/tests/testdata/outputs_expected/nonascii.sol.o.json index 237b1c1e..712f50c1 100644 --- a/tests/testdata/outputs_expected/nonascii.sol.o.json +++ b/tests/testdata/outputs_expected/nonascii.sol.o.json @@ -1 +1,5 @@ -{"error": null, "issues": [], "success": true} \ No newline at end of file +{ + "error": null, + "issues": [], + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 b/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 index c1512195..5e1c5ee1 100644 --- a/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 @@ -1 +1,7 @@ -{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": [], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "issues": [], + "meta": {}, + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": [], + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.json b/tests/testdata/outputs_expected/origin.sol.o.json index 93603018..34f1ce7d 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.json +++ b/tests/testdata/outputs_expected/origin.sol.o.json @@ -1 +1,19 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 317, "contract": "Unknown", "debug": "", "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, "min_gas_used": 626, "severity": "Medium", "swc-id": "111", "title": "Use of tx.origin"}], "success": true} \ No newline at end of file +{ + "error": null, + "issues": [ + { + "SourceMap": null, + "address": 317, + "contract": "Unknown", + "debug": "", + "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, + "min_gas_used": 626, + "severity": "Medium", + "swc-id": "111", + "title": "Use of tx.origin" + } + ], + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.jsonv2 b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 index 8591ceee..ee565925 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 @@ -1 +1,29 @@ -{"issues": [{"description": {"head": ["Use of tx.origin is deprecated."], "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": {}, "locations": [{"sourceMap": "317:1:0"}], "severity": "Medium", "swcID": "111", "swcTitle": "Use of Deprecated Solidity Functions"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x25b20ef097dfc0aa56a932c4e09f06ee02a69c005767df86877f48c6c2412f03"], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "issues": [ + { + "description": { + "head": [ + "Use of tx.origin is deprecated." + ], + "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": {}, + "locations": [ + { + "sourceMap": "317:1:0" + } + ], + "severity": "Medium", + "swcID": "111", + "swcTitle": "Use of Deprecated Solidity Functions" + } + ], + "meta": {}, + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": [ + "0x25b20ef097dfc0aa56a932c4e09f06ee02a69c005767df86877f48c6c2412f03" + ], + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.markdown b/tests/testdata/outputs_expected/origin.sol.o.markdown index cbacdae3..1f5f83ac 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.markdown +++ b/tests/testdata/outputs_expected/origin.sol.o.markdown @@ -11,5 +11,5 @@ ### Description Use of tx.origin is deprecated. -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. +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. See also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin diff --git a/tests/testdata/outputs_expected/origin.sol.o.text b/tests/testdata/outputs_expected/origin.sol.o.text index 5b62a208..b7ebc992 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.text +++ b/tests/testdata/outputs_expected/origin.sol.o.text @@ -6,7 +6,7 @@ Function name: transferOwnership(address) PC address: 317 Estimated Gas Usage: 626 - 1051 Use of tx.origin is deprecated. -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. +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. See also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin -------------------- diff --git a/tests/testdata/outputs_expected/overflow.sol.o.json b/tests/testdata/outputs_expected/overflow.sol.o.json index 1ef38e4d..f928ccdb 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.json +++ b/tests/testdata/outputs_expected/overflow.sol.o.json @@ -1 +1,45 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1053, "min_gas_used": 768, "severity": "High", "swc-id": "101", "title": "Integer Overflow"}, {"SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "swc-id": "101", "title": "Integer Underflow"}, {"SourceMap": null, "address": 649, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "swc-id": "101", "title": "Integer Underflow"}], "success": true} \ No newline at end of file +{ + "error": null, + "success": true, + "issues": [ + { + "severity": "High", + "SourceMap": null, + "title": "Integer Overflow", + "max_gas_used": 1053, + "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", + "swc-id": "101", + "contract": "Unknown", + "function": "sendeth(address,uint256)", + "address": 567, + "min_gas_used": 768, + "debug": "" + }, + { + "debug": "", + "min_gas_used": 1299, + "function": "sendeth(address,uint256)", + "address": 567, + "contract": "Unknown", + "swc-id": "101", + "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", + "max_gas_used": 1774, + "SourceMap": null, + "title": "Integer Underflow", + "severity": "High" + }, + { + "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", + "max_gas_used": 1774, + "title": "Integer Underflow", + "SourceMap": null, + "severity": "High", + "debug": "", + "min_gas_used": 1299, + "address": 649, + "function": "sendeth(address,uint256)", + "contract": "Unknown", + "swc-id": "101" + } + ] +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 index e8016642..6c3666e6 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 @@ -1 +1,67 @@ -{"issues": [{"description": {"head": ["The subtraction can overflow."], "tail": ["The binary subtraction operation can result in an integer overflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xf230bec502569e8b7e7737616d0ad0f200c436624e3c223e5398c0615cd2d6b9"], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "sourceType": "raw-bytecode", + "issues": [ + { + "severity": "High", + "extra": {}, + "swcID": "101", + "swcTitle": "Integer Overflow and Underflow", + "locations": [ + { + "sourceMap": "567:1:0" + } + ], + "description": { + "tail": [ + "The binary subtraction operation can result in an integer overflow.\n" + ], + "head": [ + "The subtraction can overflow." + ] + } + }, + { + "description": { + "head": [ + "The subtraction can underflow." + ], + "tail": [ + "The binary subtraction operation can result in an integer underflow.\n" + ] + }, + "swcTitle": "Integer Overflow and Underflow", + "locations": [ + { + "sourceMap": "567:1:0" + } + ], + "severity": "High", + "extra": {}, + "swcID": "101" + }, + { + "extra": {}, + "swcID": "101", + "severity": "High", + "locations": [ + { + "sourceMap": "649:1:0" + } + ], + "swcTitle": "Integer Overflow and Underflow", + "description": { + "tail": [ + "The binary subtraction operation can result in an integer underflow.\n" + ], + "head": [ + "The subtraction can underflow." + ] + } + } + ], + "sourceList": [ + "0xf230bec502569e8b7e7737616d0ad0f200c436624e3c223e5398c0615cd2d6b9" + ], + "sourceFormat": "evm-byzantium-bytecode", + "meta": {} +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.json b/tests/testdata/outputs_expected/returnvalue.sol.o.json index ebe87f67..7c866dd1 100644 --- a/tests/testdata/outputs_expected/returnvalue.sol.o.json +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.json @@ -1 +1,45 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 196, "contract": "Unknown", "debug": "", "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, "min_gas_used": 599, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 285, "contract": "Unknown", "debug": "", "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, "min_gas_used": 621, "severity": "Low", "swc-id": "107", "title": "External Call To Fixed Address"}, {"SourceMap": null, "address": 285, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1339, "severity": "Low", "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file +{ + "error": null, + "issues": [ + { + "SourceMap": null, + "address": 196, + "contract": "Unknown", + "debug": "", + "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, + "min_gas_used": 599, + "severity": "Low", + "swc-id": "107", + "title": "External Call To Fixed Address" + }, + { + "SourceMap": null, + "address": 285, + "contract": "Unknown", + "debug": "", + "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, + "min_gas_used": 621, + "severity": "Low", + "swc-id": "107", + "title": "External Call To Fixed Address" + }, + { + "SourceMap": null, + "address": 285, + "contract": "Unknown", + "debug": "", + "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, + "min_gas_used": 1339, + "severity": "Low", + "swc-id": "104", + "title": "Unchecked Call Return Value" + } + ], + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 b/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 index 5a0d1908..46a05f26 100644 --- a/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 @@ -1 +1,67 @@ -{"issues": [{"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "196:1:0"}], "severity": "Low", "swcID": "107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "285:1:0"}], "severity": "Low", "swcID": "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": {}, "locations": [{"sourceMap": "285:1:0"}], "severity": "Low", "swcID": "104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xb191cf6cc0d8cc37a91c9d88019cc011b932169fb5776df616e2bb9cd93b4039"], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "issues": [ + { + "description": { + "head": [ + "The contract executes an external message call." + ], + "tail": [ + "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." + ] + }, + "extra": {}, + "locations": [ + { + "sourceMap": "196:1:0" + } + ], + "severity": "Low", + "swcID": "107", + "swcTitle": "Reentrancy" + }, + { + "description": { + "head": [ + "The contract executes an external message call." + ], + "tail": [ + "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." + ] + }, + "extra": {}, + "locations": [ + { + "sourceMap": "285:1:0" + } + ], + "severity": "Low", + "swcID": "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": {}, + "locations": [ + { + "sourceMap": "285:1:0" + } + ], + "severity": "Low", + "swcID": "104", + "swcTitle": "Unchecked Call Return Value" + } + ], + "meta": {}, + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": [ + "0xb191cf6cc0d8cc37a91c9d88019cc011b932169fb5776df616e2bb9cd93b4039" + ], + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/rubixi.sol.o.json b/tests/testdata/outputs_expected/rubixi.sol.o.json index bac935c7..d328ade0 100644 --- a/tests/testdata/outputs_expected/rubixi.sol.o.json +++ b/tests/testdata/outputs_expected/rubixi.sol.o.json @@ -8,7 +8,7 @@ "function": "_function_0x4229616d", "type": "Warning", "address": 1599, - "debug": "", + "debug": "" }, { "title": "Ether send", @@ -16,7 +16,7 @@ "function": "_function_0xb4022950", "type": "Warning", "address": 1940, - "debug": "", + "debug": "" }, { "title": "Ether send", @@ -24,7 +24,7 @@ "function": "_function_0xb4022950", "type": "Warning", "address": 2582, - "debug": "", + "debug": "" }, { "title": "Exception state", @@ -32,7 +32,7 @@ "function": "_function_0x57d4021b", "type": "Informational", "address": 1653, - "debug": "", + "debug": "" }, { "title": "Exception state", @@ -40,7 +40,7 @@ "function": "_function_0x9dbc4f9b", "type": "Informational", "address": 2085, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -48,7 +48,7 @@ "function": "fallback", "type": "Informational", "address": 3111, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -56,7 +56,7 @@ "function": "fallback", "type": "Informational", "address": 3140, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -64,7 +64,7 @@ "function": "fallback", "type": "Informational", "address": 2950, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -72,7 +72,7 @@ "function": "fallback", "type": "Informational", "address": 1268, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -80,7 +80,7 @@ "function": "_function_0x09dfdc71", "type": "Informational", "address": 310, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -88,7 +88,7 @@ "function": "_function_0x09dfdc71", "type": "Informational", "address": 1316, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -96,7 +96,7 @@ "function": "_function_0x253459e3", "type": "Informational", "address": 1375, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -104,7 +104,7 @@ "function": "_function_0x4229616d", "type": "Informational", "address": 1511, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -112,7 +112,7 @@ "function": "_function_0x57d4021b", "type": "Informational", "address": 1679, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -120,7 +120,7 @@ "function": "_function_0x6fbaaa1e", "type": "Informational", "address": 618, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -128,7 +128,7 @@ "function": "_function_0x8a5fb3ca", "type": "Informational", "address": 805, - "debug": "", + "debug": "" }, { "title": "Invariant branch condition", @@ -136,7 +136,7 @@ "function": "_function_0x9dbc4f9b", "type": "Informational", "address": 2187, - "debug": "", + "debug": "" }, { "title": "Unchecked CALL return value", @@ -144,7 +144,7 @@ "function": "_function_0x4229616d", "type": "Informational", "address": 1599, - "debug": "", + "debug": "" }, { "title": "Unchecked CALL return value", @@ -152,7 +152,7 @@ "function": "_function_0xb4022950", "type": "Informational", "address": 1940, - "debug": "", + "debug": "" }, { "title": "Unchecked CALL return value", @@ -160,7 +160,7 @@ "function": "_function_0xb4022950", "type": "Informational", "address": 2582, - "debug": "", - }, - ], -} + "debug": "" + } + ] +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/suicide.sol.o.json b/tests/testdata/outputs_expected/suicide.sol.o.json index a2a1e640..d13cac2b 100644 --- a/tests/testdata/outputs_expected/suicide.sol.o.json +++ b/tests/testdata/outputs_expected/suicide.sol.o.json @@ -1 +1,19 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 146, "contract": "Unknown", "debug": "", "description": "The contract can be killed by anyone.\nArbitrary senders can kill this contract and withdraw its balance to their own account.", "function": "kill(address)", "max_gas_used": 263, "min_gas_used": 168, "severity": "High", "swc-id": "106", "title": "Unprotected Selfdestruct"}], "success": true} \ No newline at end of file +{ + "error": null, + "issues": [ + { + "SourceMap": null, + "address": 146, + "contract": "Unknown", + "debug": "", + "description": "The contract can be killed by anyone.\nArbitrary senders can kill this contract and withdraw its balance to their own account.", + "function": "kill(address)", + "max_gas_used": 263, + "min_gas_used": 168, + "severity": "High", + "swc-id": "106", + "title": "Unprotected Selfdestruct" + } + ], + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 b/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 index e16aae95..b679fcee 100644 --- a/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 @@ -1 +1,29 @@ -{"issues": [{"description": {"head": ["The contract can be killed by anyone."], "tail": ["Arbitrary senders can kill this contract and withdraw its balance to their own account."]}, "extra": {}, "locations": [{"sourceMap": "146:1:0"}], "severity": "High", "swcID": "106", "swcTitle": "Unprotected SELFDESTRUCT Instruction"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x2fb801366b61a05b30550481a1c8f7d5f20de0b93d9f2f2ce2b28c4e322033c9"], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "issues": [ + { + "description": { + "head": [ + "The contract can be killed by anyone." + ], + "tail": [ + "Arbitrary senders can kill this contract and withdraw its balance to their own account." + ] + }, + "extra": {}, + "locations": [ + { + "sourceMap": "146:1:0" + } + ], + "severity": "High", + "swcID": "106", + "swcTitle": "Unprotected SELFDESTRUCT Instruction" + } + ], + "meta": {}, + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": [ + "0x2fb801366b61a05b30550481a1c8f7d5f20de0b93d9f2f2ce2b28c4e322033c9" + ], + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.json b/tests/testdata/outputs_expected/underflow.sol.o.json index 1ef38e4d..ed13ac20 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.json +++ b/tests/testdata/outputs_expected/underflow.sol.o.json @@ -1 +1,45 @@ -{"error": null, "issues": [{"SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1053, "min_gas_used": 768, "severity": "High", "swc-id": "101", "title": "Integer Overflow"}, {"SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "swc-id": "101", "title": "Integer Underflow"}, {"SourceMap": null, "address": 649, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "swc-id": "101", "title": "Integer Underflow"}], "success": true} \ No newline at end of file +{ + "error": null, + "issues": [ + { + "SourceMap": null, + "address": 567, + "contract": "Unknown", + "debug": "", + "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", + "function": "sendeth(address,uint256)", + "max_gas_used": 1053, + "min_gas_used": 768, + "severity": "High", + "swc-id": "101", + "title": "Integer Overflow" + }, + { + "SourceMap": null, + "address": 567, + "contract": "Unknown", + "debug": "", + "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", + "function": "sendeth(address,uint256)", + "max_gas_used": 1774, + "min_gas_used": 1299, + "severity": "High", + "swc-id": "101", + "title": "Integer Underflow" + }, + { + "SourceMap": null, + "address": 649, + "contract": "Unknown", + "debug": "", + "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", + "function": "sendeth(address,uint256)", + "max_gas_used": 1774, + "min_gas_used": 1299, + "severity": "High", + "swc-id": "101", + "title": "Integer Underflow" + } + ], + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 index 7e354795..25ea93c3 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 @@ -1 +1,67 @@ -{"issues": [{"description": {"head": ["The subtraction can overflow."], "tail": ["The binary subtraction operation can result in an integer overflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xabef56740bf7795a9f8732e4781ebd27f2977f8a4997e3ff11cee79a4ba6c0ce"], "sourceType": "raw-bytecode"} \ No newline at end of file +{ + "issues": [ + { + "description": { + "head": [ + "The subtraction can overflow." + ], + "tail": [ + "The binary subtraction operation can result in an integer overflow.\n" + ] + }, + "extra": {}, + "locations": [ + { + "sourceMap": "567:1:0" + } + ], + "severity": "High", + "swcID": "101", + "swcTitle": "Integer Overflow and Underflow" + }, + { + "description": { + "head": [ + "The subtraction can underflow." + ], + "tail": [ + "The binary subtraction operation can result in an integer underflow.\n" + ] + }, + "extra": {}, + "locations": [ + { + "sourceMap": "567:1:0" + } + ], + "severity": "High", + "swcID": "101", + "swcTitle": "Integer Overflow and Underflow" + }, + { + "description": { + "head": [ + "The subtraction can underflow." + ], + "tail": [ + "The binary subtraction operation can result in an integer underflow.\n" + ] + }, + "extra": {}, + "locations": [ + { + "sourceMap": "649:1:0" + } + ], + "severity": "High", + "swcID": "101", + "swcTitle": "Integer Overflow and Underflow" + } + ], + "meta": {}, + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": [ + "0xabef56740bf7795a9f8732e4781ebd27f2977f8a4997e3ff11cee79a4ba6c0ce" + ], + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/weak_random.sol.o.json b/tests/testdata/outputs_expected/weak_random.sol.o.json index 681f8544..2338b178 100644 --- a/tests/testdata/outputs_expected/weak_random.sol.o.json +++ b/tests/testdata/outputs_expected/weak_random.sol.o.json @@ -8,7 +8,7 @@ "function": "_function_0xe9874106", "type": "Warning", "address": 1285, - "debug": "", + "debug": "" }, { "title": "Ether send", @@ -16,7 +16,7 @@ "function": "_function_0xe9874106", "type": "Warning", "address": 1285, - "debug": "", + "debug": "" }, { "title": "Exception state", @@ -24,7 +24,7 @@ "function": "fallback", "type": "Informational", "address": 356, - "debug": "", + "debug": "" }, { "title": "Exception state", @@ -32,7 +32,7 @@ "function": "_function_0xe9874106", "type": "Informational", "address": 146, - "debug": "", + "debug": "" }, { "title": "Transaction order dependence", @@ -40,7 +40,7 @@ "function": "_function_0xe9874106", "type": "Warning", "address": 1285, - "debug": "", - }, - ], -} + "debug": "" + } + ] +} \ No newline at end of file From d6a5e892969d658e0ca09e23c465991074a970b3 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Tue, 1 Jan 2019 11:19:47 +0700 Subject: [PATCH 25/56] Apply the necessary black formatting --- mythril/analysis/modules/dependence_on_predictable_vars.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mythril/analysis/modules/dependence_on_predictable_vars.py b/mythril/analysis/modules/dependence_on_predictable_vars.py index 5807dad0..a9e17a5f 100644 --- a/mythril/analysis/modules/dependence_on_predictable_vars.py +++ b/mythril/analysis/modules/dependence_on_predictable_vars.py @@ -166,7 +166,9 @@ def _analyze_states(state: GlobalState) -> list: if index and solve(call): description = ( "A block hash is calculated using the block.blockhash(uint blockNumber) method. " - "The block number is obtained from storage index {}".format(index) + "The block number is obtained from storage index {}".format( + index + ) ) issue = Issue( contract=call.node.contract_name, From 811098043d4c4468e06327c7567956edd63cd1df Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Tue, 1 Jan 2019 12:14:12 +0700 Subject: [PATCH 26/56] Intialize source object __init__ method --- mythril/analysis/report.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 65d0d90a..db8b53c8 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -99,14 +99,20 @@ class Report: loader=PackageLoader("mythril.analysis"), trim_blocks=True ) - def __init__(self, verbose=False, source=Source()): + def __init__(self, verbose=False, source=None): self.issues = {} self.verbose = verbose self.solc_version = "" - self.source_type = source.source_type - self.source_format = source.source_format - self.source_list = source.source_list - self.meta = source.meta + self.meta = {} + + if source is not None: + self.source = source + else: + self.source = Source() + + self.source_type = self.source.source_type + self.source_format = self.source.source_format + self.source_list = self.source.source_list def sorted_issues(self): issue_list = [issue.as_dict for key, issue in self.issues.items()] From b2155e167b559367bc24ba614f51360793951f12 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Tue, 1 Jan 2019 12:16:50 +0700 Subject: [PATCH 27/56] Remove meta from source class (belongs to issue not source) --- mythril/support/source_support.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mythril/support/source_support.py b/mythril/support/source_support.py index dbdccdd8..1fd18508 100644 --- a/mythril/support/source_support.py +++ b/mythril/support/source_support.py @@ -29,4 +29,3 @@ class Source: else: assert False # Fail hard - self.meta = "" From 1ae517e0f0d6d096e8ce56baaed8289b95f90ca5 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Tue, 1 Jan 2019 12:23:35 +0700 Subject: [PATCH 28/56] Add new SWC ids --- mythril/analysis/swc_data.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mythril/analysis/swc_data.py b/mythril/analysis/swc_data.py index cb114054..12ef1d3e 100644 --- a/mythril/analysis/swc_data.py +++ b/mythril/analysis/swc_data.py @@ -20,6 +20,12 @@ SHADOWING_STATE_VARIABLES = "119" WEAK_RANDOMNESS = "120" SIGNATURE_REPLAY = "121" IMPROPER_VERIFICATION_BASED_ON_MSG_SENDER = "122" +REQUIREMENT_VIOLATION = "123" +WRITE_TO__RBIRARY_STORAGE = "124" +INCORRECT_INHERITANCE_ORDER = "125" +ARBITRARY_JUMP = "127" +DOS_WITH_BLOCK_GAS_LIMIT = "128" +TYPOGRAPHICAL_ERROR = "129" PREDICTABLE_VARS_DEPENDENCE = ( "N/A" @@ -49,4 +55,10 @@ SWC_TO_TITLE = { "120": "Weak Sources of Randomness from Chain Attributes", "121": "Missing Protection against Signature Replay Attacks", "122": "Lack of Proper Signature Verification", + "123": "Requirement Violation", + "124": "Write to Arbitrary Storage Location", + "125": "Incorrect Inheritance Order", + "127": "Arbitrary Jump with Function Type Variable", + "128": "DoS With Block Gas Limit", + "129": "Typographical Error", } From c6fd36de38cf081776518abb138f16b4378b0fb5 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Tue, 1 Jan 2019 18:11:25 +0530 Subject: [PATCH 29/56] Correct typo in swc title and remove PREDICTABLE_VARS variable --- mythril/analysis/swc_data.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mythril/analysis/swc_data.py b/mythril/analysis/swc_data.py index 12ef1d3e..1996be20 100644 --- a/mythril/analysis/swc_data.py +++ b/mythril/analysis/swc_data.py @@ -21,15 +21,12 @@ WEAK_RANDOMNESS = "120" SIGNATURE_REPLAY = "121" IMPROPER_VERIFICATION_BASED_ON_MSG_SENDER = "122" REQUIREMENT_VIOLATION = "123" -WRITE_TO__RBIRARY_STORAGE = "124" +WRITE_TO_ARBITRARY_STORAGE = "124" INCORRECT_INHERITANCE_ORDER = "125" ARBITRARY_JUMP = "127" DOS_WITH_BLOCK_GAS_LIMIT = "128" TYPOGRAPHICAL_ERROR = "129" -PREDICTABLE_VARS_DEPENDENCE = ( - "N/A" -) # TODO: Add the swc id when this is added to the SWC Registry SWC_TO_TITLE = { "100": "Function Default Visibility", From ecc0a7ab4792c1adfd0fcdfac208697aac1bd833 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Wed, 2 Jan 2019 22:06:59 +0530 Subject: [PATCH 30/56] Cache the integer overflows for sstores --- mythril/analysis/modules/integer.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index c59e9982..3076b883 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -42,6 +42,8 @@ class IntegerOverflowUnderflowModule(DetectionModule): entrypoint="callback", pre_hooks=["ADD", "MUL", "SUB", "SSTORE", "JUMPI"], ) + self.overflow_cache = {} + self.underflow_cache = {} self._issues = [] @property @@ -49,11 +51,14 @@ class IntegerOverflowUnderflowModule(DetectionModule): return self._issues def execute(self, state: GlobalState): - if state.get_current_instruction()["opcode"] == "ADD": + address = state.get_current_instruction()["address"] + has_overflow = self.overflow_cache.get(address, False) + has_underflow = self.underflow_cache.get(address, False) + if state.get_current_instruction()["opcode"] == "ADD" and not has_overflow: self._handle_add(state) - elif state.get_current_instruction()["opcode"] == "MUL": + elif state.get_current_instruction()["opcode"] == "MUL" and not has_overflow: self._handle_mul(state) - elif state.get_current_instruction()["opcode"] == "SUB": + elif state.get_current_instruction()["opcode"] == "SUB" and not has_underflow: self._handle_sub(state) elif state.get_current_instruction()["opcode"] == "SSTORE": self._handle_sstore(state) @@ -149,6 +154,17 @@ class IntegerOverflowUnderflowModule(DetectionModule): issue.description = "This binary {} operation can result in {}.\n".format( annotation.operator, title.lower() ) + address = ostate.get_current_instruction()["address"] + + if annotation.operator == "subtraction" and self.underflow_cache.get( + address, False + ): + return + if annotation.operator != "subtraction" and self.overflow_cache.get( + address, False + ): + return + try: issue.debug = str( solver.get_transaction_sequence( @@ -157,6 +173,11 @@ class IntegerOverflowUnderflowModule(DetectionModule): ) except UnsatError: return + if annotation.operator == "subtraction": + self.underflow_cache[address] = True + else: + self.overflow_cache[address] = True + self._issues.append(issue) def _handle_jumpi(self, state): From 813cb066f216e6df9c875c596fbebd089409bf06 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Thu, 3 Jan 2019 02:19:56 +0530 Subject: [PATCH 31/56] Add cache for jumpi in integer module --- mythril/analysis/modules/integer.py | 18 ++++++++++++++++++ mythril/analysis/security.py | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 3076b883..5b5897ce 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -54,6 +54,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): address = state.get_current_instruction()["address"] has_overflow = self.overflow_cache.get(address, False) has_underflow = self.underflow_cache.get(address, False) + if state.get_current_instruction()["opcode"] == "ADD" and not has_overflow: self._handle_add(state) elif state.get_current_instruction()["opcode"] == "MUL" and not has_overflow: @@ -203,6 +204,17 @@ class IntegerOverflowUnderflowModule(DetectionModule): issue.description = "This binary {} operation can result in integer overflow.\n".format( annotation.operator ) + address = ostate.get_current_instruction()["address"] + + if annotation.operator == "subtraction" and self.underflow_cache.get( + address, False + ): + return + if annotation.operator != "subtraction" and self.overflow_cache.get( + address, False + ): + return + try: issue.debug = str( solver.get_transaction_sequence( @@ -211,6 +223,12 @@ class IntegerOverflowUnderflowModule(DetectionModule): ) except UnsatError: return + + if annotation.operator == "subtraction": + self.underflow_cache[address] = True + else: + self.overflow_cache[address] = True + self._issues.append(issue) @staticmethod diff --git a/mythril/analysis/security.py b/mythril/analysis/security.py index 25a4341f..96aef79a 100644 --- a/mythril/analysis/security.py +++ b/mythril/analysis/security.py @@ -1,3 +1,4 @@ +from mythril.analysis.modules.integer import IntegerOverflowUnderflowModule from collections import defaultdict from ethereum.opcodes import opcodes from mythril.analysis import modules @@ -14,6 +15,9 @@ def reset_callback_modules(): modules = get_detection_modules("callback") for module in modules: module.detector._issues = [] + if isinstance(module.detector, IntegerOverflowUnderflowModule): + module.detector.overflow_cache = {} + module.detector.underflow_cache = {} def get_detection_module_hooks(modules, hook_type="pre"): From 76bbb9771a3a22803dc76f2bb543a216cbfcef4a Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 3 Jan 2019 21:36:59 +0700 Subject: [PATCH 32/56] Update formatting of swcID field --- mythril/analysis/report.py | 2 +- .../outputs_expected/calls.sol.o.jsonv2 | 163 +----------------- .../outputs_expected/ether_send.sol.o.jsonv2 | 8 +- .../outputs_expected/exceptions.sol.o.jsonv2 | 87 +--------- .../kinds_of_calls.sol.o.jsonv2 | 106 +----------- .../outputs_expected/metacoin.sol.o.jsonv2 | 8 +- .../multi_contracts.sol.o.jsonv2 | 30 +--- .../outputs_expected/nonascii.sol.o.jsonv2 | 8 +- .../outputs_expected/origin.sol.o.jsonv2 | 30 +--- .../outputs_expected/overflow.sol.o.jsonv2 | 68 +------- .../outputs_expected/returnvalue.sol.o.jsonv2 | 68 +------- .../outputs_expected/suicide.sol.o.jsonv2 | 30 +--- .../outputs_expected/underflow.sol.o.jsonv2 | 68 +------- 13 files changed, 13 insertions(+), 663 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index db8b53c8..81492cb1 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -155,7 +155,7 @@ class Report: _issues.append( { - "swcID": issue.swc_id, + "swcID": "SWC-" + issue.swc_id, "swcTitle": title, "description": { "head": issue.description_head, diff --git a/tests/testdata/outputs_expected/calls.sol.o.jsonv2 b/tests/testdata/outputs_expected/calls.sol.o.jsonv2 index 580400f4..cdd59a54 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/calls.sol.o.jsonv2 @@ -1,162 +1 @@ -{ - "sourceFormat": "evm-byzantium-bytecode", - "issues": [ - { - "locations": [ - { - "sourceMap": "661:1:0" - } - ], - "description": { - "tail": [ - "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." - ], - "head": [ - "The contract executes an external message call." - ] - }, - "severity": "Low", - "swcID": "107", - "extra": {}, - "swcTitle": "Reentrancy" - }, - { - "swcID": "107", - "extra": {}, - "swcTitle": "Reentrancy", - "locations": [ - { - "sourceMap": "779:1:0" - } - ], - "description": { - "tail": [ - "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." - ], - "head": [ - "The contract executes an external message call." - ] - }, - "severity": "Low" - }, - { - "swcID": "107", - "extra": {}, - "swcTitle": "Reentrancy", - "locations": [ - { - "sourceMap": "858:1:0" - } - ], - "description": { - "head": [ - "The contract executes an external message call." - ], - "tail": [ - "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." - ] - }, - "severity": "Low" - }, - { - "swcTitle": "Reentrancy", - "extra": {}, - "swcID": "107", - "severity": "Medium", - "description": { - "head": [ - "A call to a user-supplied address is executed." - ], - "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 thecontract state." - ] - }, - "locations": [ - { - "sourceMap": "912:1:0" - } - ] - }, - { - "swcTitle": "Unchecked Call Return Value", - "extra": {}, - "swcID": "104", - "severity": "Low", - "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." - ] - }, - "locations": [ - { - "sourceMap": "661:1:0" - } - ] - }, - { - "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." - ] - }, - "severity": "Low", - "locations": [ - { - "sourceMap": "779:1:0" - } - ], - "swcTitle": "Unchecked Call Return Value", - "swcID": "104", - "extra": {} - }, - { - "locations": [ - { - "sourceMap": "858:1:0" - } - ], - "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." - ] - }, - "severity": "Low", - "swcID": "104", - "extra": {}, - "swcTitle": "Unchecked Call Return Value" - }, - { - "severity": "Low", - "description": { - "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." - ], - "head": [ - "The return value of a message call is not checked." - ] - }, - "locations": [ - { - "sourceMap": "912:1:0" - } - ], - "swcTitle": "Unchecked Call Return Value", - "extra": {}, - "swcID": "104" - } - ], - "sourceType": "raw-bytecode", - "sourceList": [ - "0x7cbb77986c6b1bf6e945cd3fba06d3ea3d28cfc49cdfdc9571ec30703ac5862f" - ], - "meta": {} -} \ No newline at end of file +{"issues": [{"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Medium", "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": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x7cbb77986c6b1bf6e945cd3fba06d3ea3d28cfc49cdfdc9571ec30703ac5862f"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 b/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 index 5e1c5ee1..c1512195 100644 --- a/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 @@ -1,7 +1 @@ -{ - "issues": [], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [], - "sourceType": "raw-bytecode" -} \ No newline at end of file +{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": [], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 b/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 index e6b6849e..21c65a1c 100644 --- a/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 @@ -1,86 +1 @@ -{ - "meta": {}, - "issues": [ - { - "swcTitle": "Assert Violation", - "swcID": "110", - "description": { - "head": [ - "A reachable exception has been detected." - ], - "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." - ] - }, - "locations": [ - { - "sourceMap": "446:1:0" - } - ], - "extra": {}, - "severity": "Low" - }, - { - "severity": "Low", - "extra": {}, - "locations": [ - { - "sourceMap": "484:1:0" - } - ], - "swcID": "110", - "swcTitle": "Assert Violation", - "description": { - "head": [ - "A reachable exception has been detected." - ], - "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." - ] - } - }, - { - "swcTitle": "Assert Violation", - "swcID": "110", - "description": { - "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." - ], - "head": [ - "A reachable exception has been detected." - ] - }, - "locations": [ - { - "sourceMap": "506:1:0" - } - ], - "extra": {}, - "severity": "Low" - }, - { - "description": { - "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." - ], - "head": [ - "A reachable exception has been detected." - ] - }, - "swcTitle": "Assert Violation", - "swcID": "110", - "extra": {}, - "locations": [ - { - "sourceMap": "531:1:0" - } - ], - "severity": "Low" - } - ], - "sourceList": [ - "0x4a773a86bc6fb269f88bf09bb3094de29b6073cf13b1760e9d01d957f50a9dfd" - ], - "sourceFormat": "evm-byzantium-bytecode", - "sourceType": "raw-bytecode" -} \ No newline at end of file +{"issues": [{"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "446:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "484:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "506:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "531:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x4a773a86bc6fb269f88bf09bb3094de29b6073cf13b1760e9d01d957f50a9dfd"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 index f22d7019..e63c0c07 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 @@ -1,105 +1 @@ -{ - "issues": [ - { - "swcTitle": "Use of Deprecated Solidity Functions", - "swcID": "111", - "extra": {}, - "severity": "Medium", - "description": { - "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." - ], - "head": [ - "Use of callcode is deprecated." - ] - }, - "locations": [ - { - "sourceMap": "618:1:0" - } - ] - }, - { - "severity": "Medium", - "locations": [ - { - "sourceMap": "1038:1:0" - } - ], - "description": { - "head": [ - "A call to a user-supplied address is executed." - ], - "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 thecontract state." - ] - }, - "extra": {}, - "swcTitle": "Reentrancy", - "swcID": "107" - }, - { - "swcTitle": "Unchecked Call Return Value", - "swcID": "104", - "extra": {}, - "severity": "Low", - "description": { - "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." - ], - "head": [ - "The return value of a message call is not checked." - ] - }, - "locations": [ - { - "sourceMap": "618:1:0" - } - ] - }, - { - "extra": {}, - "severity": "Low", - "locations": [ - { - "sourceMap": "849:1:0" - } - ], - "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." - ] - }, - "swcTitle": "Unchecked Call Return Value", - "swcID": "104" - }, - { - "swcID": "104", - "swcTitle": "Unchecked Call Return Value", - "locations": [ - { - "sourceMap": "1038:1:0" - } - ], - "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." - ] - }, - "severity": "Low", - "extra": {} - } - ], - "sourceList": [ - "0x6daec61d05d8f1210661e7e7d1ed6d72bd6ade639398fac1e867aff50abfc1c1" - ], - "sourceFormat": "evm-byzantium-bytecode", - "sourceType": "raw-bytecode", - "meta": {} -} \ No newline at end of file +{"issues": [{"description": {"head": ["Use of callcode is deprecated."], "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Medium", "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Medium", "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "849:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x6daec61d05d8f1210661e7e7d1ed6d72bd6ade639398fac1e867aff50abfc1c1"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 b/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 index 5e1c5ee1..c1512195 100644 --- a/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 @@ -1,7 +1 @@ -{ - "issues": [], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [], - "sourceType": "raw-bytecode" -} \ No newline at end of file +{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": [], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 b/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 index afd053dd..e4f7dd25 100644 --- a/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 @@ -1,29 +1 @@ -{ - "sourceFormat": "evm-byzantium-bytecode", - "issues": [ - { - "locations": [ - { - "sourceMap": "142:1:0" - } - ], - "swcID": "105", - "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." - ], - "head": [ - "Anyone can withdraw ETH from the contract account." - ] - }, - "extra": {}, - "severity": "High", - "swcTitle": "Unprotected Ether Withdrawal" - } - ], - "sourceList": [ - "0xbc9c3d9db56d20cf4ca3b6fd88ff9215cf728a092cca1ed8edb83272b933ff5b" - ], - "meta": {}, - "sourceType": "raw-bytecode" -} \ No newline at end of file +{"issues": [{"description": {"head": ["Anyone can withdraw ETH from the contract account."], "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": {}, "locations": [{"sourceMap": "142:1:0"}], "severity": "High", "swcID": "SWC-105", "swcTitle": "Unprotected Ether Withdrawal"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xbc9c3d9db56d20cf4ca3b6fd88ff9215cf728a092cca1ed8edb83272b933ff5b"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 b/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 index 5e1c5ee1..c1512195 100644 --- a/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 @@ -1,7 +1 @@ -{ - "issues": [], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [], - "sourceType": "raw-bytecode" -} \ No newline at end of file +{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": [], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.jsonv2 b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 index ee565925..b6848588 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 @@ -1,29 +1 @@ -{ - "issues": [ - { - "description": { - "head": [ - "Use of tx.origin is deprecated." - ], - "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": {}, - "locations": [ - { - "sourceMap": "317:1:0" - } - ], - "severity": "Medium", - "swcID": "111", - "swcTitle": "Use of Deprecated Solidity Functions" - } - ], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [ - "0x25b20ef097dfc0aa56a932c4e09f06ee02a69c005767df86877f48c6c2412f03" - ], - "sourceType": "raw-bytecode" -} \ No newline at end of file +{"issues": [{"description": {"head": ["Use of tx.origin is deprecated."], "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": {}, "locations": [{"sourceMap": "317:1:0"}], "severity": "Medium", "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x25b20ef097dfc0aa56a932c4e09f06ee02a69c005767df86877f48c6c2412f03"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 index 6c3666e6..0aa1a5ba 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 @@ -1,67 +1 @@ -{ - "sourceType": "raw-bytecode", - "issues": [ - { - "severity": "High", - "extra": {}, - "swcID": "101", - "swcTitle": "Integer Overflow and Underflow", - "locations": [ - { - "sourceMap": "567:1:0" - } - ], - "description": { - "tail": [ - "The binary subtraction operation can result in an integer overflow.\n" - ], - "head": [ - "The subtraction can overflow." - ] - } - }, - { - "description": { - "head": [ - "The subtraction can underflow." - ], - "tail": [ - "The binary subtraction operation can result in an integer underflow.\n" - ] - }, - "swcTitle": "Integer Overflow and Underflow", - "locations": [ - { - "sourceMap": "567:1:0" - } - ], - "severity": "High", - "extra": {}, - "swcID": "101" - }, - { - "extra": {}, - "swcID": "101", - "severity": "High", - "locations": [ - { - "sourceMap": "649:1:0" - } - ], - "swcTitle": "Integer Overflow and Underflow", - "description": { - "tail": [ - "The binary subtraction operation can result in an integer underflow.\n" - ], - "head": [ - "The subtraction can underflow." - ] - } - } - ], - "sourceList": [ - "0xf230bec502569e8b7e7737616d0ad0f200c436624e3c223e5398c0615cd2d6b9" - ], - "sourceFormat": "evm-byzantium-bytecode", - "meta": {} -} \ No newline at end of file +{"issues": [{"description": {"head": ["The subtraction can overflow."], "tail": ["The binary subtraction operation can result in an integer overflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xf230bec502569e8b7e7737616d0ad0f200c436624e3c223e5398c0615cd2d6b9"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 b/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 index 46a05f26..66dd3b5e 100644 --- a/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 @@ -1,67 +1 @@ -{ - "issues": [ - { - "description": { - "head": [ - "The contract executes an external message call." - ], - "tail": [ - "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." - ] - }, - "extra": {}, - "locations": [ - { - "sourceMap": "196:1:0" - } - ], - "severity": "Low", - "swcID": "107", - "swcTitle": "Reentrancy" - }, - { - "description": { - "head": [ - "The contract executes an external message call." - ], - "tail": [ - "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully." - ] - }, - "extra": {}, - "locations": [ - { - "sourceMap": "285:1:0" - } - ], - "severity": "Low", - "swcID": "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": {}, - "locations": [ - { - "sourceMap": "285:1:0" - } - ], - "severity": "Low", - "swcID": "104", - "swcTitle": "Unchecked Call Return Value" - } - ], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [ - "0xb191cf6cc0d8cc37a91c9d88019cc011b932169fb5776df616e2bb9cd93b4039" - ], - "sourceType": "raw-bytecode" -} \ No newline at end of file +{"issues": [{"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "196:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "285: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": {}, "locations": [{"sourceMap": "285:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xb191cf6cc0d8cc37a91c9d88019cc011b932169fb5776df616e2bb9cd93b4039"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 b/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 index b679fcee..324cdf44 100644 --- a/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 @@ -1,29 +1 @@ -{ - "issues": [ - { - "description": { - "head": [ - "The contract can be killed by anyone." - ], - "tail": [ - "Arbitrary senders can kill this contract and withdraw its balance to their own account." - ] - }, - "extra": {}, - "locations": [ - { - "sourceMap": "146:1:0" - } - ], - "severity": "High", - "swcID": "106", - "swcTitle": "Unprotected SELFDESTRUCT Instruction" - } - ], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [ - "0x2fb801366b61a05b30550481a1c8f7d5f20de0b93d9f2f2ce2b28c4e322033c9" - ], - "sourceType": "raw-bytecode" -} \ No newline at end of file +{"issues": [{"description": {"head": ["The contract can be killed by anyone."], "tail": ["Arbitrary senders can kill this contract and withdraw its balance to their own account."]}, "extra": {}, "locations": [{"sourceMap": "146:1:0"}], "severity": "High", "swcID": "SWC-106", "swcTitle": "Unprotected SELFDESTRUCT Instruction"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x2fb801366b61a05b30550481a1c8f7d5f20de0b93d9f2f2ce2b28c4e322033c9"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 index 25ea93c3..afb1bd36 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 @@ -1,67 +1 @@ -{ - "issues": [ - { - "description": { - "head": [ - "The subtraction can overflow." - ], - "tail": [ - "The binary subtraction operation can result in an integer overflow.\n" - ] - }, - "extra": {}, - "locations": [ - { - "sourceMap": "567:1:0" - } - ], - "severity": "High", - "swcID": "101", - "swcTitle": "Integer Overflow and Underflow" - }, - { - "description": { - "head": [ - "The subtraction can underflow." - ], - "tail": [ - "The binary subtraction operation can result in an integer underflow.\n" - ] - }, - "extra": {}, - "locations": [ - { - "sourceMap": "567:1:0" - } - ], - "severity": "High", - "swcID": "101", - "swcTitle": "Integer Overflow and Underflow" - }, - { - "description": { - "head": [ - "The subtraction can underflow." - ], - "tail": [ - "The binary subtraction operation can result in an integer underflow.\n" - ] - }, - "extra": {}, - "locations": [ - { - "sourceMap": "649:1:0" - } - ], - "severity": "High", - "swcID": "101", - "swcTitle": "Integer Overflow and Underflow" - } - ], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [ - "0xabef56740bf7795a9f8732e4781ebd27f2977f8a4997e3ff11cee79a4ba6c0ce" - ], - "sourceType": "raw-bytecode" -} \ No newline at end of file +{"issues": [{"description": {"head": ["The subtraction can overflow."], "tail": ["The binary subtraction operation can result in an integer overflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xabef56740bf7795a9f8732e4781ebd27f2977f8a4997e3ff11cee79a4ba6c0ce"], "sourceType": "raw-bytecode"} \ No newline at end of file From b4eabf032e1cddd98a2b4a0f15a5b7484a139e24 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Thu, 3 Jan 2019 21:54:04 +0700 Subject: [PATCH 33/56] Fix a couple of things --- mythril/analysis/modules/multiple_sends.py | 8 +- mythril/analysis/report.py | 6 +- .../outputs_expected/calls.sol.o.json | 111 +----------------- .../outputs_expected/calls.sol.o.jsonv2 | 2 +- .../outputs_expected/ether_send.sol.o.json | 6 +- .../outputs_expected/exceptions.sol.o.json | 59 +--------- .../outputs_expected/exceptions.sol.o.jsonv2 | 2 +- .../kinds_of_calls.sol.o.json | 72 +----------- .../kinds_of_calls.sol.o.jsonv2 | 2 +- .../outputs_expected/metacoin.sol.o.json | 6 +- .../multi_contracts.sol.o.json | 20 +--- .../multi_contracts.sol.o.jsonv2 | 2 +- .../outputs_expected/nonascii.sol.o.json | 6 +- .../outputs_expected/origin.sol.o.json | 20 +--- .../outputs_expected/origin.sol.o.jsonv2 | 2 +- .../outputs_expected/overflow.sol.o.json | 46 +------- .../outputs_expected/overflow.sol.o.jsonv2 | 2 +- .../outputs_expected/returnvalue.sol.o.json | 46 +------- .../outputs_expected/returnvalue.sol.o.jsonv2 | 2 +- .../outputs_expected/suicide.sol.o.json | 20 +--- .../outputs_expected/suicide.sol.o.jsonv2 | 2 +- .../outputs_expected/underflow.sol.o.json | 46 +------- .../outputs_expected/underflow.sol.o.jsonv2 | 2 +- 23 files changed, 28 insertions(+), 462 deletions(-) diff --git a/mythril/analysis/modules/multiple_sends.py b/mythril/analysis/modules/multiple_sends.py index 6ea8d529..d41e3790 100644 --- a/mythril/analysis/modules/multiple_sends.py +++ b/mythril/analysis/modules/multiple_sends.py @@ -81,10 +81,10 @@ def _analyze_state(state: GlobalState): call.state.get_current_instruction()["address"] ) - description_tail = ( - "Try to isolate each external call into its own transaction," - " as external calls can fail accidentally or deliberately.\n" - ) + description_tail += ( + "Try to isolate each external call into its own transaction," + " as external calls can fail accidentally or deliberately.\n" + ) issue = Issue( contract=node.contract_name, diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 81492cb1..8480b56c 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -33,8 +33,8 @@ class Issue: self.contract = contract self.function = function_name self.address = address - self.description_head = (description_head,) - self.description_tail = (description_tail,) + self.description_head = description_head + self.description_tail = description_tail self.description = "%s\n%s" % (description_head, description_tail) self.severity = severity self.debug = debug @@ -69,7 +69,7 @@ class Issue: "debug": self.debug, "min_gas_used": self.min_gas_used, "max_gas_used": self.max_gas_used, - "SourceMap": self.source_mapping, + "sourceMap": self.source_mapping, } if self.filename and self.lineno: diff --git a/tests/testdata/outputs_expected/calls.sol.o.json b/tests/testdata/outputs_expected/calls.sol.o.json index 9d7bb2b0..1342a258 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.json +++ b/tests/testdata/outputs_expected/calls.sol.o.json @@ -1,110 +1 @@ -{ - "success": true, - "error": null, - "issues": [ - { - "debug": "", - "function": "thisisfine()", - "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.", - "title": "External Call To Fixed Address", - "min_gas_used": 643, - "severity": "Low", - "SourceMap": null, - "contract": "Unknown", - "swc-id": "107", - "max_gas_used": 1254, - "address": 661 - }, - { - "function": "thisisfine()", - "debug": "", - "title": "Unchecked Call Return Value", - "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.", - "SourceMap": null, - "severity": "Low", - "min_gas_used": 1361, - "address": 661, - "max_gas_used": 35972, - "swc-id": "104", - "contract": "Unknown" - }, - { - "max_gas_used": 1298, - "address": 779, - "contract": "Unknown", - "swc-id": "107", - "severity": "Low", - "SourceMap": null, - "min_gas_used": 687, - "title": "External Call To Fixed Address", - "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()", - "debug": "" - }, - { - "title": "Unchecked Call Return Value", - "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()", - "debug": "", - "max_gas_used": 36016, - "address": 779, - "contract": "Unknown", - "swc-id": "104", - "severity": "Low", - "SourceMap": null, - "min_gas_used": 1405 - }, - { - "contract": "Unknown", - "swc-id": "107", - "max_gas_used": 1320, - "address": 858, - "min_gas_used": 709, - "severity": "Low", - "SourceMap": null, - "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.", - "title": "External Call To Fixed Address", - "debug": "", - "function": "reentrancy()" - }, - { - "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.", - "title": "Unchecked Call Return Value", - "debug": "", - "function": "reentrancy()", - "contract": "Unknown", - "swc-id": "104", - "max_gas_used": 61052, - "address": 858, - "min_gas_used": 6441, - "severity": "Low", - "SourceMap": null - }, - { - "severity": "Medium", - "SourceMap": null, - "min_gas_used": 335, - "max_gas_used": 616, - "address": 912, - "contract": "Unknown", - "swc-id": "107", - "function": "calluseraddress(address)", - "debug": "", - "title": "External Call To User-Supplied Address", - "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 thecontract state." - }, - { - "min_gas_used": 1055, - "SourceMap": null, - "severity": "Low", - "swc-id": "104", - "contract": "Unknown", - "address": 912, - "max_gas_used": 35336, - "debug": "", - "function": "calluseraddress(address)", - "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.", - "title": "Unchecked Call Return Value" - } - ] -} \ No newline at end of file +{"error": null, "issues": [{"address": 661, "contract": "Unknown", "debug": "", "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, "min_gas_used": 643, "severity": "Low", "sourceMap": null, "swc-id": "107", "title": "External Call To Fixed Address"}, {"address": 661, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1361, "severity": "Low", "sourceMap": null, "swc-id": "104", "title": "Unchecked Call Return Value"}, {"address": 779, "contract": "Unknown", "debug": "", "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, "min_gas_used": 687, "severity": "Low", "sourceMap": null, "swc-id": "107", "title": "External Call To Fixed Address"}, {"address": 779, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1405, "severity": "Low", "sourceMap": null, "swc-id": "104", "title": "Unchecked Call Return Value"}, {"address": 858, "contract": "Unknown", "debug": "", "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, "min_gas_used": 709, "severity": "Low", "sourceMap": null, "swc-id": "107", "title": "External Call To Fixed Address"}, {"address": 858, "contract": "Unknown", "debug": "", "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, "min_gas_used": 6441, "severity": "Low", "sourceMap": null, "swc-id": "104", "title": "Unchecked Call Return Value"}, {"address": 912, "contract": "Unknown", "debug": "", "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 thecontract state.", "function": "calluseraddress(address)", "max_gas_used": 616, "min_gas_used": 335, "severity": "Medium", "sourceMap": null, "swc-id": "107", "title": "External Call To User-Supplied Address"}, {"address": 912, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1055, "severity": "Low", "sourceMap": null, "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/calls.sol.o.jsonv2 b/tests/testdata/outputs_expected/calls.sol.o.jsonv2 index cdd59a54..8a0aa0c7 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/calls.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Medium", "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": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x7cbb77986c6b1bf6e945cd3fba06d3ea3d28cfc49cdfdc9571ec30703ac5862f"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": "The contract executes an external message call.", "tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."}, "extra": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": "The contract executes an external message call.", "tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."}, "extra": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": "The contract executes an external message call.", "tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."}, "extra": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": "A call to a user-supplied address is executed.", "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 thecontract state."}, "extra": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Medium", "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": {}, "locations": [{"sourceMap": "661:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "779:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "858:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "912:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x7cbb77986c6b1bf6e945cd3fba06d3ea3d28cfc49cdfdc9571ec30703ac5862f"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/ether_send.sol.o.json b/tests/testdata/outputs_expected/ether_send.sol.o.json index 712f50c1..237b1c1e 100644 --- a/tests/testdata/outputs_expected/ether_send.sol.o.json +++ b/tests/testdata/outputs_expected/ether_send.sol.o.json @@ -1,5 +1 @@ -{ - "error": null, - "issues": [], - "success": true -} \ No newline at end of file +{"error": null, "issues": [], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.json b/tests/testdata/outputs_expected/exceptions.sol.o.json index fc75823e..de103061 100644 --- a/tests/testdata/outputs_expected/exceptions.sol.o.json +++ b/tests/testdata/outputs_expected/exceptions.sol.o.json @@ -1,58 +1 @@ -{ - "success": true, - "error": null, - "issues": [ - { - "title": "Exception State", - "severity": "Low", - "max_gas_used": 301, - "function": "assert3(uint256)", - "address": 446, - "min_gas_used": 206, - "contract": "Unknown", - "swc-id": "110", - "SourceMap": null, - "debug": "", - "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." - }, - { - "swc-id": "110", - "min_gas_used": 256, - "contract": "Unknown", - "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.", - "debug": "", - "SourceMap": null, - "severity": "Low", - "max_gas_used": 351, - "title": "Exception State", - "address": 484, - "function": "arrayaccess(uint256)" - }, - { - "max_gas_used": 367, - "severity": "Low", - "title": "Exception State", - "address": 506, - "function": "divisionby0(uint256)", - "swc-id": "110", - "min_gas_used": 272, - "contract": "Unknown", - "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.", - "debug": "", - "SourceMap": null - }, - { - "title": "Exception State", - "max_gas_used": 363, - "severity": "Low", - "function": "assert1()", - "address": 531, - "min_gas_used": 268, - "contract": "Unknown", - "swc-id": "110", - "SourceMap": null, - "debug": "", - "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." - } - ] -} \ No newline at end of file +{"error": null, "issues": [{"address": 446, "contract": "Unknown", "debug": "", "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, "min_gas_used": 206, "severity": "Low", "sourceMap": null, "swc-id": "110", "title": "Exception State"}, {"address": 484, "contract": "Unknown", "debug": "", "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, "min_gas_used": 256, "severity": "Low", "sourceMap": null, "swc-id": "110", "title": "Exception State"}, {"address": 506, "contract": "Unknown", "debug": "", "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, "min_gas_used": 272, "severity": "Low", "sourceMap": null, "swc-id": "110", "title": "Exception State"}, {"address": 531, "contract": "Unknown", "debug": "", "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, "min_gas_used": 268, "severity": "Low", "sourceMap": null, "swc-id": "110", "title": "Exception State"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 b/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 index 21c65a1c..8a88b8d6 100644 --- a/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/exceptions.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "446:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "484:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "506:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"description": {"head": ["A reachable exception has been detected."], "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": {}, "locations": [{"sourceMap": "531:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x4a773a86bc6fb269f88bf09bb3094de29b6073cf13b1760e9d01d957f50a9dfd"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": "A reachable exception has been detected.", "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": {}, "locations": [{"sourceMap": "446:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"description": {"head": "A reachable exception has been detected.", "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": {}, "locations": [{"sourceMap": "484:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"description": {"head": "A reachable exception has been detected.", "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": {}, "locations": [{"sourceMap": "506:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}, {"description": {"head": "A reachable exception has been detected.", "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": {}, "locations": [{"sourceMap": "531:1:0"}], "severity": "Low", "swcID": "SWC-110", "swcTitle": "Assert Violation"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x4a773a86bc6fb269f88bf09bb3094de29b6073cf13b1760e9d01d957f50a9dfd"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json index 2ff55cc7..b18d1c40 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.json @@ -1,71 +1 @@ -{ - "issues": [ - { - "contract": "Unknown", - "debug": "", - "min_gas_used": 1113, - "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.", - "severity": "Low", - "SourceMap": null, - "swc-id": "104", - "max_gas_used": 35865, - "function": "_function_0x141f32ff", - "title": "Unchecked Call Return Value", - "address": 618 - }, - { - "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.", - "severity": "Medium", - "SourceMap": null, - "min_gas_used": 389, - "debug": "", - "contract": "Unknown", - "address": 618, - "swc-id": "111", - "title": "Use of callcode", - "function": "_function_0x141f32ff", - "max_gas_used": 1141 - }, - { - "address": 849, - "max_gas_used": 35922, - "title": "Unchecked Call Return Value", - "function": "_function_0x9b58bc26", - "swc-id": "104", - "SourceMap": null, - "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.", - "severity": "Low", - "contract": "Unknown", - "debug": "", - "min_gas_used": 1170 - }, - { - "min_gas_used": 471, - "debug": "", - "contract": "Unknown", - "SourceMap": null, - "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 thecontract state.", - "severity": "Medium", - "function": "_function_0xeea4c864", - "title": "External Call To User-Supplied Address", - "max_gas_used": 1223, - "swc-id": "107", - "address": 1038 - }, - { - "swc-id": "104", - "title": "Unchecked Call Return Value", - "function": "_function_0xeea4c864", - "max_gas_used": 35947, - "address": 1038, - "debug": "", - "min_gas_used": 1195, - "contract": "Unknown", - "severity": "Low", - "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.", - "SourceMap": null - } - ], - "success": true, - "error": null -} \ No newline at end of file +{"error": null, "issues": [{"address": 618, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1113, "severity": "Low", "sourceMap": null, "swc-id": "104", "title": "Unchecked Call Return Value"}, {"address": 618, "contract": "Unknown", "debug": "", "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, "min_gas_used": 389, "severity": "Medium", "sourceMap": null, "swc-id": "111", "title": "Use of callcode"}, {"address": 849, "contract": "Unknown", "debug": "", "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": 35922, "min_gas_used": 1170, "severity": "Low", "sourceMap": null, "swc-id": "104", "title": "Unchecked Call Return Value"}, {"address": 1038, "contract": "Unknown", "debug": "", "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 thecontract state.", "function": "_function_0xeea4c864", "max_gas_used": 1223, "min_gas_used": 471, "severity": "Medium", "sourceMap": null, "swc-id": "107", "title": "External Call To User-Supplied Address"}, {"address": 1038, "contract": "Unknown", "debug": "", "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": 35947, "min_gas_used": 1195, "severity": "Low", "sourceMap": null, "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 index e63c0c07..ea5479c2 100644 --- a/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/kinds_of_calls.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["Use of callcode is deprecated."], "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Medium", "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}, {"description": {"head": ["A call to a user-supplied address is executed."], "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 thecontract state."]}, "extra": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Medium", "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "849:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x6daec61d05d8f1210661e7e7d1ed6d72bd6ade639398fac1e867aff50abfc1c1"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": "Use of callcode is deprecated.", "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Medium", "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}, {"description": {"head": "A call to a user-supplied address is executed.", "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 thecontract state."}, "extra": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Medium", "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": {}, "locations": [{"sourceMap": "618:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "849:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}, {"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": {}, "locations": [{"sourceMap": "1038:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x6daec61d05d8f1210661e7e7d1ed6d72bd6ade639398fac1e867aff50abfc1c1"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/metacoin.sol.o.json b/tests/testdata/outputs_expected/metacoin.sol.o.json index 712f50c1..237b1c1e 100644 --- a/tests/testdata/outputs_expected/metacoin.sol.o.json +++ b/tests/testdata/outputs_expected/metacoin.sol.o.json @@ -1,5 +1 @@ -{ - "error": null, - "issues": [], - "success": true -} \ No newline at end of file +{"error": null, "issues": [], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.json b/tests/testdata/outputs_expected/multi_contracts.sol.o.json index a446616c..64a7bee7 100644 --- a/tests/testdata/outputs_expected/multi_contracts.sol.o.json +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.json @@ -1,19 +1 @@ -{ - "success": true, - "issues": [ - { - "min_gas_used": 186, - "contract": "Unknown", - "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.", - "SourceMap": null, - "max_gas_used": 467, - "function": "transfer()", - "title": "Unprotected Ether Withdrawal", - "address": 142, - "debug": "", - "severity": "High", - "swc-id": "105" - } - ], - "error": null -} \ No newline at end of file +{"error": null, "issues": [{"address": 142, "contract": "Unknown", "debug": "", "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, "min_gas_used": 186, "severity": "High", "sourceMap": null, "swc-id": "105", "title": "Unprotected Ether Withdrawal"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 b/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 index e4f7dd25..46747699 100644 --- a/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/multi_contracts.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["Anyone can withdraw ETH from the contract account."], "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": {}, "locations": [{"sourceMap": "142:1:0"}], "severity": "High", "swcID": "SWC-105", "swcTitle": "Unprotected Ether Withdrawal"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xbc9c3d9db56d20cf4ca3b6fd88ff9215cf728a092cca1ed8edb83272b933ff5b"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": "Anyone can withdraw ETH from the contract account.", "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": {}, "locations": [{"sourceMap": "142:1:0"}], "severity": "High", "swcID": "SWC-105", "swcTitle": "Unprotected Ether Withdrawal"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xbc9c3d9db56d20cf4ca3b6fd88ff9215cf728a092cca1ed8edb83272b933ff5b"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/nonascii.sol.o.json b/tests/testdata/outputs_expected/nonascii.sol.o.json index 712f50c1..237b1c1e 100644 --- a/tests/testdata/outputs_expected/nonascii.sol.o.json +++ b/tests/testdata/outputs_expected/nonascii.sol.o.json @@ -1,5 +1 @@ -{ - "error": null, - "issues": [], - "success": true -} \ No newline at end of file +{"error": null, "issues": [], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.json b/tests/testdata/outputs_expected/origin.sol.o.json index 34f1ce7d..5b786178 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.json +++ b/tests/testdata/outputs_expected/origin.sol.o.json @@ -1,19 +1 @@ -{ - "error": null, - "issues": [ - { - "SourceMap": null, - "address": 317, - "contract": "Unknown", - "debug": "", - "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, - "min_gas_used": 626, - "severity": "Medium", - "swc-id": "111", - "title": "Use of tx.origin" - } - ], - "success": true -} \ No newline at end of file +{"error": null, "issues": [{"address": 317, "contract": "Unknown", "debug": "", "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, "min_gas_used": 626, "severity": "Medium", "sourceMap": null, "swc-id": "111", "title": "Use of tx.origin"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/origin.sol.o.jsonv2 b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 index b6848588..095427f1 100644 --- a/tests/testdata/outputs_expected/origin.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/origin.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["Use of tx.origin is deprecated."], "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": {}, "locations": [{"sourceMap": "317:1:0"}], "severity": "Medium", "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x25b20ef097dfc0aa56a932c4e09f06ee02a69c005767df86877f48c6c2412f03"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": "Use of tx.origin is deprecated.", "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": {}, "locations": [{"sourceMap": "317:1:0"}], "severity": "Medium", "swcID": "SWC-111", "swcTitle": "Use of Deprecated Solidity Functions"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x25b20ef097dfc0aa56a932c4e09f06ee02a69c005767df86877f48c6c2412f03"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/overflow.sol.o.json b/tests/testdata/outputs_expected/overflow.sol.o.json index f928ccdb..556818c6 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.json +++ b/tests/testdata/outputs_expected/overflow.sol.o.json @@ -1,45 +1 @@ -{ - "error": null, - "success": true, - "issues": [ - { - "severity": "High", - "SourceMap": null, - "title": "Integer Overflow", - "max_gas_used": 1053, - "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", - "swc-id": "101", - "contract": "Unknown", - "function": "sendeth(address,uint256)", - "address": 567, - "min_gas_used": 768, - "debug": "" - }, - { - "debug": "", - "min_gas_used": 1299, - "function": "sendeth(address,uint256)", - "address": 567, - "contract": "Unknown", - "swc-id": "101", - "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", - "max_gas_used": 1774, - "SourceMap": null, - "title": "Integer Underflow", - "severity": "High" - }, - { - "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", - "max_gas_used": 1774, - "title": "Integer Underflow", - "SourceMap": null, - "severity": "High", - "debug": "", - "min_gas_used": 1299, - "address": 649, - "function": "sendeth(address,uint256)", - "contract": "Unknown", - "swc-id": "101" - } - ] -} \ No newline at end of file +{"error": null, "issues": [{"address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1053, "min_gas_used": 768, "severity": "High", "sourceMap": null, "swc-id": "101", "title": "Integer Overflow"}, {"address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "sourceMap": null, "swc-id": "101", "title": "Integer Underflow"}, {"address": 649, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "sourceMap": null, "swc-id": "101", "title": "Integer Underflow"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 index 0aa1a5ba..5b8465cd 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["The subtraction can overflow."], "tail": ["The binary subtraction operation can result in an integer overflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xf230bec502569e8b7e7737616d0ad0f200c436624e3c223e5398c0615cd2d6b9"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": "The subtraction can overflow.", "tail": "The binary subtraction operation can result in an integer overflow.\n"}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": "The subtraction can underflow.", "tail": "The binary subtraction operation can result in an integer underflow.\n"}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": "The subtraction can underflow.", "tail": "The binary subtraction operation can result in an integer underflow.\n"}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xf230bec502569e8b7e7737616d0ad0f200c436624e3c223e5398c0615cd2d6b9"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.json b/tests/testdata/outputs_expected/returnvalue.sol.o.json index 7c866dd1..2c741ba2 100644 --- a/tests/testdata/outputs_expected/returnvalue.sol.o.json +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.json @@ -1,45 +1 @@ -{ - "error": null, - "issues": [ - { - "SourceMap": null, - "address": 196, - "contract": "Unknown", - "debug": "", - "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, - "min_gas_used": 599, - "severity": "Low", - "swc-id": "107", - "title": "External Call To Fixed Address" - }, - { - "SourceMap": null, - "address": 285, - "contract": "Unknown", - "debug": "", - "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, - "min_gas_used": 621, - "severity": "Low", - "swc-id": "107", - "title": "External Call To Fixed Address" - }, - { - "SourceMap": null, - "address": 285, - "contract": "Unknown", - "debug": "", - "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, - "min_gas_used": 1339, - "severity": "Low", - "swc-id": "104", - "title": "Unchecked Call Return Value" - } - ], - "success": true -} \ No newline at end of file +{"error": null, "issues": [{"address": 196, "contract": "Unknown", "debug": "", "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, "min_gas_used": 599, "severity": "Low", "sourceMap": null, "swc-id": "107", "title": "External Call To Fixed Address"}, {"address": 285, "contract": "Unknown", "debug": "", "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, "min_gas_used": 621, "severity": "Low", "sourceMap": null, "swc-id": "107", "title": "External Call To Fixed Address"}, {"address": 285, "contract": "Unknown", "debug": "", "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, "min_gas_used": 1339, "severity": "Low", "sourceMap": null, "swc-id": "104", "title": "Unchecked Call Return Value"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 b/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 index 66dd3b5e..6da3980c 100644 --- a/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/returnvalue.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "196:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": ["The contract executes an external message call."], "tail": ["An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."]}, "extra": {}, "locations": [{"sourceMap": "285: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": {}, "locations": [{"sourceMap": "285:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xb191cf6cc0d8cc37a91c9d88019cc011b932169fb5776df616e2bb9cd93b4039"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": "The contract executes an external message call.", "tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."}, "extra": {}, "locations": [{"sourceMap": "196:1:0"}], "severity": "Low", "swcID": "SWC-107", "swcTitle": "Reentrancy"}, {"description": {"head": "The contract executes an external message call.", "tail": "An external function call to a fixed contract address is executed. Make sure that the callee contract has been reviewed carefully."}, "extra": {}, "locations": [{"sourceMap": "285: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": {}, "locations": [{"sourceMap": "285:1:0"}], "severity": "Low", "swcID": "SWC-104", "swcTitle": "Unchecked Call Return Value"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xb191cf6cc0d8cc37a91c9d88019cc011b932169fb5776df616e2bb9cd93b4039"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/suicide.sol.o.json b/tests/testdata/outputs_expected/suicide.sol.o.json index d13cac2b..5bb5eb13 100644 --- a/tests/testdata/outputs_expected/suicide.sol.o.json +++ b/tests/testdata/outputs_expected/suicide.sol.o.json @@ -1,19 +1 @@ -{ - "error": null, - "issues": [ - { - "SourceMap": null, - "address": 146, - "contract": "Unknown", - "debug": "", - "description": "The contract can be killed by anyone.\nArbitrary senders can kill this contract and withdraw its balance to their own account.", - "function": "kill(address)", - "max_gas_used": 263, - "min_gas_used": 168, - "severity": "High", - "swc-id": "106", - "title": "Unprotected Selfdestruct" - } - ], - "success": true -} \ No newline at end of file +{"error": null, "issues": [{"address": 146, "contract": "Unknown", "debug": "", "description": "The contract can be killed by anyone.\nArbitrary senders can kill this contract and withdraw its balance to their own account.", "function": "kill(address)", "max_gas_used": 263, "min_gas_used": 168, "severity": "High", "sourceMap": null, "swc-id": "106", "title": "Unprotected Selfdestruct"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 b/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 index 324cdf44..b3a966a1 100644 --- a/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/suicide.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["The contract can be killed by anyone."], "tail": ["Arbitrary senders can kill this contract and withdraw its balance to their own account."]}, "extra": {}, "locations": [{"sourceMap": "146:1:0"}], "severity": "High", "swcID": "SWC-106", "swcTitle": "Unprotected SELFDESTRUCT Instruction"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x2fb801366b61a05b30550481a1c8f7d5f20de0b93d9f2f2ce2b28c4e322033c9"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": "The contract can be killed by anyone.", "tail": "Arbitrary senders can kill this contract and withdraw its balance to their own account."}, "extra": {}, "locations": [{"sourceMap": "146:1:0"}], "severity": "High", "swcID": "SWC-106", "swcTitle": "Unprotected SELFDESTRUCT Instruction"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x2fb801366b61a05b30550481a1c8f7d5f20de0b93d9f2f2ce2b28c4e322033c9"], "sourceType": "raw-bytecode"} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.json b/tests/testdata/outputs_expected/underflow.sol.o.json index ed13ac20..556818c6 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.json +++ b/tests/testdata/outputs_expected/underflow.sol.o.json @@ -1,45 +1 @@ -{ - "error": null, - "issues": [ - { - "SourceMap": null, - "address": 567, - "contract": "Unknown", - "debug": "", - "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", - "function": "sendeth(address,uint256)", - "max_gas_used": 1053, - "min_gas_used": 768, - "severity": "High", - "swc-id": "101", - "title": "Integer Overflow" - }, - { - "SourceMap": null, - "address": 567, - "contract": "Unknown", - "debug": "", - "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", - "function": "sendeth(address,uint256)", - "max_gas_used": 1774, - "min_gas_used": 1299, - "severity": "High", - "swc-id": "101", - "title": "Integer Underflow" - }, - { - "SourceMap": null, - "address": 649, - "contract": "Unknown", - "debug": "", - "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", - "function": "sendeth(address,uint256)", - "max_gas_used": 1774, - "min_gas_used": 1299, - "severity": "High", - "swc-id": "101", - "title": "Integer Underflow" - } - ], - "success": true -} \ No newline at end of file +{"error": null, "issues": [{"address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can overflow.\nThe binary subtraction operation can result in an integer overflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1053, "min_gas_used": 768, "severity": "High", "sourceMap": null, "swc-id": "101", "title": "Integer Overflow"}, {"address": 567, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "sourceMap": null, "swc-id": "101", "title": "Integer Underflow"}, {"address": 649, "contract": "Unknown", "debug": "", "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", "sourceMap": null, "swc-id": "101", "title": "Integer Underflow"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 index afb1bd36..3fccf8a7 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 @@ -1 +1 @@ -{"issues": [{"description": {"head": ["The subtraction can overflow."], "tail": ["The binary subtraction operation can result in an integer overflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": ["The subtraction can underflow."], "tail": ["The binary subtraction operation can result in an integer underflow.\n"]}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xabef56740bf7795a9f8732e4781ebd27f2977f8a4997e3ff11cee79a4ba6c0ce"], "sourceType": "raw-bytecode"} \ No newline at end of file +{"issues": [{"description": {"head": "The subtraction can overflow.", "tail": "The binary subtraction operation can result in an integer overflow.\n"}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": "The subtraction can underflow.", "tail": "The binary subtraction operation can result in an integer underflow.\n"}, "extra": {}, "locations": [{"sourceMap": "567:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}, {"description": {"head": "The subtraction can underflow.", "tail": "The binary subtraction operation can result in an integer underflow.\n"}, "extra": {}, "locations": [{"sourceMap": "649:1:0"}], "severity": "High", "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow"}], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0xabef56740bf7795a9f8732e4781ebd27f2977f8a4997e3ff11cee79a4ba6c0ce"], "sourceType": "raw-bytecode"} \ No newline at end of file From 9410ceb83d85d70a484bbf08ecc274216fa0589f Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Thu, 3 Jan 2019 22:59:07 +0530 Subject: [PATCH 34/56] Add documentation for Source class --- mythril/support/source_support.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/mythril/support/source_support.py b/mythril/support/source_support.py index 1fd18508..a8e6f0b9 100644 --- a/mythril/support/source_support.py +++ b/mythril/support/source_support.py @@ -3,15 +3,28 @@ from mythril.ethereum.evmcontract import EVMContract class Source: + """Class to handle to source data""" + def __init__( self, source_type=None, source_format=None, source_list=None, meta=None ): + """ + :param source_type: whether it is a solidity-file or evm-bytecode + :param source_format: whether it is bytecode, ethereum-address or text + :param source_list: List of files + :param meta: meta data + """ self.source_type = source_type self.source_format = source_format self.source_list = [] self.meta = meta def get_source_from_contracts_list(self, contracts): + """ + get the source data from the contracts list + :param contracts: the list of contracts + :return: + """ if contracts is None or len(contracts) == 0: return if isinstance(contracts[0], SolidityContract): From 2b668a7a4fd31bb36608ffa2da9b53c7d810d5e0 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 4 Jan 2019 00:12:54 +0530 Subject: [PATCH 35/56] fix merge conflicts with tests --- tests/testdata/outputs_expected/overflow.sol.o.json | 4 ++-- .../testdata/outputs_expected/overflow.sol.o.jsonv2 | 12 ++++++------ tests/testdata/outputs_expected/underflow.sol.o.json | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/testdata/outputs_expected/overflow.sol.o.json b/tests/testdata/outputs_expected/overflow.sol.o.json index 1a2e7fbf..091b2bb6 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.json +++ b/tests/testdata/outputs_expected/overflow.sol.o.json @@ -1,7 +1,6 @@ { "error": null, "issues": [{ - "SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", @@ -10,10 +9,10 @@ "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", + "sourceMap": null, "swc-id": "101", "title": "Integer Underflow" }, { - "SourceMap": null, "address": 649, "contract": "Unknown", "debug": "", @@ -22,6 +21,7 @@ "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", + "sourceMap": null, "swc-id": "101", "title": "Integer Underflow" }], diff --git a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 index 002059f8..2ff9c7a0 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 @@ -1,27 +1,27 @@ { "issues": [{ "description": { - "head": ["The subtraction can underflow."], - "tail": ["The binary subtraction operation can result in an integer underflow.\n"] + "head": "The subtraction can underflow.", + "tail": "The binary subtraction operation can result in an integer underflow.\n" }, "extra": {}, "locations": [{ "sourceMap": "567:1:0" }], "severity": "High", - "swcID": "101", + "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow" }, { "description": { - "head": ["The subtraction can underflow."], - "tail": ["The binary subtraction operation can result in an integer underflow.\n"] + "head": "The subtraction can underflow.", + "tail": "The binary subtraction operation can result in an integer underflow.\n" }, "extra": {}, "locations": [{ "sourceMap": "649:1:0" }], "severity": "High", - "swcID": "101", + "swcID": "SWC-101", "swcTitle": "Integer Overflow and Underflow" }], "meta": {}, diff --git a/tests/testdata/outputs_expected/underflow.sol.o.json b/tests/testdata/outputs_expected/underflow.sol.o.json index 1a2e7fbf..091b2bb6 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.json +++ b/tests/testdata/outputs_expected/underflow.sol.o.json @@ -1,7 +1,6 @@ { "error": null, "issues": [{ - "SourceMap": null, "address": 567, "contract": "Unknown", "debug": "", @@ -10,10 +9,10 @@ "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", + "sourceMap": null, "swc-id": "101", "title": "Integer Underflow" }, { - "SourceMap": null, "address": 649, "contract": "Unknown", "debug": "", @@ -22,6 +21,7 @@ "max_gas_used": 1774, "min_gas_used": 1299, "severity": "High", + "sourceMap": null, "swc-id": "101", "title": "Integer Underflow" }], From df7d5c799f7def5cd92571bbac89828cb6de29cd Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Fri, 4 Jan 2019 09:54:28 +0700 Subject: [PATCH 36/56] Add jsonv2 option to help --- mythril/interfaces/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/interfaces/cli.py b/mythril/interfaces/cli.py index 98c1d8bc..772f52b9 100644 --- a/mythril/interfaces/cli.py +++ b/mythril/interfaces/cli.py @@ -117,7 +117,7 @@ def main(): choices=["text", "markdown", "json", "jsonv2"], default="text", help="report output format", - metavar="", + metavar="", ) outputs.add_argument( "--verbose-report", From ed5354297a64d0459d71e2532e5b623c13817af9 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Fri, 4 Jan 2019 10:19:05 +0700 Subject: [PATCH 37/56] Improve integer module descriptions --- mythril/analysis/modules/integer.py | 16 +++-- .../outputs_expected/overflow.sol.o.json | 59 ++++++++-------- .../outputs_expected/overflow.sol.o.jsonv2 | 69 +++++++++++-------- .../outputs_expected/overflow.sol.o.markdown | 8 +-- .../outputs_expected/overflow.sol.o.text | 10 ++- .../outputs_expected/underflow.sol.o.json | 59 ++++++++-------- .../outputs_expected/underflow.sol.o.jsonv2 | 69 +++++++++++-------- .../outputs_expected/underflow.sol.o.markdown | 8 +-- .../outputs_expected/underflow.sol.o.text | 10 ++- 9 files changed, 166 insertions(+), 142 deletions(-) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 186082bf..b6c1abd1 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -80,7 +80,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): if model is None: return - annotation = OverUnderflowAnnotation(state, "add", c) + annotation = OverUnderflowAnnotation(state, "addition", c) op0.annotate(annotation) def _handle_mul(self, state): @@ -97,7 +97,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): if model is None: return - annotation = OverUnderflowAnnotation(state, "multiply", c) + annotation = OverUnderflowAnnotation(state, "multiplication", c) op0.annotate(annotation) def _handle_sub(self, state): @@ -139,10 +139,16 @@ class IntegerOverflowUnderflowModule(DetectionModule): ostate = annotation.overflowing_state node = ostate.node - description_tail = "The binary {} operation can result in an integer {}.\n".format( + description_head = "The binary {} can {}.".format( annotation.operator, _type.lower() ) + description_tail = "The operands of the {} operation are not sufficiently constrained. " \ + "The {} could therefore result in an integer {}. Prevent the {} by checking inputs " \ + "or ensure sure that the {} is caught by an assertion.".format( + annotation.operator, annotation.operator, _type.lower(), _type.lower(), _type.lower() + ) + issue = Issue( contract=node.contract_name, function_name=node.function_name, @@ -151,9 +157,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): bytecode=ostate.environment.code.bytecode, title="Integer {}".format(_type), severity="High", - description_head="The {} can {}.".format( - annotation.operator, _type.lower() - ), + description_head=description_head, description_tail=description_tail, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), ) diff --git a/tests/testdata/outputs_expected/overflow.sol.o.json b/tests/testdata/outputs_expected/overflow.sol.o.json index 091b2bb6..b08b7c51 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.json +++ b/tests/testdata/outputs_expected/overflow.sol.o.json @@ -1,29 +1,32 @@ { - "error": null, - "issues": [{ - "address": 567, - "contract": "Unknown", - "debug": "", - "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", - "function": "sendeth(address,uint256)", - "max_gas_used": 1774, - "min_gas_used": 1299, - "severity": "High", - "sourceMap": null, - "swc-id": "101", - "title": "Integer Underflow" - }, { - "address": 649, - "contract": "Unknown", - "debug": "", - "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", - "function": "sendeth(address,uint256)", - "max_gas_used": 1774, - "min_gas_used": 1299, - "severity": "High", - "sourceMap": null, - "swc-id": "101", - "title": "Integer Underflow" - }], - "success": true -} + "error": null, + "issues": [ + { + "address": 567, + "contract": "Unknown", + "debug": "", + "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": 1774, + "min_gas_used": 1299, + "severity": "High", + "sourceMap": null, + "swc-id": "101", + "title": "Integer Underflow" + }, + { + "address": 649, + "contract": "Unknown", + "debug": "", + "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": 1774, + "min_gas_used": 1299, + "severity": "High", + "sourceMap": null, + "swc-id": "101", + "title": "Integer Underflow" + } + ], + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 index 2ff9c7a0..9c2c320f 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/overflow.sol.o.jsonv2 @@ -1,31 +1,40 @@ { - "issues": [{ - "description": { - "head": "The subtraction can underflow.", - "tail": "The binary subtraction operation can result in an integer underflow.\n" - }, - "extra": {}, - "locations": [{ - "sourceMap": "567:1:0" - }], - "severity": "High", - "swcID": "SWC-101", - "swcTitle": "Integer Overflow and Underflow" - }, { - "description": { - "head": "The subtraction can underflow.", - "tail": "The binary subtraction operation can result in an integer underflow.\n" - }, - "extra": {}, - "locations": [{ - "sourceMap": "649:1:0" - }], - "severity": "High", - "swcID": "SWC-101", - "swcTitle": "Integer Overflow and Underflow" - }], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": ["0xf230bec502569e8b7e7737616d0ad0f200c436624e3c223e5398c0615cd2d6b9"], - "sourceType": "raw-bytecode" -} + "issues": [ + { + "description": { + "head": "The binary subtraction can underflow.", + "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": {}, + "locations": [ + { + "sourceMap": "567:1:0" + } + ], + "severity": "High", + "swcID": "SWC-101", + "swcTitle": "Integer Overflow and Underflow" + }, + { + "description": { + "head": "The binary subtraction can underflow.", + "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": {}, + "locations": [ + { + "sourceMap": "649:1:0" + } + ], + "severity": "High", + "swcID": "SWC-101", + "swcTitle": "Integer Overflow and Underflow" + } + ], + "meta": {}, + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": [ + "0xf230bec502569e8b7e7737616d0ad0f200c436624e3c223e5398c0615cd2d6b9" + ], + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/overflow.sol.o.markdown b/tests/testdata/outputs_expected/overflow.sol.o.markdown index e9dc8ed0..00dcc1c7 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.markdown +++ b/tests/testdata/outputs_expected/overflow.sol.o.markdown @@ -10,8 +10,8 @@ ### Description -The subtraction can underflow. -The binary subtraction operation can result in an integer underflow. +The binary subtraction can underflow. +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. ## Integer Underflow - SWC ID: 101 @@ -23,5 +23,5 @@ The binary subtraction operation can result in an integer underflow. ### Description -The subtraction can underflow. -The binary subtraction operation can result in an integer underflow. +The binary subtraction can underflow. +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. diff --git a/tests/testdata/outputs_expected/overflow.sol.o.text b/tests/testdata/outputs_expected/overflow.sol.o.text index 1859a1f9..f0e783fa 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.text +++ b/tests/testdata/outputs_expected/overflow.sol.o.text @@ -5,9 +5,8 @@ Contract: Unknown Function name: sendeth(address,uint256) PC address: 567 Estimated Gas Usage: 1299 - 1774 -The subtraction can underflow. -The binary subtraction operation can result in an integer underflow. - +The binary subtraction can underflow. +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. -------------------- ==== Integer Underflow ==== @@ -17,8 +16,7 @@ Contract: Unknown Function name: sendeth(address,uint256) PC address: 649 Estimated Gas Usage: 1299 - 1774 -The subtraction can underflow. -The binary subtraction operation can result in an integer underflow. - +The binary subtraction can underflow. +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. -------------------- diff --git a/tests/testdata/outputs_expected/underflow.sol.o.json b/tests/testdata/outputs_expected/underflow.sol.o.json index 091b2bb6..b08b7c51 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.json +++ b/tests/testdata/outputs_expected/underflow.sol.o.json @@ -1,29 +1,32 @@ { - "error": null, - "issues": [{ - "address": 567, - "contract": "Unknown", - "debug": "", - "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", - "function": "sendeth(address,uint256)", - "max_gas_used": 1774, - "min_gas_used": 1299, - "severity": "High", - "sourceMap": null, - "swc-id": "101", - "title": "Integer Underflow" - }, { - "address": 649, - "contract": "Unknown", - "debug": "", - "description": "The subtraction can underflow.\nThe binary subtraction operation can result in an integer underflow.\n", - "function": "sendeth(address,uint256)", - "max_gas_used": 1774, - "min_gas_used": 1299, - "severity": "High", - "sourceMap": null, - "swc-id": "101", - "title": "Integer Underflow" - }], - "success": true -} + "error": null, + "issues": [ + { + "address": 567, + "contract": "Unknown", + "debug": "", + "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": 1774, + "min_gas_used": 1299, + "severity": "High", + "sourceMap": null, + "swc-id": "101", + "title": "Integer Underflow" + }, + { + "address": 649, + "contract": "Unknown", + "debug": "", + "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": 1774, + "min_gas_used": 1299, + "severity": "High", + "sourceMap": null, + "swc-id": "101", + "title": "Integer Underflow" + } + ], + "success": true +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 index 4af814f1..ab57bbd9 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/underflow.sol.o.jsonv2 @@ -1,31 +1,40 @@ { - "issues": [{ - "description": { - "head": ["The subtraction can underflow."], - "tail": ["The binary subtraction operation can result in an integer underflow.\n"] - }, - "extra": {}, - "locations": [{ - "sourceMap": "567:1:0" - }], - "severity": "High", - "swcID": "101", - "swcTitle": "Integer Overflow and Underflow" - }, { - "description": { - "head": ["The subtraction can underflow."], - "tail": ["The binary subtraction operation can result in an integer underflow.\n"] - }, - "extra": {}, - "locations": [{ - "sourceMap": "649:1:0" - }], - "severity": "High", - "swcID": "101", - "swcTitle": "Integer Overflow and Underflow" - }], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": ["0xabef56740bf7795a9f8732e4781ebd27f2977f8a4997e3ff11cee79a4ba6c0ce"], - "sourceType": "raw-bytecode" -} + "issues": [ + { + "description": { + "head": "The binary subtraction can underflow.", + "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": {}, + "locations": [ + { + "sourceMap": "567:1:0" + } + ], + "severity": "High", + "swcID": "SWC-101", + "swcTitle": "Integer Overflow and Underflow" + }, + { + "description": { + "head": "The binary subtraction can underflow.", + "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": {}, + "locations": [ + { + "sourceMap": "649:1:0" + } + ], + "severity": "High", + "swcID": "SWC-101", + "swcTitle": "Integer Overflow and Underflow" + } + ], + "meta": {}, + "sourceFormat": "evm-byzantium-bytecode", + "sourceList": [ + "0xabef56740bf7795a9f8732e4781ebd27f2977f8a4997e3ff11cee79a4ba6c0ce" + ], + "sourceType": "raw-bytecode" +} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/underflow.sol.o.markdown b/tests/testdata/outputs_expected/underflow.sol.o.markdown index e9dc8ed0..00dcc1c7 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.markdown +++ b/tests/testdata/outputs_expected/underflow.sol.o.markdown @@ -10,8 +10,8 @@ ### Description -The subtraction can underflow. -The binary subtraction operation can result in an integer underflow. +The binary subtraction can underflow. +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. ## Integer Underflow - SWC ID: 101 @@ -23,5 +23,5 @@ The binary subtraction operation can result in an integer underflow. ### Description -The subtraction can underflow. -The binary subtraction operation can result in an integer underflow. +The binary subtraction can underflow. +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. diff --git a/tests/testdata/outputs_expected/underflow.sol.o.text b/tests/testdata/outputs_expected/underflow.sol.o.text index 1859a1f9..f0e783fa 100644 --- a/tests/testdata/outputs_expected/underflow.sol.o.text +++ b/tests/testdata/outputs_expected/underflow.sol.o.text @@ -5,9 +5,8 @@ Contract: Unknown Function name: sendeth(address,uint256) PC address: 567 Estimated Gas Usage: 1299 - 1774 -The subtraction can underflow. -The binary subtraction operation can result in an integer underflow. - +The binary subtraction can underflow. +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. -------------------- ==== Integer Underflow ==== @@ -17,8 +16,7 @@ Contract: Unknown Function name: sendeth(address,uint256) PC address: 649 Estimated Gas Usage: 1299 - 1774 -The subtraction can underflow. -The binary subtraction operation can result in an integer underflow. - +The binary subtraction can underflow. +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. -------------------- From 8e565af113039e71efeecb6ea3dff28250e4ba80 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Fri, 4 Jan 2019 10:21:59 +0700 Subject: [PATCH 38/56] Blackkkkkkkk --- mythril/analysis/modules/integer.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index b6c1abd1..48b32eab 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -143,10 +143,16 @@ class IntegerOverflowUnderflowModule(DetectionModule): annotation.operator, _type.lower() ) - description_tail = "The operands of the {} operation are not sufficiently constrained. " \ - "The {} could therefore result in an integer {}. Prevent the {} by checking inputs " \ + description_tail = ( + "The operands of the {} operation are not sufficiently constrained. " + "The {} could therefore result in an integer {}. Prevent the {} by checking inputs " "or ensure sure that the {} is caught by an assertion.".format( - annotation.operator, annotation.operator, _type.lower(), _type.lower(), _type.lower() + annotation.operator, + annotation.operator, + _type.lower(), + _type.lower(), + _type.lower(), + ) ) issue = Issue( From badaaa7709cf114c2b0b5d3622a2d6dc3ac1ddce Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 4 Jan 2019 13:04:54 +0530 Subject: [PATCH 39/56] Add the bytecode_hash as property --- mythril/ethereum/evmcontract.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mythril/ethereum/evmcontract.py b/mythril/ethereum/evmcontract.py index 516fcf6b..ec43686c 100644 --- a/mythril/ethereum/evmcontract.py +++ b/mythril/ethereum/evmcontract.py @@ -40,15 +40,24 @@ class EVMContract(persistent.Persistent): self.creation_disassembly = Disassembly( creation_code, enable_online_lookup=enable_online_lookup ) + self._bytecode_hash = None + + @property + def bytecode_hash(self): + if self._bytecode_hash is not None: + return self._bytecode_hash + try: keccak = sha3.keccak_256() keccak.update(bytes.fromhex(self.code[2:])) - self.bytecode_hash = "0x" + keccak.hexdigest() + self._bytecode_hash = "0x" + keccak.hexdigest() except ValueError: log.debug( "Unable to change the bytecode to bytes. Bytecode: {}".format(code) ) - self.bytecode_hash = "" + self._bytecode_hash = "" + + return self._bytecode_hash def as_dict(self): """ From ca34b3aa1918a8fa189ed32bd4625d1600e27240 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Fri, 4 Jan 2019 17:10:30 +0700 Subject: [PATCH 40/56] Make debugging output nicer --- mythril/analysis/modules/ether_thief.py | 3 ++- mythril/analysis/modules/exceptions.py | 4 +++- mythril/analysis/modules/external_calls.py | 5 ++-- mythril/analysis/modules/integer.py | 24 +++++++++++-------- mythril/analysis/modules/suicide.py | 3 ++- .../analysis/templates/report_as_text.jinja2 | 2 +- 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/mythril/analysis/modules/ether_thief.py b/mythril/analysis/modules/ether_thief.py index 5e8ee880..b4dcb0b0 100644 --- a/mythril/analysis/modules/ether_thief.py +++ b/mythril/analysis/modules/ether_thief.py @@ -1,6 +1,7 @@ """This module contains the detection code for unauthorized ether withdrawal.""" import logging +import json from copy import copy from mythril.analysis import solver @@ -88,7 +89,7 @@ class EtherThief(DetectionModule): transaction_sequence = solver.get_transaction_sequence(state, constraints) - debug = str(transaction_sequence) + debug = json.dumps(transaction_sequence, indent=4) issue = Issue( contract=node.contract_name, diff --git a/mythril/analysis/modules/exceptions.py b/mythril/analysis/modules/exceptions.py index 0545e5e8..d819d0ea 100644 --- a/mythril/analysis/modules/exceptions.py +++ b/mythril/analysis/modules/exceptions.py @@ -1,5 +1,6 @@ """This module contains the detection code for reachable exceptions.""" import logging +import json from mythril.analysis import solver from mythril.analysis.modules.base import DetectionModule @@ -33,7 +34,8 @@ def _analyze_state(state) -> list: "Use `require()` for regular input checking." ) - debug = str(solver.get_transaction_sequence(state, node.constraints)) + transaction_sequence = solver.get_transaction_sequence(state, node.constraints) + debug = json.dumps(transaction_sequence, indent=4) issue = Issue( contract=node.contract_name, diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index def3de0d..09828267 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -9,6 +9,7 @@ from mythril.laser.smt import UGT, symbol_factory from mythril.laser.ethereum.state.global_state import GlobalState from mythril.exceptions import UnsatError import logging +import json log = logging.getLogger(__name__) @@ -45,7 +46,7 @@ def _analyze_state(state): constraints += [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF] transaction_sequence = solver.get_transaction_sequence(state, constraints) - debug = str(transaction_sequence) + 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 " @@ -74,7 +75,7 @@ def _analyze_state(state): "[EXTERNAL_CALLS] Callee address cannot be modified. Reporting informational issue." ) - debug = str(transaction_sequence) + debug = json.dumps(transaction_sequence, indent=4) description_head = "The contract executes an external message call." description_tail = ( "An external function call to a fixed contract address is executed. Make sure " diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 48b32eab..a607a00e 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -1,14 +1,15 @@ """This module contains the detection code for integer overflows and underflows.""" + +import json + from mythril.analysis import solver from mythril.analysis.report import Issue from mythril.analysis.swc_data import INTEGER_OVERFLOW_AND_UNDERFLOW from mythril.exceptions import UnsatError from mythril.laser.ethereum.state.global_state import GlobalState -from mythril.laser.ethereum.taint_analysis import TaintRunner from mythril.analysis.modules.base import DetectionModule - from mythril.laser.smt import ( BVAddNoOverflow, BVSubNoUnderflow, @@ -19,7 +20,6 @@ from mythril.laser.smt import ( Expression, ) -import copy import logging @@ -169,11 +169,13 @@ class IntegerOverflowUnderflowModule(DetectionModule): ) try: - issue.debug = str( - solver.get_transaction_sequence( + + transaction_sequence = olver.get_transaction_sequence( state, node.constraints + [annotation.constraint] ) - ) + + issue.debug = json.dumps(transaction_sequence, indent=4) + except UnsatError: return self._issues.append(issue) @@ -211,11 +213,13 @@ class IntegerOverflowUnderflowModule(DetectionModule): ) try: - issue.debug = str( - solver.get_transaction_sequence( - state, node.constraints + [annotation.constraint] - ) + + transaction_sequence = solver.get_transaction_sequence( + state, node.constraints + [annotation.constraint] ) + + issue.debug = json.dumps(transaction_sequence, indent=4) + except UnsatError: return self._issues.append(issue) diff --git a/mythril/analysis/modules/suicide.py b/mythril/analysis/modules/suicide.py index 79dfdd52..b56896ff 100644 --- a/mythril/analysis/modules/suicide.py +++ b/mythril/analysis/modules/suicide.py @@ -5,6 +5,7 @@ from mythril.exceptions import UnsatError from mythril.analysis.modules.base import DetectionModule from mythril.laser.ethereum.state.global_state import GlobalState import logging +import json log = logging.getLogger(__name__) @@ -40,7 +41,7 @@ def _analyze_state(state): "the contract balance is sent." ) - debug = str(transaction_sequence) + debug = json.dumps(transaction_sequence, indent=4) issue = Issue( contract=node.contract_name, diff --git a/mythril/analysis/templates/report_as_text.jinja2 b/mythril/analysis/templates/report_as_text.jinja2 index 32d3cf02..08edb6cb 100644 --- a/mythril/analysis/templates/report_as_text.jinja2 +++ b/mythril/analysis/templates/report_as_text.jinja2 @@ -20,7 +20,7 @@ In file: {{ issue.filename }}:{{ issue.lineno }} {% endif %} {% if verbose and issue.debug %} -------------------- -DEBUGGING INFORMATION: +Transaction Sequence: {{ issue.debug }} {% endif %} From b598ce3afa799e0eb98520795e40041fa86a7059 Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Fri, 4 Jan 2019 17:13:02 +0700 Subject: [PATCH 41/56] A little bit of black --- mythril/analysis/modules/integer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index a607a00e..1629c374 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -170,9 +170,9 @@ class IntegerOverflowUnderflowModule(DetectionModule): try: - transaction_sequence = olver.get_transaction_sequence( - state, node.constraints + [annotation.constraint] - ) + transaction_sequence = solver.get_transaction_sequence( + state, node.constraints + [annotation.constraint] + ) issue.debug = json.dumps(transaction_sequence, indent=4) From 41cacff5518dd0737865b8ac110ee2161d76f657 Mon Sep 17 00:00:00 2001 From: JoranHonig Date: Fri, 4 Jan 2019 17:15:46 +0700 Subject: [PATCH 42/56] Update mythril/analysis/report.py Co-Authored-By: b-mueller --- mythril/analysis/report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 0722acf3..3a94f57d 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -134,7 +134,7 @@ class Report: self.meta = {} if source is not None: - self.source = source + self.source = source or Source() else: self.source = Source() From 924b1dd71c8b205b23789593d57c19870b0d594a Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Fri, 4 Jan 2019 17:21:18 +0700 Subject: [PATCH 43/56] Reformat report.py (again?) --- mythril/analysis/report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 3a94f57d..2eb33d88 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -134,7 +134,7 @@ class Report: self.meta = {} if source is not None: - self.source = source or Source() + self.source = source or Source() else: self.source = Source() From fb396024b2b6a6d208492f7443bd2c8d4afabb26 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 4 Jan 2019 20:44:02 +0530 Subject: [PATCH 44/56] Remove lines which are redundant after the bugfix --- mythril/solidity/soliditycontract.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mythril/solidity/soliditycontract.py b/mythril/solidity/soliditycontract.py index 16e3b576..d2669e7f 100644 --- a/mythril/solidity/soliditycontract.py +++ b/mythril/solidity/soliditycontract.py @@ -127,11 +127,7 @@ class SolidityContract(EVMContract): disassembly = self.creation_disassembly if constructor else self.disassembly mappings = self.constructor_mappings if constructor else self.mappings index = helper.get_instruction_index(disassembly.instruction_list, address) - if index is None: - index = helper.get_instruction_index( - self.creation_disassembly.instruction_list, address - ) - mappings = self.constructor_mappings + solidity_file = self.solidity_files[mappings[index].solidity_file_idx] filename = solidity_file.filename From b55880c0aa5b511507606d587475b7331c1817a0 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 4 Jan 2019 20:50:52 +0530 Subject: [PATCH 45/56] convert sourceList to snake case --- mythril/analysis/report.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 2eb33d88..f48de589 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -184,15 +184,15 @@ class Report: :return: """ _issues = [] - sourceList = [] + source_list = [] for key, issue in self.issues.items(): - if issue.bytecode_hash not in sourceList: - idx = len(sourceList) - sourceList.append(issue.bytecode_hash) + if issue.bytecode_hash not in source_list: + idx = len(source_list) + source_list.append(issue.bytecode_hash) else: - idx = sourceList.index(issue.bytecode_hash) + idx = source_list.index(issue.bytecode_hash) try: title = SWC_TO_TITLE[issue.swc_id] @@ -217,7 +217,7 @@ class Report: "issues": _issues, "sourceType": "raw-bytecode", "sourceFormat": "evm-byzantium-bytecode", - "sourceList": sourceList, + "sourceList": source_list, "meta": {}, } From 758c0d6cf89238353ddc2c563f158544edfd1781 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 4 Jan 2019 21:20:56 +0530 Subject: [PATCH 46/56] Add creation bytecode hash and remove unused statement in the Report class --- mythril/analysis/report.py | 4 ---- mythril/ethereum/evmcontract.py | 35 ++++++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index f48de589..6624e7ab 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -138,10 +138,6 @@ class Report: else: self.source = Source() - self.source_type = self.source.source_type - self.source_format = self.source.source_format - self.source_list = self.source.source_list - def sorted_issues(self): """ diff --git a/mythril/ethereum/evmcontract.py b/mythril/ethereum/evmcontract.py index ec43686c..cc84f81a 100644 --- a/mythril/ethereum/evmcontract.py +++ b/mythril/ethereum/evmcontract.py @@ -41,23 +41,48 @@ class EVMContract(persistent.Persistent): creation_code, enable_online_lookup=enable_online_lookup ) self._bytecode_hash = None + self._creation_bytecode_hash = None @property def bytecode_hash(self): + """ + + :return: runtime bytecode hash + """ if self._bytecode_hash is not None: return self._bytecode_hash + self._bytecode_hash = self._get_hash(self.code[2:]) + + return self._bytecode_hash + + @property + def creation_bytecode_hash(self): + """ + :return: Creation bytecode hash + """ + if self._creation_bytecode_hash is not None: + return self._creation_bytecode_hash + + self._creation_bytecode_hash = self._get_hash(self.creation_code[2:]) + + return self._creation_bytecode_hash + + @staticmethod + def _get_hash(code): + """ + :param code: bytecode + :return: Returns hash of the given bytecode + """ try: keccak = sha3.keccak_256() - keccak.update(bytes.fromhex(self.code[2:])) - self._bytecode_hash = "0x" + keccak.hexdigest() + keccak.update(bytes.fromhex(code[2:])) + return "0x" + keccak.hexdigest() except ValueError: log.debug( "Unable to change the bytecode to bytes. Bytecode: {}".format(code) ) - self._bytecode_hash = "" - - return self._bytecode_hash + return "" def as_dict(self): """ From feb58fa7e066331ca76bb279a62bdc885a0d2db8 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 4 Jan 2019 21:48:09 +0530 Subject: [PATCH 47/56] Add standardized functions for the description head, tail and title to avoid mistakes --- mythril/analysis/modules/integer.py | 61 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 1629c374..4589789b 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -124,6 +124,29 @@ class IntegerOverflowUnderflowModule(DetectionModule): stack[index] = symbol_factory.BitVecVal(value, 256) return stack[index] + @staticmethod + def _get_description_head(annotation, _type): + return "The binary {} can {}.".format(annotation.operator, _type.lower()) + + @staticmethod + def _get_description_tail(annotation, _type): + + return ( + "The operands of the {} operation are not sufficiently constrained. " + "The {} could therefore result in an integer {}. Prevent the {} by checking inputs " + "or ensure sure that the {} is caught by an assertion.".format( + annotation.operator, + annotation.operator, + _type.lower(), + _type.lower(), + _type.lower(), + ) + ) + + @staticmethod + def _get_title(_type): + return "Integer {}".format(_type) + def _handle_sstore(self, state): stack = state.mstate.stack value = stack[-2] @@ -139,32 +162,16 @@ class IntegerOverflowUnderflowModule(DetectionModule): ostate = annotation.overflowing_state node = ostate.node - description_head = "The binary {} can {}.".format( - annotation.operator, _type.lower() - ) - - description_tail = ( - "The operands of the {} operation are not sufficiently constrained. " - "The {} could therefore result in an integer {}. Prevent the {} by checking inputs " - "or ensure sure that the {} is caught by an assertion.".format( - annotation.operator, - annotation.operator, - _type.lower(), - _type.lower(), - _type.lower(), - ) - ) - issue = Issue( contract=node.contract_name, function_name=node.function_name, address=ostate.get_current_instruction()["address"], swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, bytecode=ostate.environment.code.bytecode, - title="Integer {}".format(_type), + title=self._get_title(_type), severity="High", - description_head=description_head, - description_tail=description_tail, + 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), ) @@ -190,25 +197,17 @@ class IntegerOverflowUnderflowModule(DetectionModule): ostate = annotation.overflowing_state node = ostate.node - description_tail = "The binary {} operation can result in an integer overflow.\n".format( - annotation.operator - ) - title = ( - "Integer Underflow" - if annotation.operator == "subtraction" - else "Integer Overflow" - ) - + _type = "Underflow" if annotation.operator == "subtraction" else "Overflow" issue = Issue( contract=node.contract_name, function_name=node.function_name, address=ostate.get_current_instruction()["address"], swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, bytecode=ostate.environment.code.bytecode, - title=title, + title=self._get_title(_type), severity="High", - description_head="The {} can overflow.".format(annotation.operator), - description_tail=description_tail, + 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), ) From 96f6c13548a5b4d78a1961ce28e3cf95aa70b67a Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 4 Jan 2019 22:19:12 +0530 Subject: [PATCH 48/56] Add the creation bytecode hash to source list --- mythril/support/source_support.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mythril/support/source_support.py b/mythril/support/source_support.py index a8e6f0b9..bcba839e 100644 --- a/mythril/support/source_support.py +++ b/mythril/support/source_support.py @@ -16,7 +16,7 @@ class Source: """ self.source_type = source_type self.source_format = source_format - self.source_list = [] + self.source_list = source_list or [] self.meta = meta def get_source_from_contracts_list(self, contracts): @@ -38,7 +38,10 @@ class Source: "raw-bytecode" if contracts[0].name == "MAIN" else "ethereum-address" ) for contract in contracts: - self.source_list.append(contract.bytecode_hash) + if contract.creation_code: + self.source_list.append(contract.creation_bytecode_hash) + else: + self.source_list.append(contract.bytecode_hash) else: assert False # Fail hard From 5d6e85441409a1102f3d7f482a0d584ed7131910 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Fri, 4 Jan 2019 22:25:25 +0530 Subject: [PATCH 49/56] Calculate hash on the fly in the report class --- mythril/ethereum/evmcontract.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/mythril/ethereum/evmcontract.py b/mythril/ethereum/evmcontract.py index cc84f81a..47a87f83 100644 --- a/mythril/ethereum/evmcontract.py +++ b/mythril/ethereum/evmcontract.py @@ -40,8 +40,6 @@ class EVMContract(persistent.Persistent): self.creation_disassembly = Disassembly( creation_code, enable_online_lookup=enable_online_lookup ) - self._bytecode_hash = None - self._creation_bytecode_hash = None @property def bytecode_hash(self): @@ -49,11 +47,7 @@ class EVMContract(persistent.Persistent): :return: runtime bytecode hash """ - if self._bytecode_hash is not None: - return self._bytecode_hash - self._bytecode_hash = self._get_hash(self.code[2:]) - - return self._bytecode_hash + return self._get_hash(self.code[2:]) @property def creation_bytecode_hash(self): @@ -61,12 +55,7 @@ class EVMContract(persistent.Persistent): :return: Creation bytecode hash """ - if self._creation_bytecode_hash is not None: - return self._creation_bytecode_hash - - self._creation_bytecode_hash = self._get_hash(self.creation_code[2:]) - - return self._creation_bytecode_hash + return self._get_hash(self.creation_code[2:]) @staticmethod def _get_hash(code): From 6762e00905dfb3ae75faa1c48ff17dc04d15d6ac Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sun, 6 Jan 2019 17:14:36 +0530 Subject: [PATCH 50/56] Remove print statement --- mythril/analysis/modules/integer.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 8a0ac431..fbefd947 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -225,13 +225,6 @@ class IntegerOverflowUnderflowModule(DetectionModule): annotation.operator, title.lower() ) address = ostate.get_current_instruction()["address"] - print( - self._overflow_cache, - self._underflow_cache, - address, - issue.address, - [_issue.address for _issue in self._issues], - ) if annotation.operator == "subtraction" and self._underflow_cache.get( address, False From 30c8a115935d6dfc795745f32282996e07dcaf43 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Mon, 7 Jan 2019 15:20:34 +0530 Subject: [PATCH 51/56] Cache the suicide module's output --- mythril/analysis/modules/suicide.py | 102 ++++++++++++++++------------ 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/mythril/analysis/modules/suicide.py b/mythril/analysis/modules/suicide.py index 4f5eb28f..d421d786 100644 --- a/mythril/analysis/modules/suicide.py +++ b/mythril/analysis/modules/suicide.py @@ -14,50 +14,6 @@ For kill-able contracts, also check whether it is possible to direct the contrac """ -def _analyze_state(state): - log.info("Suicide module: Analyzing suicide instruction") - node = state.node - instruction = state.get_current_instruction() - to = state.mstate.stack[-1] - - log.debug("[SUICIDE] SUICIDE in function " + node.function_name) - - try: - try: - transaction_sequence = solver.get_transaction_sequence( - state, - node.constraints + [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF], - ) - description = "Anyone can kill this contract and withdraw its balance to their own account." - except UnsatError: - transaction_sequence = solver.get_transaction_sequence( - state, node.constraints - ) - description = ( - "The contract can be killed by anyone. Don't accidentally kill it." - ) - - debug = str(transaction_sequence) - - issue = Issue( - contract=node.contract_name, - function_name=node.function_name, - address=instruction["address"], - swc_id=UNPROTECTED_SELFDESTRUCT, - bytecode=state.environment.code.bytecode, - title="Unchecked SUICIDE", - _type="Warning", - description=description, - debug=debug, - gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), - ) - return [issue] - except UnsatError: - log.info("[UNCHECKED_SUICIDE] no model found") - - return [] - - class SuicideModule(DetectionModule): """This module checks if the contact can be 'accidentally' killed by anyone.""" @@ -70,6 +26,15 @@ class SuicideModule(DetectionModule): entrypoint="callback", pre_hooks=["SUICIDE"], ) + self._cache_address = {} + + def reset_module(self): + """ + Resets the module + :return: + """ + super().reset_module() + self._cache_address = {} def execute(self, state: GlobalState): """ @@ -77,8 +42,55 @@ class SuicideModule(DetectionModule): :param state: :return: """ - self._issues.extend(_analyze_state(state)) + self._issues.extend(self._analyze_state(state)) return self.issues + def _analyze_state(self, state): + log.info("Suicide module: Analyzing suicide instruction") + node = state.node + instruction = state.get_current_instruction() + if self._cache_address.get(instruction["address"], False): + return [] + to = state.mstate.stack[-1] + + log.debug("[SUICIDE] SUICIDE in function " + node.function_name) + + try: + try: + transaction_sequence = solver.get_transaction_sequence( + state, + node.constraints + + [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF], + ) + description = "Anyone can kill this contract and withdraw its balance to their own account." + except UnsatError: + transaction_sequence = solver.get_transaction_sequence( + state, node.constraints + ) + description = ( + "The contract can be killed by anyone. Don't accidentally kill it." + ) + + debug = str(transaction_sequence) + + self._cache_address[instruction["address"]] = True + issue = Issue( + contract=node.contract_name, + function_name=node.function_name, + address=instruction["address"], + swc_id=UNPROTECTED_SELFDESTRUCT, + bytecode=state.environment.code.bytecode, + title="Unchecked SUICIDE", + _type="Warning", + description=description, + debug=debug, + gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), + ) + return [issue] + except UnsatError: + log.info("[UNCHECKED_SUICIDE] no model found") + + return [] + detector = SuicideModule() From 6a59cb4954e3c513824d72d2c4aa86dd0a7700c3 Mon Sep 17 00:00:00 2001 From: Nathan Date: Mon, 7 Jan 2019 11:28:21 -0500 Subject: [PATCH 52/56] Implement special case for the delegatecall proxy pattern --- mythril/laser/ethereum/call.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/mythril/laser/ethereum/call.py b/mythril/laser/ethereum/call.py index a376443c..219aa804 100644 --- a/mythril/laser/ethereum/call.py +++ b/mythril/laser/ethereum/call.py @@ -4,6 +4,7 @@ parameters for the new global state.""" import logging from typing import Union, List +from z3 import Z3Exception from mythril.laser.ethereum import natives from mythril.laser.ethereum.gas import OPCODE_GAS @@ -179,16 +180,26 @@ def get_call_data( ) try: - calldata_from_mem = state.memory[ - util.get_concrete_int(memory_start) : util.get_concrete_int( - memory_start + memory_size + uses_entire_calldata = False + try: + uses_entire_calldata = simplify( + memory_size - global_state.environment.calldata.calldatasize == 0 ) - ] - call_data = ConcreteCalldata(transaction_id, calldata_from_mem) - log.debug("Calldata: " + str(call_data)) + except Z3Exception: + pass + + if uses_entire_calldata: + call_data = global_state.environment.calldata + else: + calldata_from_mem = state.memory[ + util.get_concrete_int(memory_start) : util.get_concrete_int( + memory_start + memory_size + ) + ] + call_data = ConcreteCalldata(transaction_id, calldata_from_mem) except TypeError: log.debug("Unsupported symbolic calldata offset") - call_data = SymbolicCalldata("{}_internalcall".format(transaction_id)) + call_data = SymbolicCalldata(transaction_id) return call_data From 30d3b9a74ee0c0b5e240836373ffe73a9bcd092d Mon Sep 17 00:00:00 2001 From: Nathan Date: Mon, 7 Jan 2019 14:15:13 -0500 Subject: [PATCH 53/56] Cleanup get_call_data --- mythril/laser/ethereum/call.py | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/mythril/laser/ethereum/call.py b/mythril/laser/ethereum/call.py index 219aa804..e99e60cd 100644 --- a/mythril/laser/ethereum/call.py +++ b/mythril/laser/ethereum/call.py @@ -179,29 +179,23 @@ def get_call_data( else memory_size ) + uses_entire_calldata = simplify( + memory_size - global_state.environment.calldata.calldatasize == 0 + ) + + if uses_entire_calldata == True: + return global_state.environment.calldata + try: - uses_entire_calldata = False - try: - uses_entire_calldata = simplify( - memory_size - global_state.environment.calldata.calldatasize == 0 + calldata_from_mem = state.memory[ + util.get_concrete_int(memory_start) : util.get_concrete_int( + memory_start + memory_size ) - except Z3Exception: - pass - - if uses_entire_calldata: - call_data = global_state.environment.calldata - else: - calldata_from_mem = state.memory[ - util.get_concrete_int(memory_start) : util.get_concrete_int( - memory_start + memory_size - ) - ] - call_data = ConcreteCalldata(transaction_id, calldata_from_mem) + ] + return ConcreteCalldata(transaction_id, calldata_from_mem) except TypeError: log.debug("Unsupported symbolic calldata offset") - call_data = SymbolicCalldata(transaction_id) - - return call_data + return SymbolicCalldata(transaction_id) def native_call( From 7491fa6dbf4f01c33e4f2a1d054995fdaabfcd45 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Tue, 8 Jan 2019 17:18:11 +0530 Subject: [PATCH 54/56] Remove redundant If condition in report.py and remove postfix assignment in tests --- mythril/analysis/report.py | 6 +----- tests/report_test.py | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 6624e7ab..a8e77db5 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -132,11 +132,7 @@ class Report: self.verbose = verbose self.solc_version = "" self.meta = {} - - if source is not None: - self.source = source or Source() - else: - self.source = Source() + self.source = source or Source() def sorted_issues(self): """ diff --git a/tests/report_test.py b/tests/report_test.py index 34ddba0d..09f2d3fc 100644 --- a/tests/report_test.py +++ b/tests/report_test.py @@ -79,7 +79,6 @@ def _assert_empty(changed_files, postfix): def _assert_empty_json(changed_files, postfix=".json"): """Asserts there are no changed files and otherwise builds error message.""" - postfix = ".json" expected = [] actual = [] From b85f2592bddcb24a9e9d87519156aae743aaffd0 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Tue, 8 Jan 2019 17:40:26 +0530 Subject: [PATCH 55/56] Remove the else condition to handle both creation code and runtime code --- mythril/support/source_support.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/support/source_support.py b/mythril/support/source_support.py index bcba839e..c774a425 100644 --- a/mythril/support/source_support.py +++ b/mythril/support/source_support.py @@ -40,7 +40,7 @@ class Source: for contract in contracts: if contract.creation_code: self.source_list.append(contract.creation_bytecode_hash) - else: + if contract.code: self.source_list.append(contract.bytecode_hash) else: From eab736d3efbff9946a2ccf13a0763801784ed55c Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Tue, 8 Jan 2019 21:14:20 +0530 Subject: [PATCH 56/56] Add a function which returns address in integer module --- mythril/analysis/modules/integer.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index fbefd947..89057b5b 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -65,7 +65,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): :param state: Statespace to analyse :return: Found issues """ - address = state.get_current_instruction()["address"] + address = _get_address_from_state(state) has_overflow = self._overflow_cache.get(address, False) has_underflow = self._underflow_cache.get(address, False) if has_overflow or has_underflow: @@ -169,7 +169,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): issue.description = "This binary {} operation can result in {}.\n".format( annotation.operator, title.lower() ) - address = ostate.get_current_instruction()["address"] + address = _get_address_from_state(ostate) if annotation.operator == "subtraction" and self._underflow_cache.get( address, False @@ -224,7 +224,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): issue.description = "This binary {} operation can result in {}.\n".format( annotation.operator, title.lower() ) - address = ostate.get_current_instruction()["address"] + address = _get_address_from_state(ostate) if annotation.operator == "subtraction" and self._underflow_cache.get( address, False @@ -264,3 +264,7 @@ class IntegerOverflowUnderflowModule(DetectionModule): detector = IntegerOverflowUnderflowModule() + + +def _get_address_from_state(state): + return state.get_current_instruction()["address"]