mirror of https://github.com/ConsenSys/mythril
blockchainethereumsmart-contractssoliditysecurityprogram-analysissecurity-analysissymbolic-execution
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.1 KiB
99 lines
3.1 KiB
import json
|
|
|
|
import pytest
|
|
from utils import output_of
|
|
|
|
from tests import PROJECT_DIR, TESTDATA
|
|
|
|
MYTH = str(PROJECT_DIR / "myth")
|
|
test_data = (
|
|
(
|
|
"flag_array.sol.o",
|
|
{
|
|
"TX_COUNT": 1,
|
|
"TX_OUTPUT": 1,
|
|
"MODULE": "EtherThief",
|
|
"ISSUE_COUNT": 1,
|
|
"ISSUE_NUMBER": 0,
|
|
},
|
|
"0xab12585800000000000000000000000000000000000000000000000000000000000004d2",
|
|
),
|
|
(
|
|
"exceptions_0.8.0.sol.o",
|
|
{
|
|
"TX_COUNT": 1,
|
|
"TX_OUTPUT": 1,
|
|
"MODULE": "Exceptions",
|
|
"ISSUE_COUNT": 2,
|
|
"ISSUE_NUMBER": 0,
|
|
},
|
|
None,
|
|
),
|
|
(
|
|
"symbolic_exec_bytecode.sol.o",
|
|
{
|
|
"TX_COUNT": 1,
|
|
"TX_OUTPUT": 0,
|
|
"MODULE": "AccidentallyKillable",
|
|
"ISSUE_COUNT": 1,
|
|
"ISSUE_NUMBER": 0,
|
|
},
|
|
None,
|
|
),
|
|
(
|
|
"extcall.sol.o",
|
|
{
|
|
"TX_COUNT": 1,
|
|
"TX_OUTPUT": 0,
|
|
"MODULE": "Exceptions",
|
|
"ISSUE_COUNT": 1,
|
|
"ISSUE_NUMBER": 0,
|
|
},
|
|
None,
|
|
),
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("file_name, tx_data, calldata", test_data)
|
|
def test_analysis(file_name, tx_data, calldata):
|
|
bytecode_file = str(TESTDATA / "inputs" / file_name)
|
|
command = f"""python3 {MYTH} analyze -f {bytecode_file} -t {tx_data["TX_COUNT"]} -o jsonv2 -m {tx_data["MODULE"]} --solver-timeout 60000 --no-onchain-data"""
|
|
output = json.loads(output_of(command))
|
|
|
|
assert len(output[0]["issues"]) == tx_data["ISSUE_COUNT"]
|
|
if calldata:
|
|
test_case = output[0]["issues"][tx_data["ISSUE_NUMBER"]]["extra"]["testCases"][
|
|
0
|
|
]
|
|
assert test_case["steps"][tx_data["TX_OUTPUT"]]["input"] == calldata
|
|
|
|
|
|
@pytest.mark.parametrize("file_name, tx_data, calldata", test_data)
|
|
def test_analysis_pending(file_name, tx_data, calldata):
|
|
bytecode_file = str(TESTDATA / "inputs" / file_name)
|
|
command = f"""python3 {MYTH} analyze -f {bytecode_file} -t {tx_data["TX_COUNT"]} -o jsonv2 -m {tx_data["MODULE"]} --solver-timeout 60000 --strategy pending --no-onchain-data"""
|
|
output = json.loads(output_of(command))
|
|
|
|
assert len(output[0]["issues"]) == tx_data["ISSUE_COUNT"]
|
|
if calldata:
|
|
test_case = output[0]["issues"][tx_data["ISSUE_NUMBER"]]["extra"]["testCases"][
|
|
0
|
|
]
|
|
assert test_case["steps"][tx_data["TX_OUTPUT"]]["input"] == calldata
|
|
|
|
|
|
test_data_code = [
|
|
("114", f"{TESTDATA}/input_contracts/tx.sol", True),
|
|
("123", f"{TESTDATA}/input_contracts/requirements_violation_pos.sol", True),
|
|
("123", f"{TESTDATA}/input_contracts/requirements_violation_neg.sol", False),
|
|
("132", f"{TESTDATA}/input_contracts/unexpected_ether_pos.sol", True),
|
|
("132", f"{TESTDATA}/input_contracts/unexpected_ether_neg.sol", False),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize("swc, file_path, exists", test_data_code)
|
|
def test_analysis_code(swc, file_path, exists):
|
|
assert (
|
|
"SWC ID: {}".format(swc)
|
|
in output_of(f"python3 {MYTH} a {file_path} --solver-timeout 5000")
|
|
) == exists
|
|
|