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.
106 lines
3.7 KiB
106 lines
3.7 KiB
from mythril.solidity.soliditycontract import SolidityContract
|
|
from mythril.mythril import Mythril
|
|
from mythril.laser.ethereum.state.account import Account
|
|
from mythril.laser.ethereum.state.machine_state import MachineState
|
|
from mythril.laser.ethereum.state.global_state import GlobalState
|
|
from mythril.laser.ethereum import svm
|
|
from tests import BaseTestCase
|
|
|
|
SHA256_TEST = [(0, False) for _ in range(4)]
|
|
RIPEMD160_TEST = [(0, False) for _ in range(2)]
|
|
ECRECOVER_TEST = [(0, False) for _ in range(2)]
|
|
IDENTITY_TEST = [(0, False) for _ in range(2)]
|
|
|
|
# These are Random numbers to check whether the 'if condition' is entered or not
|
|
# (True means entered)
|
|
SHA256_TEST[0] = (hex(5555555555555555), True)
|
|
SHA256_TEST[1] = (hex(323232325445454546), False)
|
|
SHA256_TEST[2] = (hex(34756834765834658), True)
|
|
SHA256_TEST[3] = (hex(8756476956956795876987), False)
|
|
|
|
RIPEMD160_TEST[0] = (hex(999999999999999999993), True)
|
|
RIPEMD160_TEST[1] = (hex(1111111111112), False)
|
|
|
|
ECRECOVER_TEST[0] = (hex(674837568743979857398564869), True)
|
|
ECRECOVER_TEST[1] = (hex(3487683476979311), False)
|
|
|
|
IDENTITY_TEST[0] = (hex(87426857369875698), True)
|
|
IDENTITY_TEST[1] = (hex(476934798798347), False)
|
|
|
|
|
|
def _all_info(laser):
|
|
accounts = {}
|
|
for address, _account in laser.world_state.accounts.items():
|
|
account = _account.as_dict
|
|
account["code"] = account["code"].instruction_list
|
|
account["balance"] = str(account["balance"])
|
|
accounts[address] = account
|
|
|
|
nodes = {}
|
|
for uid, node in laser.nodes.items():
|
|
states = []
|
|
for state in node.states:
|
|
if isinstance(state, MachineState):
|
|
states.append(state.as_dict)
|
|
elif isinstance(state, GlobalState):
|
|
environment = state.environment.as_dict
|
|
environment["active_account"] = environment["active_account"].address
|
|
states.append(
|
|
{
|
|
"accounts": state.accounts.keys(),
|
|
"environment": environment,
|
|
"mstate": state.mstate.as_dict,
|
|
}
|
|
)
|
|
|
|
nodes[uid] = {
|
|
"uid": node.uid,
|
|
"contract_name": node.contract_name,
|
|
"start_addr": node.start_addr,
|
|
"states": states,
|
|
"constraints": node.constraints,
|
|
"function_name": node.function_name,
|
|
"flags": str(node.flags),
|
|
}
|
|
|
|
edges = [edge.as_dict for edge in laser.edges]
|
|
|
|
return {
|
|
"accounts": accounts,
|
|
"nodes": nodes,
|
|
"edges": edges,
|
|
"total_states": laser.total_states,
|
|
"max_depth": laser.max_depth,
|
|
}
|
|
|
|
|
|
def _test_natives(laser_info, test_list, test_name):
|
|
success = 0
|
|
for i, j in test_list:
|
|
if (str(i) in laser_info or str(int(i, 16)) in laser_info) == j:
|
|
success += 1
|
|
else:
|
|
print("Failed:", str(int(i, 16)), str(j))
|
|
assert success == len(test_list)
|
|
|
|
|
|
class NativeTests(BaseTestCase):
|
|
@staticmethod
|
|
def runTest():
|
|
|
|
disassembly = SolidityContract(
|
|
"./tests/native_tests.sol", solc_binary=Mythril._init_solc_binary("0.5.0")
|
|
).disassembly
|
|
account = Account("0x0000000000000000000000000000000000000000", disassembly)
|
|
accounts = {account.address: account}
|
|
|
|
laser = svm.LaserEVM(accounts, max_depth=100, transaction_count=1)
|
|
laser.sym_exec(account.address)
|
|
|
|
laser_info = str(_all_info(laser))
|
|
|
|
print(laser_info)
|
|
_test_natives(laser_info, SHA256_TEST, "SHA256")
|
|
_test_natives(laser_info, RIPEMD160_TEST, "RIPEMD160")
|
|
_test_natives(laser_info, ECRECOVER_TEST, "ECRECOVER")
|
|
_test_natives(laser_info, IDENTITY_TEST, "IDENTITY")
|
|
|