Add more tests

pull/22/head
Bernhard Mueller 7 years ago
parent dd5c4fb7a6
commit d5242df5cf
  1. 21
      myth
  2. 19
      tests/cmline_test.py
  3. 15
      tests/testdata/metacoin.sol

21
myth

@ -13,6 +13,7 @@ from mythril.rpc.client import EthJsonRpc
from mythril.ipc.client import EthIpc from mythril.ipc.client import EthIpc
from ethereum import utils from ethereum import utils
from laser.ethereum import laserfree from laser.ethereum import laserfree
from pathlib import Path
import logging import logging
import sys import sys
import argparse import argparse
@ -33,21 +34,22 @@ def exitWithError(message):
parser = argparse.ArgumentParser(description='Bug hunting on the Ethereum blockchain') parser = argparse.ArgumentParser(description='Bug hunting on the Ethereum blockchain')
parser.add_argument("solidity_file", nargs='*')
commands = parser.add_argument_group('commands') commands = parser.add_argument_group('commands')
commands.add_argument('-d', '--disassemble', action='store_true', help='disassemble') commands.add_argument('-d', '--disassemble', action='store_true', help='disassemble')
commands.add_argument('-g', '--graph', help='generate a control flow graph', metavar='OUTPUT_FILE') commands.add_argument('-g', '--graph', help='generate a control flow graph', metavar='OUTPUT_FILE')
commands.add_argument('-x', '--fire-lasers', action='store_true', help='detect vulnerabilities') commands.add_argument('-x', '--fire-lasers', action='store_true', help='detect vulnerabilities')
commands.add_argument('-t', '--trace', action='store_true', help='trace, use with -c or -a and --data (optional)') commands.add_argument('-t', '--trace', action='store_true', help='trace contract, use with --data (optional)')
commands.add_argument('-s', '--search', help='search the contract database') commands.add_argument('-s', '--search', help='search the contract database', metavar='EXPRESSION')
commands.add_argument('--xrefs', action='store_true', help='get xrefs from a contract, use with -c or -a') commands.add_argument('--xrefs', action='store_true', help='get xrefs from a contract')
commands.add_argument('--hash', help='calculate function signature hash', metavar='SIGNATURE') commands.add_argument('--hash', help='calculate function signature hash', metavar='SIGNATURE')
commands.add_argument('--init-db', action='store_true', help='initialize the contract database') commands.add_argument('--init-db', action='store_true', help='initialize the contract database')
inputs = parser.add_argument_group('input arguments') inputs = parser.add_argument_group('input arguments')
inputs.add_argument('-c', '--code', help='hex-encoded bytecode string ("6060604052...")', metavar='BYTECODE') inputs.add_argument('-c', '--code', help='hex-encoded bytecode string ("6060604052...")', metavar='BYTECODE')
inputs.add_argument('-i', '--infiles', help='comma-separated list of solidity files', metavar='INPUT_FILES') inputs.add_argument('-a', '--address', help='pull contract from the blockchain', metavar='CONTRACT_ADDRESS')
inputs.add_argument('-a', '--address', help='pull contract from the mainnet', metavar='CONTRACT_ADDRESS')
inputs.add_argument('--data', help='message call input data for tracing') inputs.add_argument('--data', help='message call input data for tracing')
options = parser.add_argument_group('options') options = parser.add_argument_group('options')
@ -105,7 +107,7 @@ if args.search or args.init_db:
# Establish RPC/IPC connection if necessary # Establish RPC/IPC connection if necessary
if (args.address or args.infiles): if (args.address or len(args.solidity_file)):
if args.ipc: if args.ipc:
try: try:
eth = EthIpc() eth = EthIpc()
@ -127,13 +129,12 @@ if (args.code):
contracts.append(ETHContract(args.code, address = util.get_random_address())) contracts.append(ETHContract(args.code, address = util.get_random_address()))
elif (args.address): elif (args.address):
contracts.append(ETHContract(eth.eth_getCode(args.address), address = args.address)) contracts.append(ETHContract(eth.eth_getCode(args.address), address = args.address))
elif (args.infiles): elif (len(args.solidity_file)):
files = args.infiles.split(",")
counter = 0 counter = 0
for file in files: for file in args.solidity_file:
file = file.replace("~", str(Path.home())) # Expand user path
name, bytecode = compile_solidity(solc_binary, file) name, bytecode = compile_solidity(solc_binary, file)
# Max. 16 contracts supported # Max. 16 contracts supported

@ -0,0 +1,19 @@
import unittest
import os
from subprocess import check_output
class CommandLineToolTestCase(unittest.TestCase):
def runTest(self):
script_path = os.path.dirname(os.path.realpath(__file__))
myth = os.path.join(script_path, '..', 'myth')
out = check_output([myth,'-d','-c', '0x5050']).decode("UTF-8")
self.assertEqual('0 POP\n1 POP\n', out)
out = check_output([myth,'-d', os.path.join(script_path,'testdata','metacoin.sol')]).decode("UTF-8")
self.assertIn('0 PUSH1 0x60\n2 PUSH1 0x40', out)

@ -0,0 +1,15 @@
pragma solidity ^0.4.17;
contract metaCoin {
mapping (address => uint) public balances;
function metaCoin() public {
balances[msg.sender] = 10000;
}
function sendToken(address receiver, uint amount) public returns(bool successful){
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
return false;
}
}
Loading…
Cancel
Save