示例#1
0
    def test_echidna_instrumentation(self):
        self.inorder_config.instrumentation.predicates = [
            'previously(b_called) -> c_called',
            'b_called -> since(c_called, a_called)'
        ]
        self.inorder_config.instrumentation.for_echidna = True
        self.inorder_config.verification.verisol.use = False

        proof_found, verisol_counterexample = self.inorder_veriman.analyze_contract(
            self.inorder_config, reuse_pre_process=True)

        # Restore test configs:
        self.inorder_config.instrumentation.for_echidna = False
        self.inorder_config.verification.verisol.use = True

        self.check_contract_compiles(self.inorder_veriman.contract_path)

        slither = Slither(self.inorder_veriman.contract_path)
        contract_info = slither.get_contract_from_name('InOrder')
        echidna_invariants = list(
            filter(lambda func: func.name.startswith('echidna_'),
                   contract_info.functions))

        self.assertEqual(len(echidna_invariants), 2)

        for invariant in echidna_invariants:
            self.assertEqual(invariant.return_type[0].name, 'bool')

        self.check_functions_with_asserts(self.inorder_veriman, [])

        os.remove(self.inorder_veriman.contract_path)
示例#2
0
    def test_inheritance(self):
        inheritance_config = TestVeriMan.get_test_config()
        inheritance_config.contract.path = os.path.dirname(
            os.path.abspath(__file__)) + '/Inheritance.sol'
        inheritance_config.contract.name = 'D'
        inheritance_config.instrumentation.predicates = [
            'a_var + b_var + c_var + d_var < 10', 'block.number > 10'
        ]
        inheritance_config.verification.verisol.use = False

        veriman = VeriMan()
        proof_found, verisol_counterexample = veriman.analyze_contract(
            inheritance_config)

        self.check_contract_compiles(veriman.contract_path)

        slither = Slither(veriman.contract_path)
        contract_info = slither.get_contract_from_name(
            inheritance_config.contract.name)

        expected_functions = set(
            list([
                'aFunction', 'toBeOverwritten', 'bFunction', 'withTheSameName',
                'callsC', 'dFunction', 'constructor'
            ]))

        found_functions = list(
            map(lambda func: func.name, contract_info.functions_declared))

        self.assertEqual(found_functions.count('withTheSameName'), 3)
        self.assertEqual(found_functions.count('toBeOverwritten'), 1)

        self.assertEqual(expected_functions, set(found_functions))

        os.remove(veriman.contract_path)
示例#3
0
文件: __main__.py 项目: gyDBD/slither
def process_truffle(dirname, args, detector_classes, printer_classes):
    if args.truffle_version:
        cmd = ['npx', args.truffle_version, 'compile']
    elif os.path.isfile('package.json'):
        cmd = ['truffle', 'compile']
        with open('package.json') as f:
            package = json.load(f)
            if 'devDependencies' in package:
                if 'truffle' in package['devDependencies']:
                    truffle_version = 'truffle@{}'.format(
                        package['devDependencies']['truffle'])
                    cmd = ['npx', truffle_version, 'compile']
    logger.info(
        "'{}' running (use --truffle-version [email protected] to use specific version)"
        .format(' '.join(cmd)))
    process = subprocess.Popen(cmd,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)

    stdout, stderr = process.communicate()
    stdout, stderr = stdout.decode(), stderr.decode(
    )  # convert bytestrings to unicode strings

    logger.info(stdout)

    if stderr:
        logger.error(stderr)

    slither = Slither(dirname,
                      args.solc,
                      args.disable_solc_warnings,
                      args.solc_args,
                      is_truffle=True)
    return _process(slither, detector_classes, printer_classes)
示例#4
0
def process(filename, args, detector_classes, printer_classes):
    """
    The core high-level code for running Slither static analysis.

    Returns:
        list(result), int: Result list and number of contracts analyzed
    """
    slither = Slither(filename, args.solc, args.disable_solc_warnings, args.solc_args)

    for detector_cls in detector_classes:
        slither.register_detector(detector_cls)

    for printer_cls in printer_classes:
        slither.register_printer(printer_cls)

    analyzed_contracts_count = len(slither.contracts)

    results = []

    if printer_classes:
        slither.run_printers()  # Currently printers does not return results

    elif detector_classes:
        detector_results = slither.run_detectors()
        detector_results = [x for x in detector_results if x]  # remove empty results
        detector_results = [item for sublist in detector_results for item in sublist]  # flatten

        results.extend(detector_results)

    return results, analyzed_contracts_count
示例#5
0
def getSummaryOfFile(f):
    slither = Slither(f)
    summaries = []
    for contract in slither.contracts:
        events = getSummaryOfContract(contract)
        summaries.append({"name": contract.name, "functions": events})
    return summaries
示例#6
0
def process_truffle(dirname, args, detector_classes, printer_classes):
    cmd =  ['npx',args.truffle_version,'compile'] if args.truffle_version else ['truffle','compile']
    logger.info('truffle compile running...')
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    stdout, stderr = process.communicate()
    stdout, stderr = stdout.decode(), stderr.decode()  # convert bytestrings to unicode strings

    logger.info(stdout)

    if stderr:
        logger.error(stderr)

    if not os.path.isdir(os.path.join(dirname, 'build'))\
        or not os.path.isdir(os.path.join(dirname, 'build', 'contracts')):
        logger.info(red('No truffle build directory found, did you run `truffle compile`?'))
        return ([], 0)

    filenames = glob.glob(os.path.join(dirname,'build','contracts', '*.json'))

    all_contracts = []
    all_filenames = []

    for filename in filenames:
        with open(filename) as f:
            contract_loaded = json.load(f)
            all_contracts.append(contract_loaded['ast'])
            all_filenames.append(contract_loaded['sourcePath'])

    slither = Slither(all_contracts, args.solc, args.disable_solc_warnings, args.solc_args)
    return _process(slither, detector_classes, printer_classes)
示例#7
0
def run(filename, contract_name):
    """Executes script"""

    # Init Slither
    slither = Slither(filename)

    # Get an instance of the contract to be analyzed
    contract = slither.get_contract_from_name(contract_name)
    if not contract:
        print(f"Contract {contract_name} not found")
        print(
            "Either you mispelled the contract's name or solc cannot compile the contract."
        )
        exit(-1)

    # Obtain all visible functions, filtering out any that comes from an interface contract
    visible_functions = get_visible_functions(
        get_implemented_functions(contract.functions))

    erc20_fx_matches = verify_signatures(visible_functions,
                                         ERC20_FX_SIGNATURES)

    print("== ERC20 functions definition ==")
    log_matches(erc20_fx_matches)

    print("\n== Custom modifiers ==")
    log_modifiers_per_function(verify_custom_modifiers(erc20_fx_matches))

    print("\n== ERC20 events ==")
    log_matches(verify_signatures(contract.events, ERC20_EVENT_SIGNATURES),
                log_return=False)
    log_event_per_function(
        verify_event_calls(erc20_fx_matches, ERC20_EVENT_BY_FX),
        ERC20_EVENT_BY_FX)

    print("\n== ERC20 getters ==")
    log_matches(
        verify_getters(contract.state_variables, visible_functions,
                       ERC20_GETTERS))

    print("\n== Allowance frontrunning mitigation ==")
    frontrun_fx_matches = verify_signatures(visible_functions,
                                            ALLOWANCE_FRONTRUN_FX_SIGNATURES)
    log_matches(frontrun_fx_matches)
    log_event_per_function(verify_event_calls(frontrun_fx_matches,
                                              ALLOWANCE_FRONTRUN_EVENT_BY_FX),
                           ALLOWANCE_FRONTRUN_EVENT_BY_FX,
                           must=False)

    print("\n== Balance check in approve function ==")
    approve_signature = ERC20_FX_SIGNATURES[1].to_string(with_return=False,
                                                         with_spaces=False)
    approve_function = contract.get_function_from_signature(approve_signature)
    is_checking_balance = any(
        checks_sender_balance_in_require(node)
        for node in approve_function.nodes)
    log_approve_checking_balance(is_checking_balance)
示例#8
0
def process_files(filenames, args, detector_classes, printer_classes):
    all_contracts = []

    for filename in filenames:
        with open(filename) as f:
            contract_loaded = json.load(f)
            all_contracts.append(contract_loaded['ast'])

    slither = Slither(all_contracts, args.solc, args.disable_solc_warnings, args.solc_args)
    return _process(slither, detector_classes, printer_classes)
示例#9
0
def process(filename, args, detectors, printers):
    slither = Slither(filename, args.solc, args.disable_solc_warnings,
                      args.solc_args)
    if args.printers_to_run:
        [printers.run_printer(slither, p) for p in args.printers_to_run]
        return []
    else:
        checks = determineChecks(detectors, args)
        results = [detectors.run_detector(slither, c) for c in checks]
        results = [x for x in results if x]  # remove empty results
        results = [item for sublist in results for item in sublist]  #flatten
        return results
示例#10
0
def process_single(target, args, detector_classes, printer_classes):
    """
    The core high-level code for running Slither static analysis.

    Returns:
        list(result), int: Result list and number of contracts analyzed
    """
    ast = '--ast-compact-json'
    if args.legacy_ast:
        ast = '--ast-json'
    slither = Slither(target, ast_format=ast, **vars(args))

    return _process(slither, detector_classes, printer_classes)
示例#11
0
def process(filename, args, detector_classes, printer_classes):
    """
    The core high-level code for running Slither static analysis.

    Returns:
        list(result), int: Result list and number of contracts analyzed
    """
    ast = '--ast-json'
    if args.compact_ast:
        ast = '--ast-compact-json'
    slither = Slither(filename, args.solc, args.disable_solc_warnings, args.solc_args, ast)

    return _process(slither, detector_classes, printer_classes)
示例#12
0
    def pre_process_contract(self, contract_path, contract_name):
        self.contract_path = contract_path
        self.contract_name = contract_name

        slither = Slither(self.contract_path)
        self.contract_info = slither.get_contract_from_name(self.contract_name)
        if self.contract_info is None:
            raise Exception('Check config file for contract name')

        with open(self.contract_path) as contract_file:
            self.contract_lines = contract_file.readlines()

        self.__add_constructor(slither)

        self.__add_inherited_functions()

        # TODO improve efficiency:

        with open(self.contract_path, 'w') as contract_file:
            contract_file.writelines(self.contract_lines)

        slither = Slither(self.contract_path)
        self.contract_info = slither.get_contract_from_name(self.contract_name)
示例#13
0
def process_files(filenames, args, detector_classes, printer_classes):
    all_contracts = []

    for filename in filenames:
        with open(filename, encoding='utf8') as f:
            contract_loaded = json.load(f)
            all_contracts.append(contract_loaded['ast'])

    slither = Slither(all_contracts,
                      solc=args.solc,
                      disable_solc_warnings=args.disable_solc_warnings,
                      solc_arguments=args.solc_args,
                      filter_paths=parse_filter_paths(args),
                      triage_mode=args.triage_mode)

    return _process(slither, detector_classes, printer_classes)
示例#14
0
    def instrument(self, contract_path, contract_name, predicates,
                   instrument_for_echidna):
        self.contract_path = contract_path
        self.contract_name = contract_name

        slither = Slither(self.contract_path)
        self.contract_info = slither.get_contract_from_name(self.contract_name)
        if self.contract_info is None:
            raise Exception('Check config file for contract name')

        with open(self.contract_path) as contract_file:
            contract = contract_file.read()
        contract = contract.replace('}', '\n}')
        self.contract_lines = contract.split('\n')

        self.__pre_process_contract()

        parser = Parser()

        echidna_function = ''

        for index, predicate_string in enumerate(predicates):
            predicate = parser.parse(predicate_string)

            functions_to_instrument = self.__get_functions_to_instrument(
                predicate)

            self.__instrument_new_variables(predicate, functions_to_instrument,
                                            instrument_for_echidna)

            if instrument_for_echidna:
                echidna_function += '(' + predicate.solidity_repr + ')\n&& '
            else:
                assert_string = f'assert({predicate.solidity_repr}); // VERIMAN ASSERT FOR PREDICATE NO. {index + 1}'
                self.__insert_in_functions(functions_to_instrument,
                                           assert_string,
                                           self.__insert_at_end_of_functions)

        if instrument_for_echidna:
            echidna_function = 'function echidna_invariant() public returns(bool) {\nreturn ' \
                               + echidna_function.rsplit('\n&& ', 1)[0]\
                               + ';\n}'
            self.__insert_in_contract(echidna_function)

        contract = '\n'.join(self.contract_lines)
        with open(self.contract_path, 'w') as contract_file:
            contract_file.write(contract)
示例#15
0
    def check_functions_with_asserts(self, veriman, expected):
        slither = Slither(veriman.contract_path)
        contract_info = slither.get_contract_from_name(veriman.contract_name)

        expected_functions = set(list(expected))

        found_functions = list(
            filter(
                lambda func: next(
                    filter(lambda call: call.name == 'assert(bool)', func.
                           solidity_calls), None) is not None,
                contract_info.functions_declared))

        found_functions_names = list(
            map(lambda func: func.name, found_functions))

        self.assertEqual(expected_functions, set(found_functions_names))
示例#16
0
def process_truffle(dirname, args, detector_classes, printer_classes):
    # Truffle on windows has naming conflicts where it will invoke truffle.js directly instead
    # of truffle.cmd (unless in powershell or git bash). The cleanest solution is to explicitly call
    # truffle.cmd. Reference:
    # https://truffleframework.com/docs/truffle/reference/configuration#resolving-naming-conflicts-on-windows
    if not args.ignore_truffle_compile:
        truffle_base_command = "truffle" if platform.system(
        ) != 'Windows' else "truffle.cmd"
        cmd = [truffle_base_command, 'compile']
        if args.truffle_version:
            cmd = ['npx', args.truffle_version, 'compile']
        elif os.path.isfile('package.json'):
            with open('package.json') as f:
                package = json.load(f)
                if 'devDependencies' in package:
                    if 'truffle' in package['devDependencies']:
                        version = package['devDependencies']['truffle']
                        if version.startswith('^'):
                            version = version[1:]
                        truffle_version = 'truffle@{}'.format(version)
                        cmd = ['npx', truffle_version, 'compile']
        logger.info(
            "'{}' running (use --truffle-version [email protected] to use specific version)"
            .format(' '.join(cmd)))
        process = subprocess.Popen(cmd,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        stdout, stderr = process.communicate()
        stdout, stderr = stdout.decode(), stderr.decode(
        )  # convert bytestrings to unicode strings

        logger.info(stdout)

        if stderr:
            logger.error(stderr)

    slither = Slither(dirname,
                      solc=args.solc,
                      disable_solc_warnings=args.disable_solc_warnings,
                      solc_arguments=args.solc_args,
                      is_truffle=True,
                      filter_paths=parse_filter_paths(args),
                      triage_mode=args.triage_mode)

    return _process(slither, detector_classes, printer_classes)
示例#17
0
def main(sol_file):
    seed = None
    # assert False

    logger.info('Analyzing Input...')
    deps, refs = analyze(sol_file, "C", "foo()")
    lambdas = analyze_lambdas(sol_file, "C", "foo()")
    logger.info('Analysis Successful!')

    # print(deps.dependencies)
    # print(refs.pprint_refinement())

    actual_spec, prog_decl, types, i_global, global_vars = instantiate_dsl(
        sol_file, refs.types, lambdas)

    # print(actual_spec)

    logger.info('Parsing Spec...')
    spec = S.parse(actual_spec)
    logger.info('Parsing succeeded')

    # Fetch other contract names
    slither = Slither(sol_file)
    other_contracts = list(
        filter(lambda x: x != 'C', map(str, slither.contracts)))

    logger.info('Building synthesizer...')
    synthesizer = Synthesizer(
        enumerator=DependencyEnumerator(spec,
                                        max_depth=4,
                                        seed=seed,
                                        analysis=deps.dependencies,
                                        types=types),
        decider=SymdiffDecider(interpreter=SymDiffInterpreter(
            prog_decl, other_contracts, i_global, global_vars),
                               example=sol_file,
                               equal_output=check_eq))
    logger.info('Synthesizing programs...')

    prog = synthesizer.synthesize()
    if prog is not None:
        logger.info('Solution found: {}'.format(prog))
        return True
    else:
        logger.info('Solution not found!')
        return False
示例#18
0
def process(filename, args, detector_classes, printer_classes):
    """
    The core high-level code for running Slither static analysis.

    Returns:
        list(result), int: Result list and number of contracts analyzed
    """
    ast = '--ast-compact-json'
    if args.legacy_ast:
        ast = '--ast-json'
    slither = Slither(filename,
                      solc=args.solc,
                      disable_solc_warnings=args.disable_solc_warnings,
                      solc_arguments=args.solc_args,
                      ast_format=ast,
                      filter_paths=parse_filter_paths(args),
                      triage_mode=args.triage_mode)

    return _process(slither, detector_classes, printer_classes)
def main(args):
    if len(args) < 2:
        print("Usage: python get-conditions.py FILENAME")
        exit(1)

    slither = Slither(args[1])

    for contract in slither.contracts:
        # print('Contract: '+ contract.name)

        for function in contract.functions:
            # print('Function: {}'.format(function.name))

            for node in function.nodes:
                # NOTE: This will also give `return bool;` as a condition. I'm not sure that this really should count, so I used a different machnism to get this information.
                # if node.is_conditional():
                #     print(node)

                if node.contains_if() or node.contains_require_or_assert():
                    print(looks_like_state_check(contract, node), node)
示例#20
0
def process_truffle(dirname, args, detector_classes, printer_classes):
    if not args.ignore_truffle_compile:
        cmd = ['truffle', 'compile']
        if args.truffle_version:
            cmd = ['npx', args.truffle_version, 'compile']
        elif os.path.isfile('package.json'):
            with open('package.json') as f:
                package = json.load(f)
                if 'devDependencies' in package:
                    if 'truffle' in package['devDependencies']:
                        version = package['devDependencies']['truffle']
                        if version.startswith('^'):
                            version = version[1:]
                        truffle_version = 'truffle@{}'.format(version)
                        cmd = ['npx', truffle_version, 'compile']
        logger.info(
            "'{}' running (use --truffle-version [email protected] to use specific version)"
            .format(' '.join(cmd)))
        process = subprocess.Popen(cmd,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        stdout, stderr = process.communicate()
        stdout, stderr = stdout.decode(), stderr.decode(
        )  # convert bytestrings to unicode strings

        logger.info(stdout)

        if stderr:
            logger.error(stderr)

    slither = Slither(dirname,
                      solc=args.solc,
                      disable_solc_warnings=args.disable_solc_warnings,
                      solc_arguments=args.solc_args,
                      is_truffle=True,
                      filter_paths=parse_filter_paths(args),
                      triage_mode=args.triage_mode)

    return _process(slither, detector_classes, printer_classes)
示例#21
0
def process_truffle(dirname, args, detector_classes, printer_classes):
    if not os.path.isdir(os.path.join(dirname, 'build'))\
        or not os.path.isdir(os.path.join(dirname, 'build', 'contracts')):
        logger.info(
            red('No truffle build directory found, did you run `truffle compile`?'
                ))
        return (0, 0)

    filenames = glob.glob(os.path.join(dirname, 'build', 'contracts',
                                       '*.json'))

    all_contracts = []

    for filename in filenames:
        with open(filename) as f:
            contract_loaded = json.load(f)
            all_contracts += contract_loaded['ast']['nodes']

    contract = {"nodeType": "SourceUnit", "nodes": all_contracts}

    slither = Slither(contract, args.solc, args.disable_solc_warnings,
                      args.solc_args)
    return _process(slither, detector_classes, printer_classes)
from slither.slither import Slither

slither = Slither('coin.sol')
coin = slither.get_contract_from_name('Coin')[0]

# Iterate over all the contracts
for contract in slither.contracts:
   # If the contract is derived from MyContract
   if coin in contract.inheritance:
      # Get the function definition  
      mint = contract.get_function_from_signature('_mint(address,uint256)')
      # If the function was not declarer by coin, there is a bug !  
      if mint.contract != coin:
           print(f'Error, {contract} overrides {mint}')
示例#23
0
from slither.slither import Slither

# Init slither
slither = Slither('functions_writing.sol')

# Get the contract
contract = slither.get_contract_from_name('Contract')

# Get the variable
var_a = contract.get_state_variable_from_name('a')

# Get the functions writing the variable
functions_writing_a = contract.get_functions_writing_variable(var_a)

# Print the result
print 'The function writing "a" are {}'.format(
    [f.name for f in functions_writing_a])
# Successfully analyzed contracts counter
contract_processed = 0

# Dictionary which counts vulnerabilities found on contracts by type
statistics = {"front-running": 0}

directory = argv[1]
for filename in os.listdir(directory):
    if filename.endswith(".sol"):  # only run procedure on Solidity files
        filePath = os.path.join(directory, filename)
        logger.info("Analyzing file: " + filePath)

        try:  # in case of compiling errors just skip the contract (and don't count it as processed)
            # Load contracts from file
            slither = Slither(filePath)

            # Register detector
            slither.register_detector(FrontRunning)

            # Start detecting
            detector_results = slither.run_detectors()
            detector_results = [x for x in detector_results
                                if x]  # remove empty results

            # Update contract count (here I can safely assume the contract is successfully processed
            contract_processed += len(slither.contracts)
            # Update vulnerabilities found to statistics dict
            for sublist in detector_results:
                for item in sublist:
                    detector = item["check"]
import sys
from slither.slither import Slither

if len(sys.argv) != 2:
    print("python function_called.py contract.sol")
    sys.exit(-1)

# Init slither
slither = Slither(sys.argv[1])

for contract in slither.contracts:
    for function in contract.functions + contract.modifiers:
        filename = "{}-{}-{}.dot".format(sys.argv[1], contract.name,
                                         function.full_name)
        print("Export {}".format(filename))
        function.slithir_cfg_to_dot(filename)
示例#26
0
                                                read_function_name)

                    # 跨函数的全局变量依赖
                    if write_function_name != read_function_name:
                        cross_function_edges.append(
                            (from_node_id, to_node_id, {
                                'type': "state_cross",
                                'color': "blue"
                            }))
    TPG.add_edges_from(cross_function_edges)
    get_graph_png(TPG, "TPG")


if __name__ == '__main__':

    slither = Slither(EXAMPLE_PERFIX +
                      '0x09515cb5e3acaef239ab83d78b2f3e3764fcab9b.sol')

    for contract in slither.contracts:

        state_var_declare_function_map = {}  # 全局变量定义函数
        state_var_write_function_map = {}  # 全局变量写函数列表
        state_var_read_function_map = {}  # 全局变量读函数列表
        transaction_state_vars = []  # 与交易行为相关的全局变量
        transaction_state_vars_stmts = {}
        eth_send_functions = {}
        functions_slice_criterias = {}  # 每个函数对应的切片准则:阶段1、4都会生成切片准则

        # NOTE: stat_var <==> function 对应表
        print("\n=====阶段1:stat_var <==> function 对应表=====\n")

        for v in contract.state_variables:
示例#27
0
def instantiate_dsl(sol_file, analysis, lambdas):
    ## Step 1: parse the original source .sol.
    # Init slither
    slither = Slither(sol_file)

    # Get the contract, all the contact's name is C by default.
    contract = slither.get_contract_from_name('C')
    other_contracts = list(
        filter(lambda x: x != 'C', map(str, slither.contracts)))
    harness_fun = contract.functions[0]
    vars_map = {}

    # Get the function, which has name 'foo' by default.
    assert harness_fun.name == 'foo'

    for var in harness_fun.variables_read:
        add_var(vars_map, var)

    for var in harness_fun.variables_written:
        add_var(vars_map, var)

    actual_spec = toy_spec_str

    int_str = ""
    address_str = ""
    maparray_str = ""
    mapint_str = ""
    prog_decl = ""

    with open(sol_file, "r") as f:
        ind = "//#LOOPVARS: "
        body = f.read()
        if ind in body:
            global_vars = body[body.index(ind) + 12:].split("\n")[0]
            global_vars = global_vars.replace('[', "").replace(
                ']', "").replace("'", "").replace(" ", "").split(", ")
        else:
            global_vars = ["i"]

    #TODO: HANDLE NESTED LOOPS
    i_global = global_vars[0] in list(map(str, contract.variables))

    for k in vars_map:
        for v in vars_map[k]:
            if v == global_vars[0]:
                if i_global:
                    prog_decl += k + ' ' + v + '; \n'
            else:
                prog_decl += k + ' ' + v + '; \n'

    # TODO: Presumes all constants are integers or booleans
    for const in analysis[5]:
        try:
            if 'uint256' in vars_map:
                vars_map['uint256'].append(str(int(const)))
            else:
                vars_map['uint256'] = [str(int(const))]
        except:
            if 'bool' in vars_map:
                vars_map['bool'].append(const)
            else:
                vars_map['bool'] = [const]

    base_types = ["uint", "bool", "address", "bytes"] + other_contracts
    map_types = list(
        map(lambda x: "mapping({0} => {1})".format(x[0], x[1]),
            product(base_types, repeat=2)))

    all_types = base_types + map_types

    type_table = {}

    length_vars = []
    for k in vars_map:
        v = map(lambda x: '"' + x + '"', vars_map[k])
        actual_symbols = ",".join(list(v))
        print('parsing key:', k, ",".join(list(v)))
        if "[]" in k:
            length_vars += vars_map[k]
            k = "mapping(uint => {0})".format(k.replace("[]", ""))
        k = k.replace("uint8", "uint")
        k = k.replace("uint128", "uint")
        k = k.replace("uint256", "uint")
        k = k.replace("bytes32", "bytes")
        if k in all_types:
            if k in map_types:
                matches = re.findall(r"(mapping\((.*) => (.*)\))", k)
                if matches != []:
                    full_dec = matches[0][0]
                    dom = matches[0][1]
                    codom = matches[0][2]
                    k = "mapping_{0}_{1}".format(dom, codom)

            if not k in type_table:
                type_table[k] = actual_symbols.split(",")
            else:
                type_table[k] += actual_symbols.split(",")
        else:
            print("IGNORED TYPE: {0}!".format(k))
            pass

    if "uint" in type_table:
        type_table["uint"] += list(
            map(lambda v: '"{0}.length"'.format(v), length_vars))
    else:
        type_table["uint"] = list(
            map(lambda v: '"{0}.length"'.format(v), length_vars))

    typ_enums, final_typ_dict = create_refinement_types(
        analysis, type_table, lambdas)

    actual_spec = expand_dsl(actual_spec, final_typ_dict, base_types)

    actual_spec = actual_spec.format(types=typ_enums)

    # print(actual_spec)

    return actual_spec, prog_decl, final_typ_dict, i_global, global_vars
示例#28
0
from slither.slither import Slither

# Init slither
slither = Slither('variable_in_condition.sol')

# Get the contract
contract = slither.get_contract_from_name('Contract')

# Get the variable
var_a = contract.get_state_variable_from_name('a')

# Get the functions reading the variable
functions_reading_a = contract.get_functions_reading_variable(var_a)

function_using_a_as_condition = [f for f in functions_reading_a if\
                                 f.is_reading_in_conditional_node(var_a) or\
                                 f.is_reading_in_require_or_assert(var_a)]

# Print the result
print 'The function using "a" in condition are {}'.format(
    [f.name for f in function_using_a_as_condition])
示例#29
0
def analyze(fname):
    res = {
        'fname': fname,
        'external_func': Counter(),
        'external_call': Counter(),
        'internal_func': Counter(),
        'internal_call': Counter(),
        'library_func': Counter(),
        'library_call': Counter(),
        'internal_state_change_call': Counter(),
        'internal_state_change_func': Counter(),
        'writes_after_internal_call': False,
        'writes_after_internal_state_change_call': False,
        'writes_after_external_call': False,
        'writes_after_non_library_call': False,
        'reads_after_internal_call': False,
        'reads_after_internal_state_change_call': False,
        'reads_after_external_call': False,
        'reads_after_non_library_call': False,
        'external_call_num': 0,
        'external_call_checked_num': 0,
        'call_graph': {},
        'success': False
    }

    try:
        slither = Slither(fname, disable_solc_warnings=True)

        for c in slither.contracts:
            # print('Contract: {}'.format(c.name))

            state_changing_func_names = set(func.name for func in c.functions if len(func.all_state_variables_written()) > 0)

            for function in c.functions:
                record_call_set(res, 'external', function.all_high_level_calls())
                record_call_set(res, 'internal', [(declarer(c, f), f) for f in function.all_internal_calls()])
                record_call_set(res, 'internal_state_change', [(declarer(c, f), f) for f in function.all_internal_calls() if f.name in state_changing_func_names])
                record_call_set(res, 'library', function.all_library_calls())

                this_func = (c.name, signature(function))

                res['call_graph'][this_func] = set()

                for con, func in function.all_high_level_calls():
                    if func is not None:
                        res['call_graph'][this_func].add((str(con), signature(func)))

                for func in function.all_internal_calls():
                    if func is not None and isinstance(func, Function):
                        res['call_graph'][this_func].add((str(func.contract_declarer), signature(func)))

                res['writes_after_internal_call'] |= do_explore(internal_calls, lambda n: n.state_variables_written, function.entry_point)
                res['writes_after_internal_state_change_call'] |= do_explore(internal_state_change_calls(state_changing_func_names), lambda n: n.state_variables_written, function.entry_point)
                res['writes_after_external_call'] |= do_explore(external_calls, lambda n: n.state_variables_written, function.entry_point)
                res['writes_after_non_library_call'] |= do_explore(non_library_calls, lambda n: n.state_variables_written, function.entry_point)

                res['reads_after_internal_call'] |= do_explore(internal_calls, lambda n: n.state_variables_read, function.entry_point)
                res['reads_after_internal_state_change_call'] |= do_explore(internal_state_change_calls(state_changing_func_names), lambda n: n.state_variables_read, function.entry_point)
                res['reads_after_external_call'] |= do_explore(external_calls, lambda n: n.state_variables_read, function.entry_point)
                res['reads_after_non_library_call'] |= do_explore(non_library_calls, lambda n: n.state_variables_read, function.entry_point)

                for node in function.nodes:
                    num = len(node.high_level_calls)
                    if num > 0:
                        res['external_call_num'] += num
                        if node.is_conditional():
                            res['external_call_checked_num'] += num

                # print('External calls: {}'.format(external_calls))

        res['success'] = True
    except SlitherError as e:
        # raise e
        pass

    for k in res:
        if isinstance(res[k], Counter):
            res[k] = dict(res[k])

    print(res)
示例#30
0
from slither.slither import Slither

# Init slither
slither = Slither('functions_called.sol')

# Get the contract
contract = slither.get_contract_from_name('Contract')

# Get the variable
entry_point = contract.get_function_from_signature('entry_point()')

all_calls = entry_point.all_calls()

all_calls_formated = [f.contract.name + '.' + f.name for f in all_calls]

# Print the result
print 'From entry_point the functions reached are {}'.format(all_calls_formated)