diff --git a/mythril/mythril/mythril_disassembler.py b/mythril/mythril/mythril_disassembler.py index 70813bb9..8c8d7303 100644 --- a/mythril/mythril/mythril_disassembler.py +++ b/mythril/mythril/mythril_disassembler.py @@ -5,7 +5,7 @@ import os from ethereum import utils from solc.exceptions import SolcError - +from typing import List, Optional from mythril.ethereum import util from mythril.exceptions import CriticalError, CompilerError, NoContractFoundError from mythril.support import signatures @@ -208,13 +208,18 @@ class MythrilDisassembler: """ return "0x%s" % utils.sha3(func)[:4].hex() - def get_state_variable_from_storage(self, address, params=None): + def get_state_variable_from_storage( + self, address: str, params: Optional[List[str]] = None + ) -> str: """ - - :param address: - :param params: - :return: + Get variables from the storage + :param address: The contract address + :param params: The list of parameters + param types: [position, length] or ["mapping", position, key1, key2, ... ] + or [position, length, array] + :return: The corresponding storage slot and it's value """ + print(address, params, type(address)) if params is None: params = [] (position, length, mappings) = (0, 1, []) @@ -285,6 +290,7 @@ class MythrilDisassembler: hex(i), self.eth.eth_getStorageAt(address, i) ) ) + print(outtxt) except FileNotFoundError as e: raise CriticalError("IPC error: " + str(e)) except ConnectionError: diff --git a/tests/mythril/analyzer_test.py b/tests/mythril/analyzer_test.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/mythril/mythril_disassembler_test.py b/tests/mythril/mythril_disassembler_test.py new file mode 100644 index 00000000..dd8bb39a --- /dev/null +++ b/tests/mythril/mythril_disassembler_test.py @@ -0,0 +1,44 @@ +import pytest +from mythril.mythril import MythrilConfig, MythrilDisassembler + + +storage_test = [ + ( + ["438767356", "3"], + [ + "0x1a270efc: 0x0000000000000000000000000000000000000000000000000000000000000000", + "0x1a270efd: 0x0000000000000000000000000000000000000000000000000000000000000000", + "0x1a270efe: 0x0000000000000000000000000000000000000000000000000000000000000000", + ], + ), + ( + ["mapping", "4588934759847", "1", "2"], + [ + "0x7e523d5aeb10cdb378b0b1f76138c28063a2cb9ec8ff710f42a0972f4d53cf44: " + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0xba36da34ceec88853a2ebdde88e023c6919b90348f41e8905b422dc9ce22301c: " + "0x0000000000000000000000000000000000000000000000000000000000000000", + ], + ), + ( + ["4588934759847", "1", "array"], + [ + "30699902832541380821728647136767910246735388184559883985790189062258823875816: " + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + ), +] + + +@pytest.mark.parametrize("params,ans", storage_test) +def test_get_data_from_storage(params, ans): + config = MythrilConfig() + config.set_api_rpc_infura() + disassembler = MythrilDisassembler(eth=config.eth, solc_version="0.4.23") + outtext = disassembler.get_state_variable_from_storage( + "0x76799f77587738bfeef09452df215b63d2cfb08a", params + ).split("\n") + assert len(outtext) == len(ans) + for a, b in zip(outtext, ans): + assert a == b + assert outtext == ans