mirror of https://github.com/ConsenSys/mythril
parent
f1a0c9db04
commit
07347e28ff
@ -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 |
|
@ -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…
Reference in new issue