From 02534db7bd711906b3a6da22e433d292f176e0e6 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Mon, 11 Mar 2019 21:31:49 +0530 Subject: [PATCH 01/11] Fix the jsonv2 format when file is source file --- mythril/analysis/report.py | 36 ++++++++----------------------- mythril/ethereum/evmcontract.py | 29 ++++++------------------- mythril/mythril.py | 4 +--- mythril/support/source_support.py | 15 ++++++++----- mythril/support/support_utils.py | 18 ++++++++++++++++ tests/report_test.py | 2 +- 6 files changed, 45 insertions(+), 59 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 46795b8d..8b0ce31e 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -3,13 +3,13 @@ import logging import json import operator 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 from mythril.support.start_time import StartTime +from mythril.support.support_utils import get_code_hash from time import time log = logging.getLogger(__name__) @@ -62,20 +62,7 @@ class Issue: self.lineno = None self.source_mapping = None self.discovery_time = time() - StartTime().global_start_time - - try: - keccak = sha3.keccak_256() - keccak.update( - bytes.fromhex(bytecode[2:]) - if bytecode[:2] == "0x" - else 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.bytecode_hash = get_code_hash(bytecode) @property def as_dict(self): @@ -130,7 +117,7 @@ class Report: loader=PackageLoader("mythril.analysis"), trim_blocks=True ) - def __init__(self, verbose=False, source=None): + def __init__(self, verbose=False, contracts=None): """ :param verbose: @@ -139,7 +126,8 @@ class Report: self.verbose = verbose self.solc_version = "" self.meta = {} - self.source = source or Source() + self.source = Source() + self.source.get_source_from_contracts_list(contracts) def sorted_issues(self): """ @@ -187,12 +175,7 @@ class Report: for key, issue in self.issues.items(): - if issue.bytecode_hash not in source_list: - idx = len(source_list) - source_list.append(issue.bytecode_hash) - else: - idx = source_list.index(issue.bytecode_hash) - + idx = self.source.get_source_index(issue.bytecode_hash) try: title = SWC_TO_TITLE[issue.swc_id] except KeyError: @@ -211,13 +194,12 @@ class Report: "extra": {}, } ) - result = [ { "issues": _issues, - "sourceType": "raw-bytecode", - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": source_list, + "sourceType": self.source.source_type, + "sourceFormat": self.source.source_format, + "sourceList": self.source.source_list, "meta": {}, } ] diff --git a/mythril/ethereum/evmcontract.py b/mythril/ethereum/evmcontract.py index 47a87f83..8502058f 100644 --- a/mythril/ethereum/evmcontract.py +++ b/mythril/ethereum/evmcontract.py @@ -1,15 +1,14 @@ """This module contains the class representing EVM contracts, aka Smart Contracts.""" import re -import _pysha3 as sha3 import logging - -log = logging.getLogger(__name__) - import persistent -from ethereum import utils +from ethereum import utils from mythril.disassembler.disassembly import Disassembly +from mythril.support.support_utils import get_code_hash + +log = logging.getLogger(__name__) class EVMContract(persistent.Persistent): @@ -47,7 +46,7 @@ class EVMContract(persistent.Persistent): :return: runtime bytecode hash """ - return self._get_hash(self.code[2:]) + return get_code_hash(self.code) @property def creation_bytecode_hash(self): @@ -55,23 +54,7 @@ class EVMContract(persistent.Persistent): :return: Creation bytecode hash """ - return self._get_hash(self.creation_code[2:]) - - @staticmethod - def _get_hash(code): - """ - :param code: bytecode - :return: Returns hash of the given bytecode - """ - try: - keccak = sha3.keccak_256() - keccak.update(bytes.fromhex(code[2:])) - return "0x" + keccak.hexdigest() - except ValueError: - log.debug( - "Unable to change the bytecode to bytes. Bytecode: {}".format(code) - ) - return "" + return get_code_hash(self.creation_code) def as_dict(self): """ diff --git a/mythril/mythril.py b/mythril/mythril.py index 4654b235..632bfbc5 100644 --- a/mythril/mythril.py +++ b/mythril/mythril.py @@ -607,10 +607,8 @@ class Mythril(object): all_issues += issues log.info("Solver statistics: \n{}".format(str(SolverStatistics()))) - source_data = Source() - source_data.get_source_from_contracts_list(self.contracts) # Finally, output the results - report = Report(verbose_report, source_data) + report = Report(verbose_report, self.contracts) for issue in all_issues: report.append_issue(issue) diff --git a/mythril/support/source_support.py b/mythril/support/source_support.py index c774a425..68d7a6aa 100644 --- a/mythril/support/source_support.py +++ b/mythril/support/source_support.py @@ -5,9 +5,7 @@ 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 - ): + def __init__(self, source_type=None, source_format=None, source_list=None): """ :param source_type: whether it is a solidity-file or evm-bytecode :param source_format: whether it is bytecode, ethereum-address or text @@ -17,7 +15,7 @@ class Source: self.source_type = source_type self.source_format = source_format self.source_list = source_list or [] - self.meta = meta + self._source_hash = [] def get_source_from_contracts_list(self, contracts): """ @@ -32,16 +30,23 @@ class Source: self.source_format = "text" for contract in contracts: self.source_list += [file.filename for file in contract.solidity_files] + self._source_hash.append(contract.bytecode_hash) elif isinstance(contracts[0], EVMContract): self.source_format = "evm-byzantium-bytecode" self.source_type = ( - "raw-bytecode" if contracts[0].name == "MAIN" else "ethereum-address" + "ethereum-address" + if len(contracts[0].name) == 42 and contracts[0].name[0:2] == "0x" + else "raw-bytecode" ) for contract in contracts: if contract.creation_code: self.source_list.append(contract.creation_bytecode_hash) if contract.code: self.source_list.append(contract.bytecode_hash) + self._source_hash = self.source_list else: assert False # Fail hard + + def get_source_index(self, bytecode_hash): + return self._source_hash.index(bytecode_hash) diff --git a/mythril/support/support_utils.py b/mythril/support/support_utils.py index b437d795..71178871 100644 --- a/mythril/support/support_utils.py +++ b/mythril/support/support_utils.py @@ -1,5 +1,9 @@ """This module contains utility functions for the Mythril support package.""" from typing import Dict +import logging +import _pysha3 as sha3 + +log = logging.getLogger(__name__) class Singleton(type): @@ -20,3 +24,17 @@ class Singleton(type): if cls not in cls._instances: cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls] + + +def get_code_hash(code): + """ + :param code: bytecode + :return: Returns hash of the given bytecode + """ + try: + keccak = sha3.keccak_256() + keccak.update(bytes.fromhex(code[2:])) + return "0x" + keccak.hexdigest() + except ValueError: + log.debug("Unable to change the bytecode to bytes. Bytecode: {}".format(code)) + return "" diff --git a/tests/report_test.py b/tests/report_test.py index a95eb63d..5a1642b9 100644 --- a/tests/report_test.py +++ b/tests/report_test.py @@ -32,7 +32,7 @@ def _generate_report(input_file): ) issues = fire_lasers(sym) - report = Report() + report = Report(contracts=[contract]) for issue in issues: issue.filename = "test-filename.sol" report.append_issue(issue) From 31f3a4a5c388c7c021c103687fbc8c8a8a0be005 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sat, 23 Mar 2019 21:13:14 +0530 Subject: [PATCH 02/11] Make the hash function for generic case --- mythril/support/support_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mythril/support/support_utils.py b/mythril/support/support_utils.py index 71178871..6912ddd3 100644 --- a/mythril/support/support_utils.py +++ b/mythril/support/support_utils.py @@ -31,9 +31,10 @@ def get_code_hash(code): :param code: bytecode :return: Returns hash of the given bytecode """ + code = code[2:] if code[:2] == "0x" else code try: keccak = sha3.keccak_256() - keccak.update(bytes.fromhex(code[2:])) + keccak.update(bytes.fromhex(code)) return "0x" + keccak.hexdigest() except ValueError: log.debug("Unable to change the bytecode to bytes. Bytecode: {}".format(code)) From abff796a6edcb2a6f08843565cd7e5db1ab223dd Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sat, 23 Mar 2019 21:14:02 +0530 Subject: [PATCH 03/11] Change the tests according to the change in the new way --- .../testdata/outputs_expected/ether_send.sol.o.jsonv2 | 10 +--------- tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 | 10 +--------- tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 | 10 +--------- 3 files changed, 3 insertions(+), 27 deletions(-) diff --git a/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 b/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 index 0d1e9df5..81da4589 100644 --- a/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/ether_send.sol.o.jsonv2 @@ -1,9 +1 @@ -[ - { - "issues": [], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [], - "sourceType": "raw-bytecode" - } -] \ No newline at end of file +[{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x3746c7c2ae7b0d4c3f8b1905df9a7ea169b9f93bec68a10a00b4c9d27a18c6fb"], "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 0d1e9df5..725efe76 100644 --- a/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/metacoin.sol.o.jsonv2 @@ -1,9 +1 @@ -[ - { - "issues": [], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [], - "sourceType": "raw-bytecode" - } -] \ No newline at end of file +[{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x0e6f727bb3301e02d3be831bf34357522fd2f1d40e90dff8e2214553b06b5f6c"], "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 0d1e9df5..e6eb03cb 100644 --- a/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 +++ b/tests/testdata/outputs_expected/nonascii.sol.o.jsonv2 @@ -1,9 +1 @@ -[ - { - "issues": [], - "meta": {}, - "sourceFormat": "evm-byzantium-bytecode", - "sourceList": [], - "sourceType": "raw-bytecode" - } -] \ No newline at end of file +[{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x11a78eb09819f505ba4f10747e6d1f7a44480e602c67573b7abac2f733a85d93"], "sourceType": "raw-bytecode"}] \ No newline at end of file From 03d73e18b21ce36cd2113ff90ec1b00fe0ce488c Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sat, 23 Mar 2019 21:36:57 +0530 Subject: [PATCH 04/11] Add typehints and docs --- mythril/analysis/report.py | 1 - mythril/support/source_support.py | 7 ++++++- mythril/support/support_utils.py | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index 1ce5219b..44fede86 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -3,7 +3,6 @@ import logging import json import operator from jinja2 import PackageLoader, Environment - from typing import Dict, List import hashlib diff --git a/mythril/support/source_support.py b/mythril/support/source_support.py index 68d7a6aa..51d94ee8 100644 --- a/mythril/support/source_support.py +++ b/mythril/support/source_support.py @@ -48,5 +48,10 @@ class Source: else: assert False # Fail hard - def get_source_index(self, bytecode_hash): + def get_source_index(self, bytecode_hash: str) -> int: + """ + Find the contract index in the list + :param bytecode_hash: The contract hash + :return: The index of the contract in the _source_hash list + """ return self._source_hash.index(bytecode_hash) diff --git a/mythril/support/support_utils.py b/mythril/support/support_utils.py index 6912ddd3..1edbefff 100644 --- a/mythril/support/support_utils.py +++ b/mythril/support/support_utils.py @@ -26,7 +26,7 @@ class Singleton(type): return cls._instances[cls] -def get_code_hash(code): +def get_code_hash(code: str) -> str: """ :param code: bytecode :return: Returns hash of the given bytecode From 1a5a761bb6a8531e26507d973d168842db40dd89 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sun, 7 Apr 2019 22:36:27 +0530 Subject: [PATCH 05/11] Fix the merge conflict problem --- mythril/mythril/mythril_analyzer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/mythril/mythril_analyzer.py b/mythril/mythril/mythril_analyzer.py index e42e943c..5d0596e2 100644 --- a/mythril/mythril/mythril_analyzer.py +++ b/mythril/mythril/mythril_analyzer.py @@ -166,7 +166,7 @@ class MythrilAnalyzer: source_data = Source() source_data.get_source_from_contracts_list(self.contracts) # Finally, output the results - report = Report(verbose_report, source_data, exceptions=exceptions) + report = Report(verbose_report, contracts=self.contracts, exceptions=exceptions) for issue in all_issues: report.append_issue(issue) From 38daa586bd6756b62a7d1bbaeb0b4656e3b0d3dd Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Tue, 9 Apr 2019 01:39:09 +0530 Subject: [PATCH 06/11] Add creation hash to the code --- mythril/support/source_support.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mythril/support/source_support.py b/mythril/support/source_support.py index 51d94ee8..7de78c83 100644 --- a/mythril/support/source_support.py +++ b/mythril/support/source_support.py @@ -31,6 +31,7 @@ class Source: for contract in contracts: self.source_list += [file.filename for file in contract.solidity_files] self._source_hash.append(contract.bytecode_hash) + self._source_hash.append(contract.creation_bytecode_hash) elif isinstance(contracts[0], EVMContract): self.source_format = "evm-byzantium-bytecode" self.source_type = ( From 6b70e1e10a26da7ee6c6b9d1f5cd054f715bdf7c Mon Sep 17 00:00:00 2001 From: Dominik Muhs Date: Wed, 10 Apr 2019 15:07:05 +0200 Subject: [PATCH 07/11] Fix jsonv2 log format --- 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 4ba3b942..e1f73887 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -185,7 +185,7 @@ class Report: return {} logs = [] # type: List[Dict] for exception in self.exceptions: - logs += [{"level": "error", "hidden": "true", "error": exception}] + logs += [{"level": "error", "hidden": "true", "msg": exception}] return {"logs": logs} def as_swc_standard_format(self): From 7adb14c329e5dcc1c43c6fce7b0c283efa58f212 Mon Sep 17 00:00:00 2001 From: Dominik Muhs Date: Wed, 10 Apr 2019 15:58:27 +0200 Subject: [PATCH 08/11] Fix cli log format --- 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 514f039d..a3e00adb 100644 --- a/mythril/interfaces/cli.py +++ b/mythril/interfaces/cli.py @@ -47,7 +47,7 @@ def exit_with_error(format_, message): "sourceFormat": "", "sourceList": [], "meta": { - "logs": [{"level": "error", "hidden": "true", "error": message}] + "logs": [{"level": "error", "hidden": "true", "msg": message}] }, } ] From 7af06fe6f94bf677a7392ba6c724df1e591b08f9 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sat, 13 Apr 2019 00:38:38 +0530 Subject: [PATCH 09/11] Add the runtime bytecode to source list --- mythril/analysis/symbolic.py | 9 +++++++- mythril/disassembler/disassembly.py | 8 +++++-- mythril/laser/ethereum/state/account.py | 21 +++++++++++++++++-- mythril/laser/ethereum/state/world_state.py | 16 ++++++++++---- .../laser/ethereum/transaction/symbolic.py | 2 +- .../transaction/transaction_models.py | 2 +- mythril/support/source_support.py | 7 ++++++- 7 files changed, 53 insertions(+), 12 deletions(-) diff --git a/mythril/analysis/symbolic.py b/mythril/analysis/symbolic.py index 79f70efb..c195a498 100644 --- a/mythril/analysis/symbolic.py +++ b/mythril/analysis/symbolic.py @@ -2,6 +2,7 @@ purposes.""" import copy +from ethereum.utils import mk_contract_address from mythril.analysis.security import get_detection_module_hooks, get_detection_modules from mythril.laser.ethereum import svm from mythril.laser.ethereum.state.account import Account @@ -11,11 +12,12 @@ from mythril.laser.ethereum.strategy.basic import ( ReturnRandomNaivelyStrategy, ReturnWeightedRandomStrategy, ) +from mythril.laser.ethereum.transaction.symbolic import CREATOR_ADDRESS + from mythril.laser.ethereum.plugins.plugin_factory import PluginFactory from mythril.laser.ethereum.plugins.plugin_loader import LaserPluginLoader - from mythril.solidity.soliditycontract import EVMContract, SolidityContract from .ops import Call, SStore, VarType, get_variable @@ -110,6 +112,11 @@ class SymExecWrapper: ) else: self.laser.sym_exec(address) + created_address = "0x" + str(mk_contract_address(CREATOR_ADDRESS, 0).hex()) + for key, value in self.laser.world_state.accounts.items(): + if created_address == value.address: + contract.code = value.code.bytecode + break if not requires_statespace: return diff --git a/mythril/disassembler/disassembly.py b/mythril/disassembler/disassembly.py index 0cc1c8aa..595b2583 100644 --- a/mythril/disassembler/disassembly.py +++ b/mythril/disassembler/disassembly.py @@ -28,11 +28,15 @@ class Disassembly(object): self.func_hashes = [] # type: List[str] self.function_name_to_address = {} # type: Dict[str, int] self.address_to_function_name = {} # type: Dict[int, str] + self.enable_online_lookup = enable_online_lookup + self.assign_bytecode(bytecode=code) + def assign_bytecode(self, bytecode): + self.bytecode = bytecode # open from default locations # control if you want to have online signature hash lookups - signatures = SignatureDB(enable_online_lookup=enable_online_lookup) - + signatures = SignatureDB(enable_online_lookup=self.enable_online_lookup) + self.instruction_list = asm.disassemble(util.safe_decode(bytecode)) # Need to take from PUSH1 to PUSH4 because solc seems to remove excess 0s at the beginning for optimizing jump_table_indices = asm.find_op_code_sequence( [("PUSH1", "PUSH2", "PUSH3", "PUSH4"), ("EQ",)], self.instruction_list diff --git a/mythril/laser/ethereum/state/account.py b/mythril/laser/ethereum/state/account.py index c13c3f2f..e608246e 100644 --- a/mythril/laser/ethereum/state/account.py +++ b/mythril/laser/ethereum/state/account.py @@ -2,7 +2,7 @@ This includes classes representing accounts and their storage. """ - +from copy import deepcopy, copy from typing import Any, Dict, KeysView, Union from z3 import ExprRef @@ -61,6 +61,13 @@ class Storage: """ return self._storage.keys() + def __deepcopy__(self, memodict={}): + storage = Storage( + concrete=self.concrete, address=self.address, dynamic_loader=self.dynld + ) + storage._storage = copy(self._storage) + return storage + class Account: """Account class representing ethereum accounts.""" @@ -92,7 +99,6 @@ class Account: self.storage = Storage( concrete_storage, address=address, dynamic_loader=dynamic_loader ) - # Metadata self.address = address self.contract_name = contract_name @@ -128,3 +134,14 @@ class Account: "balance": self.balance, "storage": self.storage, } + + def __deepcopy__(self, memodict={}): + new_account = Account( + address=self.address, + code=self.code, + balance=self.balance, + contract_name=self.contract_name, + ) + new_account.storage = deepcopy(self.storage) + new_account.code = self.code + return new_account diff --git a/mythril/laser/ethereum/state/world_state.py b/mythril/laser/ethereum/state/world_state.py index 9e616934..862b7c8d 100644 --- a/mythril/laser/ethereum/state/world_state.py +++ b/mythril/laser/ethereum/state/world_state.py @@ -2,7 +2,7 @@ from copy import copy from random import randint from typing import Dict, List, Iterator, Optional, TYPE_CHECKING - +from ethereum.utils import mk_contract_address from mythril.laser.ethereum.state.account import Account from mythril.laser.ethereum.state.annotation import StateAnnotation @@ -50,7 +50,12 @@ class WorldState: return new_world_state def create_account( - self, balance=0, address=None, concrete_storage=False, dynamic_loader=None + self, + balance=0, + address=None, + concrete_storage=False, + dynamic_loader=None, + creator=None, ) -> Account: """Create non-contract account. @@ -60,7 +65,7 @@ class WorldState: :param dynamic_loader: used for dynamically loading storage from the block chain :return: The new account """ - address = address if address else self._generate_new_address() + address = address if address else self._generate_new_address(creator) new_account = Account( address, balance=balance, @@ -111,11 +116,14 @@ class WorldState: """ return filter(lambda x: isinstance(x, annotation_type), self.annotations) - def _generate_new_address(self) -> str: + def _generate_new_address(self, creator=None) -> str: """Generates a new address for the global state. :return: """ + if creator: + # TODO: Use nounce + return "0x" + str(mk_contract_address(creator, 0).hex()) while True: address = "0x" + "".join([str(hex(randint(0, 16)))[-1] for _ in range(40)]) if address not in self.accounts.keys(): diff --git a/mythril/laser/ethereum/transaction/symbolic.py b/mythril/laser/ethereum/transaction/symbolic.py index a827623e..def5048e 100644 --- a/mythril/laser/ethereum/transaction/symbolic.py +++ b/mythril/laser/ethereum/transaction/symbolic.py @@ -73,7 +73,7 @@ def execute_contract_creation( del laser_evm.open_states[:] new_account = laser_evm.world_state.create_account( - 0, concrete_storage=True, dynamic_loader=None + 0, concrete_storage=True, dynamic_loader=None, creator=CREATOR_ADDRESS ) if contract_name: new_account.contract_name = contract_name diff --git a/mythril/laser/ethereum/transaction/transaction_models.py b/mythril/laser/ethereum/transaction/transaction_models.py index def9a494..9ad5b76e 100644 --- a/mythril/laser/ethereum/transaction/transaction_models.py +++ b/mythril/laser/ethereum/transaction/transaction_models.py @@ -188,7 +188,7 @@ class ContractCreationTransaction(BaseTransaction): contract_code = bytes.hex(array.array("B", return_data).tostring()) - global_state.environment.active_account.code = Disassembly(contract_code) + global_state.environment.active_account.code.assign_bytecode(contract_code) self.return_data = global_state.environment.active_account.address assert global_state.environment.active_account.code.instruction_list != [] diff --git a/mythril/support/source_support.py b/mythril/support/source_support.py index 7de78c83..a7b0b5c8 100644 --- a/mythril/support/source_support.py +++ b/mythril/support/source_support.py @@ -55,4 +55,9 @@ class Source: :param bytecode_hash: The contract hash :return: The index of the contract in the _source_hash list """ - return self._source_hash.index(bytecode_hash) + # TODO: Add this part to exception logs + try: + return self._source_hash.index(bytecode_hash) + except ValueError: + self._source_hash.append(bytecode_hash) + return len(self._source_hash) - 1 From 44ed641f819df795e288e74315067f4ad9c8f84b Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sat, 13 Apr 2019 12:49:00 +0530 Subject: [PATCH 10/11] Update mythril to 0.20.4 --- mythril/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/version.py b/mythril/version.py index 07cb42e1..1c0dc71a 100644 --- a/mythril/version.py +++ b/mythril/version.py @@ -4,4 +4,4 @@ This file is suitable for sourcing inside POSIX shell, e.g. bash as well as for importing into Python. """ -VERSION = "v0.20.3" # NOQA +VERSION = "v0.20.4" # NOQA From 8967ea3090971d380f398169506ea61121541e98 Mon Sep 17 00:00:00 2001 From: Ooqu4 <46896955+Ooqu4@users.noreply.github.com> Date: Wed, 17 Apr 2019 06:06:09 +0200 Subject: [PATCH 11/11] Fix some minor typos (#1003) * Fix some minor typos * Revert wrong typo correction --- CONTRIBUTING.md | 2 +- mythril/interfaces/cli.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 38039960..7517c44a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ If you have a small question or aren't sure if you should create an issue for yo # Coding If you want to help out with the development of Mythril then you can take a look at our issues or [Waffle board](https://waffle.io/ConsenSys/mythril). -Before you start working on an issue pkease stop by on Discord to message a collaborator, this way we can assign you to the issue making sure nobody does double work. We can also provide you with support through Discord if there are any questions during the development process. +Before you start working on an issue please stop by on Discord to message a collaborator, this way we can assign you to the issue making sure nobody does double work. We can also provide you with support through Discord if there are any questions during the development process. ## New ideas Before you start working on a new idea, it's useful to create an issue on GitHub, that way we know what you want to implement and that you are working on it. Additionally, it might happen that your feature does not fit with our roadmap, in which case it would be unfortunate if you have already spent some time working on it. diff --git a/mythril/interfaces/cli.py b/mythril/interfaces/cli.py index a3e00adb..01524ad7 100644 --- a/mythril/interfaces/cli.py +++ b/mythril/interfaces/cli.py @@ -507,7 +507,7 @@ def parse_args(parser: argparse.ArgumentParser, args: argparse.Namespace) -> Non quick_commands(args) config = set_config(args) leveldb_search(config, args) - dissasembler = MythrilDisassembler( + disassembler = MythrilDisassembler( eth=config.eth, solc_version=args.solv, solc_args=args.solc_args, @@ -515,16 +515,16 @@ def parse_args(parser: argparse.ArgumentParser, args: argparse.Namespace) -> Non ) if args.truffle: try: - dissasembler.analyze_truffle_project(args) + disassembler.analyze_truffle_project(args) except FileNotFoundError: print( "Build directory not found. Make sure that you start the analysis from the project root, and that 'truffle compile' has executed successfully." ) sys.exit() - address = get_code(dissasembler, args) + address = get_code(disassembler, args) execute_command( - disassembler=dissasembler, address=address, parser=parser, args=args + disassembler=disassembler, address=address, parser=parser, args=args ) except CriticalError as ce: exit_with_error(args.outform, str(ce))