Remove truffle support (#1218)

* Remove truffle

* Fix black

* Remove truffle.py
pull/1246/head
Nikhil Parasaram 5 years ago committed by GitHub
parent f1a0c9db04
commit 07347e28ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      mythril/interfaces/cli.py
  2. 8
      mythril/interfaces/old_cli.py
  3. 11
      mythril/mythril/mythril_disassembler.py
  4. 205
      mythril/support/truffle.py
  5. 9
      tests/cmd_line_test.py
  6. 30
      tests/truffle_project/README.md
  7. 23
      tests/truffle_project/contracts/Migrations.sol
  8. 34
      tests/truffle_project/contracts/ether_send.sol
  9. 5
      tests/truffle_project/migrations/1_initial_migration.js
  10. 4
      tests/truffle_project/truffle-config.js
  11. 11
      tests/truffle_project/truffle.js

@ -769,15 +769,6 @@ def parse_args_and_execute(parser: ArgumentParser, args: Namespace) -> None:
solc_settings_json=solc_json, solc_settings_json=solc_json,
enable_online_lookup=query_signature, enable_online_lookup=query_signature,
) )
if args.command == "truffle":
try:
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 = load_code(disassembler, args) address = load_code(disassembler, args)
execute_command( execute_command(

@ -528,14 +528,6 @@ def parse_args(parser: argparse.ArgumentParser, args: argparse.Namespace) -> Non
solc_settings_json=args.solc_json, solc_settings_json=args.solc_json,
enable_online_lookup=args.query_signature, enable_online_lookup=args.query_signature,
) )
if args.truffle:
try:
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(disassembler, args) address = get_code(disassembler, args)
execute_command( execute_command(

@ -10,7 +10,6 @@ from mythril.ethereum import util
from mythril.ethereum.interface.rpc.client import EthJsonRpc from mythril.ethereum.interface.rpc.client import EthJsonRpc
from mythril.exceptions import CriticalError, CompilerError, NoContractFoundError from mythril.exceptions import CriticalError, CompilerError, NoContractFoundError
from mythril.support import signatures from mythril.support import signatures
from mythril.support.truffle import analyze_truffle_project
from mythril.ethereum.evmcontract import EVMContract from mythril.ethereum.evmcontract import EVMContract
from mythril.ethereum.interface.rpc.exceptions import ConnectionError from mythril.ethereum.interface.rpc.exceptions import ConnectionError
from mythril.solidity.soliditycontract import SolidityContract, get_contracts_from_file from mythril.solidity.soliditycontract import SolidityContract, get_contracts_from_file
@ -225,16 +224,6 @@ class MythrilDisassembler:
return address, contracts return address, contracts
def analyze_truffle_project(self, *args, **kwargs) -> None:
"""
:param args:
:param kwargs:
:return:
"""
analyze_truffle_project(
self.sigs, *args, **kwargs
) # just passthru by passing signatures for now
@staticmethod @staticmethod
def hash_for_function_signature(func: str) -> str: def hash_for_function_signature(func: str) -> str:
""" """

@ -1,205 +0,0 @@
"""This module contains functionality used to easily analyse Truffle
projects."""
import json
import logging
import os
import re
import sys
import warnings
from pathlib import PurePath
from ethereum.utils import sha3
from mythril.analysis.report import Report
from mythril.analysis.security import fire_lasers
from mythril.analysis.symbolic import SymExecWrapper
from mythril.ethereum import util
from mythril.ethereum.evmcontract import EVMContract
from mythril.laser.ethereum.util import get_instruction_index
from mythril.solidity.soliditycontract import SourceMapping
log = logging.getLogger(__name__)
def format_Warning(message, category, filename, lineno, line=""):
return "{}: {}\n\n".format(str(filename), str(message))
warnings.formatwarning = format_Warning
def analyze_truffle_project(sigs, args):
"""
:param sigs:
:param args:
"""
warnings.warn(
"The option --truffle is being deprecated, Please use the truffle-security plugin, https://github.com/ConsenSys/truffle-security",
FutureWarning,
)
project_root = os.getcwd()
build_dir = os.path.join(project_root, "build", "contracts")
files = os.listdir(build_dir)
for filename in files:
if re.match(r".*\.json$", filename) and filename != "Migrations.json":
with open(os.path.join(build_dir, filename)) as cf:
contractdata = json.load(cf)
try:
name = contractdata["contractName"]
bytecode = contractdata["deployedBytecode"]
filename = PurePath(contractdata["sourcePath"]).name
except KeyError:
print(
"Unable to parse contract data. Please use Truffle 4 to compile your project."
)
sys.exit()
if len(bytecode) < 4:
continue
get_sigs_from_truffle(sigs, contractdata)
ethcontract = EVMContract(bytecode, name=name)
address = util.get_indexed_address(0)
sym = SymExecWrapper(
ethcontract,
address,
args.strategy,
max_depth=args.max_depth,
create_timeout=args.create_timeout,
execution_timeout=args.execution_timeout,
transaction_count=args.transaction_count,
modules=args.modules or [],
compulsory_statespace=False,
)
issues = fire_lasers(sym)
if not len(issues):
if args.outform == "text" or args.outform == "markdown":
print("# Analysis result for " + name + "\n\nNo issues found.")
else:
result = {
"contract": name,
"result": {"success": True, "error": None, "issues": []},
}
print(json.dumps(result))
else:
report = Report()
# augment with source code
deployed_disassembly = ethcontract.disassembly
constructor_disassembly = ethcontract.creation_disassembly
source = contractdata["source"]
deployed_source_map = contractdata["deployedSourceMap"].split(";")
source_map = contractdata["sourceMap"].split(";")
deployed_mappings = get_mappings(source, deployed_source_map)
constructor_mappings = get_mappings(source, source_map)
for issue in issues:
if issue.function == "constructor":
mappings = constructor_mappings
disassembly = constructor_disassembly
else:
mappings = deployed_mappings
disassembly = deployed_disassembly
index = get_instruction_index(
disassembly.instruction_list, issue.address
)
if index:
try:
offset = mappings[index].offset
length = mappings[index].length
issue.filename = filename
issue.code = source.encode("utf-8")[
offset : offset + length
].decode("utf-8")
issue.lineno = mappings[index].lineno
except IndexError:
log.debug("No code mapping at index %d", index)
report.append_issue(issue)
if args.outform == "json":
result = {
"contract": name,
"result": {
"success": True,
"error": None,
"issues": list(map(lambda x: x.as_dict, issues)),
},
}
print(json.dumps(result))
else:
if args.outform == "text":
print(
"# Analysis result for " + name + ":\n\n" + report.as_text()
)
elif args.outform == "markdown":
print(report.as_markdown())
def get_sigs_from_truffle(sigs, contract_data):
"""
:param sigs:
:param contract_data:
"""
abis = contract_data["abi"]
for abi in abis:
if abi["type"] != "function":
continue
function_name = abi["name"]
list_of_args = ",".join([input["type"] for input in abi["inputs"]])
signature = function_name + "(" + list_of_args + ")"
sigs.add("0x" + sha3(signature)[:4].hex(), signature)
def get_mappings(source, deployed_source_map):
"""
:param source:
:param deployed_source_map:
:return:
"""
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:
offset = int(mapping[0])
if len(mapping) > 1 and len(mapping[1]) > 0:
length = int(mapping[1])
if len(mapping) > 2 and len(mapping[2]) > 0:
idx = int(mapping[2])
if idx == -1:
lineno = None
else:
lineno = source.encode("utf-8")[0:offset].count("\n".encode("utf-8")) + 1
prev_item = item
mappings.append(SourceMapping(idx, offset, length, lineno, item))
return mappings

@ -70,15 +70,6 @@ class CommandLineToolTestCase(BaseTestCase):
self.assertIn("0x1a270efc", output_of(command)) self.assertIn("0x1a270efc", output_of(command))
class TruffleTestCase(BaseTestCase):
def test_analysis_truffle_project(self):
truffle_project_root = str(TESTS_DIR / "truffle_project")
command = "cd {}; truffle compile; python3 {} truffle -t 2".format(
truffle_project_root, MYTH
)
self.assertIn("=== Unprotected Ether Withdrawal ====", output_of(command))
class InfuraTestCase(BaseTestCase): class InfuraTestCase(BaseTestCase):
def test_infura_mainnet(self): def test_infura_mainnet(self):
command = "python3 {} disassemble --rpc infura-mainnet -a 0x2a0c0dbecc7e4d658f48e01e3fa353f44050c208".format( command = "python3 {} disassemble --rpc infura-mainnet -a 0x2a0c0dbecc7e4d658f48e01e3fa353f44050c208".format(

@ -1,30 +0,0 @@
Truffle Hello World Demo
========================
```
npm install -g truffle ethereumjs-testrpc
```
This repo is created by following commands:
```
truffle init
truffle compile
```
In order to run `truffle migrate`, we need to setup `truffle.js` first:
```
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // Match any network id
}
}
```
Resources
---------
- <https://medium.com/etherereum-salon/eth-testing-472c2f73b4c3>

@ -1,23 +0,0 @@
pragma solidity ^0.4.17;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
function Migrations() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}

@ -1,34 +0,0 @@
contract Crowdfunding {
mapping(address => uint) public balances;
address public owner;
uint256 INVEST_MIN = 1 ether;
uint256 INVEST_MAX = 10 ether;
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function crowdfunding() {
owner = msg.sender;
}
function withdrawfunds() onlyOwner {
msg.sender.transfer(this.balance);
}
function invest() public payable {
require(msg.value > INVEST_MIN && msg.value < INVEST_MAX);
balances[msg.sender] += msg.value;
}
function getBalance() public constant returns (uint) {
return balances[msg.sender];
}
function() public payable {
invest();
}
}

@ -1,5 +0,0 @@
var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};

@ -1,4 +0,0 @@
module.exports = {
// See <http://truffleframework.com/docs/advanced/configuration>
// to customize your Truffle configuration!
};

@ -1,11 +0,0 @@
module.exports = {
// See <http://truffleframework.com/docs/advanced/configuration>
// to customize your Truffle configuration!
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // Match any network id
}
}
};
Loading…
Cancel
Save