|
|
|
@ -6,6 +6,7 @@ import json |
|
|
|
|
import logging |
|
|
|
|
from mythril.ether.ethcontract import ETHContract |
|
|
|
|
from mythril.ether.soliditycontract import SourceMapping |
|
|
|
|
from mythril.exceptions import CriticalError |
|
|
|
|
from mythril.analysis.security import fire_lasers |
|
|
|
|
from mythril.analysis.symbolic import SymExecWrapper |
|
|
|
|
from mythril.analysis.report import Report |
|
|
|
@ -14,7 +15,7 @@ from mythril.ether import util |
|
|
|
|
from mythril.laser.ethereum.util import get_instruction_index |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def analyze_truffle_project(args): |
|
|
|
|
def analyze_truffle_project(sigs, args): |
|
|
|
|
|
|
|
|
|
project_root = os.getcwd() |
|
|
|
|
|
|
|
|
@ -33,13 +34,17 @@ def analyze_truffle_project(args): |
|
|
|
|
name = contractdata['contractName'] |
|
|
|
|
bytecode = contractdata['deployedBytecode'] |
|
|
|
|
filename = PurePath(contractdata['sourcePath']).name |
|
|
|
|
except: |
|
|
|
|
abi = contractdata['abi'] |
|
|
|
|
except KeyError: |
|
|
|
|
print("Unable to parse contract data. Please use Truffle 4 to compile your project.") |
|
|
|
|
sys.exit() |
|
|
|
|
|
|
|
|
|
if (len(bytecode) < 4): |
|
|
|
|
if len(bytecode) < 4: |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
list_of_functions = parse_abi_for_functions(abi) |
|
|
|
|
sigs.signatures.update(sigs.get_sigs_from_functions(list_of_functions)) |
|
|
|
|
sigs.write() |
|
|
|
|
|
|
|
|
|
ethcontract = ETHContract(bytecode, name=name) |
|
|
|
|
|
|
|
|
|
address = util.get_indexed_address(0) |
|
|
|
@ -47,7 +52,7 @@ def analyze_truffle_project(args): |
|
|
|
|
issues = fire_lasers(sym) |
|
|
|
|
|
|
|
|
|
if not len(issues): |
|
|
|
|
if (args.outform == 'text' or args.outform == 'markdown'): |
|
|
|
|
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': []}} |
|
|
|
@ -97,13 +102,23 @@ def analyze_truffle_project(args): |
|
|
|
|
|
|
|
|
|
report.append_issue(issue) |
|
|
|
|
|
|
|
|
|
if (args.outform == 'json'): |
|
|
|
|
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'): |
|
|
|
|
if args.outform == 'text': |
|
|
|
|
print("# Analysis result for " + name + ":\n\n" + report.as_text()) |
|
|
|
|
elif (args.outform == 'markdown'): |
|
|
|
|
elif args.outform == 'markdown': |
|
|
|
|
print(report.as_markdown()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_abi_for_functions(abi): |
|
|
|
|
funcs = [] |
|
|
|
|
for data in abi: |
|
|
|
|
if data['type'] != 'function': |
|
|
|
|
continue |
|
|
|
|
args = '('+','.join([input['type'] for input in data['inputs']])+')' |
|
|
|
|
funcs.append(data['name']+args) |
|
|
|
|
return funcs |
|
|
|
|