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.
131 lines
3.9 KiB
131 lines
3.9 KiB
import pytest
|
|
from pathlib import Path
|
|
from mythril.mythril import MythrilDisassembler
|
|
from mythril.solidity.features import SolidityFeatureExtractor
|
|
from mythril.solidity.soliditycontract import SolidityContract, SolcAST
|
|
|
|
TEST_FILES = Path(__file__).parent / "testdata/input_contracts"
|
|
solc_binary_5 = MythrilDisassembler._init_solc_binary("v0.5.0")
|
|
solc_binary_8 = MythrilDisassembler._init_solc_binary("v0.8.0")
|
|
solc_binary_82 = MythrilDisassembler._init_solc_binary("v0.8.20")
|
|
|
|
|
|
test_cases = [
|
|
("suicide.sol", 1, "kill", "contains_selfdestruct", True, solc_binary_5),
|
|
(
|
|
"SimpleModifier.sol",
|
|
1,
|
|
"withdrawfunds",
|
|
"all_require_vars",
|
|
set(["msg", "owner"]),
|
|
solc_binary_5,
|
|
),
|
|
(
|
|
"SimpleModifier.sol",
|
|
1,
|
|
"withdrawfunds",
|
|
"transfer_vars",
|
|
set(["owner"]),
|
|
solc_binary_5,
|
|
),
|
|
("rubixi.sol", 18, "init", "contains_selfdestruct", False, solc_binary_5),
|
|
("rubixi.sol", 18, "collectAllFees", "has_owner_modifier", True, solc_binary_5),
|
|
("rubixi.sol", 18, "collectAllFees", "is_payable", False, solc_binary_5),
|
|
(
|
|
"rubixi.sol",
|
|
18,
|
|
"collectAllFees",
|
|
"all_require_vars",
|
|
set(["collectedFees", "creator"]),
|
|
solc_binary_5,
|
|
),
|
|
(
|
|
"rubixi.sol",
|
|
18,
|
|
"collectPercentOfFees",
|
|
"all_require_vars",
|
|
set(["collectedFees", "_pcent", "creator"]),
|
|
solc_binary_5,
|
|
),
|
|
(
|
|
"rubixi.sol",
|
|
18,
|
|
"changeMultiplier",
|
|
"all_require_vars",
|
|
set(["_mult", "creator"]),
|
|
solc_binary_5,
|
|
),
|
|
("rubixi.sol", 18, "", "is_payable", True, solc_binary_5),
|
|
(
|
|
"rubixi.sol",
|
|
18,
|
|
"collectAllFees",
|
|
"transfer_vars",
|
|
set(["creator"]),
|
|
solc_binary_5,
|
|
),
|
|
("exceptions.sol", 8, "assert3", "contains_assert", True, solc_binary_5),
|
|
(
|
|
"exceptions.sol",
|
|
8,
|
|
"requireisfine",
|
|
"all_require_vars",
|
|
set(["input"]),
|
|
solc_binary_5,
|
|
),
|
|
("WalletLibrary.sol", 23, "execute", "has_owner_modifier", True, solc_binary_5),
|
|
("WalletLibrary.sol", 23, "initWallet", "has_owner_modifier", False, solc_binary_5),
|
|
(
|
|
"WalletLibrary.sol",
|
|
23,
|
|
"initWallet",
|
|
"all_require_vars",
|
|
set(["m_numOwners"]),
|
|
solc_binary_5,
|
|
),
|
|
(
|
|
"WalletLibrary.sol",
|
|
23,
|
|
"confirm",
|
|
"all_require_vars",
|
|
set(["success"]),
|
|
solc_binary_5,
|
|
),
|
|
("kcalls.sol", 3, "callSetN", "contains_call", True, solc_binary_5),
|
|
("kcalls.sol", 3, "delegatecallSetN", "contains_delegatecall", True, solc_binary_5),
|
|
("kcalls.sol", 3, "callcodeSetN", "contains_staticcall", True, solc_binary_5),
|
|
(
|
|
"regression_1.sol",
|
|
5,
|
|
"transfer",
|
|
"all_require_vars",
|
|
set(["userBalances", "msg", "_to", "_amount"]),
|
|
solc_binary_8,
|
|
),
|
|
("SecureVault.sol", 11, "withdraw", "has_owner_modifier", True, solc_binary_82),
|
|
("SecureVault.sol", 11, "deposit", "has_owner_modifier", False, solc_binary_82),
|
|
(
|
|
"SecureVault.sol",
|
|
11,
|
|
"withdraw",
|
|
"all_require_vars",
|
|
set(["amount", "this"]),
|
|
solc_binary_82,
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"file_name, num_funcs, func_name, field, expected_value, solc_binary", test_cases
|
|
)
|
|
def test_features(file_name, num_funcs, func_name, field, expected_value, solc_binary):
|
|
input_file = TEST_FILES / file_name
|
|
name = file_name.split(".")[0]
|
|
if name[0].islower():
|
|
name = name.capitalize()
|
|
contract = SolidityContract(str(input_file), name=name, solc_binary=solc_binary)
|
|
ms = contract.solc_json["sources"][str(input_file)]["ast"]
|
|
sfe = SolidityFeatureExtractor(ms)
|
|
fe = sfe.extract_features()
|
|
assert len(fe) == num_funcs
|
|
assert fe[func_name][field] == expected_value
|
|
|