示例#1
0
    def output(self, _filename):
        """
            _filename is not used
            Args:
                _filename(string)
        """

        txt = ''

        all_tables = []

        for contract in self.slither.contracts_derived:
            txt += '\n{}:\n'.format(contract.name)
            table = MyPrettyTable(['Name', 'Type'])
            for variable in contract.state_variables_ordered:
                if not variable.is_constant:
                    table.add_row(
                        [variable.canonical_name,
                         str(variable.type)])

            all_tables.append((contract.name, table))
            txt += str(table) + '\n'

        self.info(txt)

        res = self.generate_output(txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)
        return res
def output_detectors(detector_classes):
    detectors_list = []
    for detector in detector_classes:
        argument = detector.ARGUMENT
        help_info = detector.HELP
        impact = detector.IMPACT
        require_proxy = detector.REQUIRE_PROXY
        require_v2 = detector.REQUIRE_CONTRACT_V2
        detectors_list.append(
            (argument, help_info, impact, require_proxy, require_v2))
    table = MyPrettyTable(
        ["Num", "Check", "What it Detects", "Impact", "Proxy", "Contract V2"])

    # Sort by impact, confidence, and name
    detectors_list = sorted(detectors_list,
                            key=lambda element: (element[2], element[0]))
    idx = 1
    for (argument, help_info, impact, proxy, v2) in detectors_list:
        table.add_row([
            idx,
            argument,
            help_info,
            classification_txt[impact],
            "X" if proxy else "",
            "X" if v2 else "",
        ])
        idx = idx + 1
    print(table)
示例#3
0
    def output(self, _filename):
        """
        _filename is not used
        Args:
            _filename(string)
        """

        txt = ""

        all_tables = []

        for contract in self.slither.contracts_derived:
            txt += "\n{}:\n".format(contract.name)
            table = MyPrettyTable(["Name", "Type", "Slot", "Offset"])
            for variable in contract.state_variables_ordered:
                if not variable.is_constant:
                    slot, offset = contract.compilation_unit.storage_layout_of(
                        contract, variable)
                    table.add_row([
                        variable.canonical_name,
                        str(variable.type), slot, offset
                    ])

            all_tables.append((contract.name, table))
            txt += str(table) + "\n"

        self.info(txt)

        res = self.generate_output(txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)
        return res
示例#4
0
    def output(self, _filename):
        """
            _filename is not used
            Args:
                _filename(string)
        """

        txt = ''
        all_tables = []
        for contract in self.contracts:
            txt += "\nContract %s\n" % contract.name
            table = MyPrettyTable([
                "Function", "State variables written",
                "Conditions on msg.sender"
            ])
            for function in contract.functions:

                state_variables_written = [
                    v.name for v in function.all_state_variables_written()
                ]
                msg_sender_condition = self.get_msg_sender_checks(function)
                table.add_row([
                    function.name,
                    str(state_variables_written),
                    str(msg_sender_condition)
                ])
            all_tables.append((contract.name, table))
            txt += str(table) + '\n'

        self.info(txt)
        res = self.generate_output(txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)

        return res
示例#5
0
    def output(self, _filename):
        """
        _filename is not used
        Args:
            _filename(string)
        """

        all_tables = []
        all_txt = ""
        for contract in self.slither.contracts_derived:
            txt = "\nContract %s" % contract.name
            table = MyPrettyTable(["Function", "require or assert"])
            for function in contract.functions:
                require = function.all_slithir_operations()
                require = [
                    ir for ir in require if isinstance(ir, SolidityCall)
                    and ir.function in require_or_assert
                ]
                require = [ir.node for ir in require]
                table.add_row([
                    function.name,
                    self._convert([str(m.expression) for m in set(require)]),
                ])
            txt += "\n" + str(table)
            self.info(txt)
            all_tables.append((contract.name, table))
            all_txt += txt

        res = self.generate_output(all_txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)

        return res
示例#6
0
    def output(self, _filename):
        """
        _filename is not used
        Args:
            _filename(string)
        """

        all_txt = ""
        all_tables = []

        for contract in self.slither.contracts_derived:
            txt = f"\nContract {contract.name}"
            table = MyPrettyTable(["Function", "Modifiers"])
            for function in contract.functions:
                modifiers = function.modifiers
                for call in function.all_internal_calls():
                    if isinstance(call, Function):
                        modifiers += call.modifiers
                for (_, call) in function.all_library_calls():
                    if isinstance(call, Function):
                        modifiers += call.modifiers
                table.add_row([function.name, [m.name for m in set(modifiers)]])
            txt += "\n" + str(table)
            self.info(txt)
            all_txt += txt
            all_tables.append((contract.name, table))

        res = self.generate_output(all_txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)

        return res
示例#7
0
    def output(self, _filename: str) -> output.Output:
        """
        _filename is not used
        Args:
            _filename(string)
        """

        modifier_name: str = "whenNotPaused"

        txt = ""
        txt += "Constructor and pure/view functions are not displayed\n"
        all_tables = []
        for contract in self.slither.contracts:

            txt += f"\n{contract.name}:\n"
            table = MyPrettyTable(["Name", "Use whenNotPaused"])

            for function in contract.functions_entry_points:
                status = "X" if _use_modifier(function, modifier_name) else ""
                table.add_row([function.solidity_signature, status])

            txt += str(table) + "\n"
            all_tables.append((contract.name, table))

        self.info(txt)

        res = self.generate_output(txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)

        return res
示例#8
0
def _all_properties():
    table = MyPrettyTable(["Num", "Description", "Scenario"])
    idx = 0
    for scenario, value in ERC20_PROPERTIES.items():
        for prop in value.properties:
            table.add_row([idx, prop.description, scenario])
            idx = idx + 1
    return table
示例#9
0
def output_printers(printer_classes):
    printers_list = []
    for printer in printer_classes:
        argument = printer.ARGUMENT
        help_info = printer.HELP
        printers_list.append((argument, help_info))
    table = MyPrettyTable(["Num", "Printer", "What it Does"])

    # Sort by impact, confidence, and name
    printers_list = sorted(printers_list, key=lambda element: (element[0]))
    idx = 1
    for (argument, help_info) in printers_list:
        table.add_row([idx, argument, help_info])
        idx = idx + 1
    print(table)
示例#10
0
    def output(self, _filename):
        """
            _filename is not used
            Args:
                _filename(string)
        """

        all_tables = []
        all_txt = ''

        for c in self.contracts:
            if c.is_top_level:
                continue
            (name, inheritance, var, func_summaries,
             modif_summaries) = c.get_summary()
            txt = "\nContract %s" % name
            txt += '\nContract vars: ' + str(var)
            txt += '\nInheritance:: ' + str(inheritance)
            table = MyPrettyTable([
                "Function", "Visibility", "Modifiers", "Read", "Write",
                "Internal Calls", "External Calls"
            ])
            for (_c_name, f_name, visi, modifiers, read, write, internal_calls,
                 external_calls) in func_summaries:
                read = self._convert(read)
                write = self._convert(write)
                internal_calls = self._convert(internal_calls)
                external_calls = self._convert(external_calls)
                table.add_row([
                    f_name, visi, modifiers, read, write, internal_calls,
                    external_calls
                ])
            txt += "\n \n" + str(table)
            table = MyPrettyTable([
                "Modifiers", "Visibility", "Read", "Write", "Internal Calls",
                "External Calls"
            ])
            for (_c_name, f_name, visi, _, read, write, internal_calls,
                 external_calls) in modif_summaries:
                read = self._convert(read)
                write = self._convert(write)
                internal_calls = self._convert(internal_calls)
                external_calls = self._convert(external_calls)
                table.add_row([
                    f_name, visi, read, write, internal_calls, external_calls
                ])
            txt += "\n\n" + str(table)
            txt += "\n"
            self.info(txt)

            all_tables.append((name, table))
            all_txt += txt

        res = self.generate_output(all_txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)

        return res
示例#11
0
    def add_pretty_table(self,
                         content: MyPrettyTable,
                         name: str,
                         additional_fields: Optional[Dict] = None):
        if additional_fields is None:
            additional_fields = {}
        type_specific_fields = {"content": content.to_json(), "name": name}
        element = _create_base_element("pretty_table", type_specific_fields,
                                       additional_fields)

        self._data["elements"].append(element)
示例#12
0
    def add_pretty_table(self,
                         content: MyPrettyTable,
                         name,
                         additional_fields=None):
        if additional_fields is None:
            additional_fields = {}
        type_specific_fields = {'content': content.to_json(), 'name': name}
        element = _create_base_element('pretty_table', type_specific_fields,
                                       additional_fields)

        self._data['elements'].append(element)
示例#13
0
def output_mutators(mutators_classes):
    mutators_list = []
    for detector in mutators_classes:
        argument = detector.NAME
        help_info = detector.HELP
        fault_class = detector.FAULTCLASS.name
        fault_nature = detector.FAULTNATURE.name
        mutators_list.append((argument, help_info, fault_class, fault_nature))
    table = MyPrettyTable(
        ["Num", "Name", "What it Does", "Fault Class", "Fault Nature"])

    # Sort by class, nature, name
    mutators_list = sorted(mutators_list,
                           key=lambda element:
                           (element[2], element[3], element[0]))
    idx = 1
    for (argument, help_info, fault_class, fault_nature) in mutators_list:
        table.add_row([idx, argument, help_info, fault_class, fault_nature])
        idx = idx + 1
    print(table)
    def output(self, _filename):
        """
        _filename is not used
        Args:
            _filename(string)
        """

        all_tables = []
        all_txt = ""

        txt = ""
        for c in self.contracts:
            if c.is_top_level:
                continue
            txt += f"\nContract {c.name}\n"
            table = MyPrettyTable(["Variable", "Dependencies"])
            for v in c.state_variables:
                table.add_row([v.name, _get(v, c)])

            txt += str(table)

            txt += "\n"
            for f in c.functions_and_modifiers_declared:
                txt += f"\nFunction {f.full_name}\n"
                table = MyPrettyTable(["Variable", "Dependencies"])
                for v in f.variables:
                    table.add_row([v.name, _get(v, f)])
                for v in c.state_variables:
                    table.add_row([v.canonical_name, _get(v, f)])
                txt += str(table)
            self.info(txt)

            all_txt += txt
            all_tables.append((c.name, table))

        res = self.generate_output(all_txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)

        return res
    def output(self, _filename):
        """
        _filename is not used
        Args:
            _filename(string)
        """

        txt = ""
        all_tables = []
        for contract in self.slither.contracts_derived:
            txt += f"\n{contract.name}:\n"
            table = MyPrettyTable(["Name", "ID"])
            for function in contract.functions:
                if function.visibility in ["public", "external"]:
                    function_id = get_function_id(function.solidity_signature)
                    table.add_row([
                        function.solidity_signature, f"{function_id:#0{10}x}"
                    ])
            for variable in contract.state_variables:
                if variable.visibility in ["public"]:
                    sig = variable.function_name
                    function_id = get_function_id(sig)
                    table.add_row([sig, f"{function_id:#0{10}x}"])
            txt += str(table) + "\n"
            all_tables.append((contract.name, table))

        self.info(txt)

        res = self.generate_output(txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)

        return res
示例#16
0
    def output(self, _filename):
        """
            _filename is not used
            Args:
                _filename(string)
        """

        txt = ''
        all_tables = []
        for contract in self.slither.contracts_derived:
            txt += '\n{}:\n'.format(contract.name)
            table = MyPrettyTable(['Name', 'ID'])
            for function in contract.functions:
                if function.visibility in ['public', 'external']:
                    table.add_row([
                        function.solidity_signature,
                        hex(get_function_id(function.solidity_signature))
                    ])
            for variable in contract.state_variables:
                if variable.visibility in ['public']:
                    sig = variable.function_name
                    table.add_row([sig, hex(get_function_id(sig))])
            txt += str(table) + '\n'
            all_tables.append((contract.name, table))

        self.info(txt)

        res = self.generate_output(txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)

        return res
示例#17
0
    def output(self, _filename):
        """
            _filename is not used
            Args:
                _filename(string)
        """

        all_tables = []
        all_txt = ''

        txt = ''
        for c in self.contracts:
            txt += "\nContract %s\n" % c.name
            table = MyPrettyTable(['Variable', 'Dependencies'])
            for v in c.state_variables:
                table.add_row([v.name, _get(v, c)])

            txt += str(table)

            txt += "\n"
            for f in c.functions_and_modifiers_declared:
                txt += "\nFunction %s\n" % f.full_name
                table = MyPrettyTable(['Variable', 'Dependencies'])
                for v in f.variables:
                    table.add_row([v.name, _get(v, f)])
                for v in c.state_variables:
                    table.add_row([v.canonical_name, _get(v, f)])
                txt += str(table)
            self.info(txt)

            all_txt += txt
            all_tables.append((c.name, table))

        res = self.generate_output(all_txt)
        for name, table in all_tables:
            res.add_pretty_table(table, name)

        return res
示例#18
0
def output_detectors(detector_classes):
    detectors_list = []
    for detector in detector_classes:
        argument = detector.ARGUMENT
        # dont show the backdoor example
        if argument == "backdoor":
            continue
        help_info = detector.HELP
        impact = detector.IMPACT
        confidence = classification_txt[detector.CONFIDENCE]
        detectors_list.append((argument, help_info, impact, confidence))
    table = MyPrettyTable(
        ["Num", "Check", "What it Detects", "Impact", "Confidence"])

    # Sort by impact, confidence, and name
    detectors_list = sorted(detectors_list,
                            key=lambda element:
                            (element[2], element[3], element[0]))
    idx = 1
    for (argument, help_info, impact, confidence) in detectors_list:
        table.add_row(
            [idx, argument, help_info, classification_txt[impact], confidence])
        idx = idx + 1
    print(table)
示例#19
0
    def output(self, _filename):
        """
        _filename is not used
            Args:
                _filename(string)
        """

        txt = "\n"
        txt += self._compilation_type()

        results = {
            'contracts': {
                "elements": []
            },
            'number_lines': 0,
            'number_lines_in_dependencies': 0,
            'number_lines_assembly': 0,
            'standard_libraries': [],
            'ercs': [],
            'number_findings': dict(),
            'detectors': []
        }

        lines_number = self._lines_number()
        if lines_number:
            total_lines, total_dep_lines, total_tests_lines = lines_number
            txt += f'Number of lines: {total_lines} (+ {total_dep_lines} in dependencies, + {total_tests_lines} in tests)\n'
            results['number_lines'] = total_lines
            results['number_lines__dependencies'] = total_dep_lines
            total_asm_lines = self._get_number_of_assembly_lines()
            txt += f"Number of assembly lines: {total_asm_lines}\n"
            results['number_lines_assembly'] = total_asm_lines

        number_contracts, number_contracts_deps, number_contracts_tests = self._number_contracts(
        )
        txt += f'Number of contracts: {number_contracts} (+ {number_contracts_deps} in dependencies, + {number_contracts_tests} tests) \n\n'

        txt_detectors, detectors_results, optimization, info, low, medium, high = self.get_detectors_result(
        )
        txt += txt_detectors

        results['number_findings'] = {
            'optimization_issues': optimization,
            'informational_issues': info,
            'low_issues': low,
            'medium_issues': medium,
            'high_issues': high
        }
        results['detectors'] = detectors_results

        libs = self._standard_libraries()
        if libs:
            txt += f'\nUse: {", ".join(libs)}\n'
            results['standard_libraries'] = [str(l) for l in libs]

        ercs = self._ercs()
        if ercs:
            txt += f'ERCs: {", ".join(ercs)}\n'
            results['ercs'] = [str(e) for e in ercs]

        table = MyPrettyTable([
            "Name", "# functions", "ERCS", "ERC20 info", "Complex code",
            "Features"
        ])
        for contract in self.slither.contracts_derived:

            if contract.is_from_dependency() or contract.is_test:
                continue

            is_complex = self.is_complex_code(contract)
            number_functions = self._number_functions(contract)
            ercs = ','.join(contract.ercs())
            is_erc20 = contract.is_erc20()
            erc20_info = ''
            if is_erc20:
                erc20_info += self.get_summary_erc20(contract)

            features = "\n".join([
                name
                for name, to_print in self._get_features(contract).items()
                if to_print
            ])

            table.add_row([
                contract.name, number_functions, ercs, erc20_info, is_complex,
                features
            ])

        self.info(txt + '\n' + str(table))

        results_contract = output.Output('')
        for contract in self.slither.contracts_derived:
            if contract.is_test or contract.is_from_dependency():
                continue

            contract_d = {
                'contract_name':
                contract.name,
                'is_complex_code':
                self._is_complex_code(contract),
                'is_erc20':
                contract.is_erc20(),
                'number_functions':
                self._number_functions(contract),
                'features': [
                    name
                    for name, to_print in self._get_features(contract).items()
                    if to_print
                ]
            }
            if contract_d['is_erc20']:
                pause, mint_limited, race_condition_mitigated = self._get_summary_erc20(
                    contract)
                contract_d['erc20_pause'] = pause
                if mint_limited is not None:
                    contract_d['erc20_can_mint'] = True
                    contract_d['erc20_mint_limited'] = mint_limited
                else:
                    contract_d['erc20_can_mint'] = False
                contract_d[
                    'erc20_race_condition_mitigated'] = race_condition_mitigated
            results_contract.add_contract(contract,
                                          additional_fields=contract_d)

        results['contracts']['elements'] = results_contract.elements

        json = self.generate_output(txt, additional_fields=results)

        return json
示例#20
0
    def output(self, _filename):  # pylint: disable=too-many-locals,too-many-statements
        """
        _filename is not used
            Args:
                _filename(string)
        """

        txt = "\n"
        txt += self._compilation_type()

        results = {
            "contracts": {"elements": []},
            "number_lines": 0,
            "number_lines_in_dependencies": 0,
            "number_lines_assembly": 0,
            "standard_libraries": [],
            "ercs": [],
            "number_findings": dict(),
            "detectors": [],
        }

        lines_number = self._lines_number()
        if lines_number:
            total_lines, total_dep_lines, total_tests_lines = lines_number
            txt += f"Number of lines: {total_lines} (+ {total_dep_lines} in dependencies, + {total_tests_lines} in tests)\n"
            results["number_lines"] = total_lines
            results["number_lines__dependencies"] = total_dep_lines
            total_asm_lines = self._get_number_of_assembly_lines()
            txt += f"Number of assembly lines: {total_asm_lines}\n"
            results["number_lines_assembly"] = total_asm_lines

        (
            number_contracts,
            number_contracts_deps,
            number_contracts_tests,
        ) = self._number_contracts()
        txt += f"Number of contracts: {number_contracts} (+ {number_contracts_deps} in dependencies, + {number_contracts_tests} tests) \n\n"

        (
            txt_detectors,
            detectors_results,
            optimization,
            info,
            low,
            medium,
            high,
        ) = self.get_detectors_result()
        txt += txt_detectors

        results["number_findings"] = {
            "optimization_issues": optimization,
            "informational_issues": info,
            "low_issues": low,
            "medium_issues": medium,
            "high_issues": high,
        }
        results["detectors"] = detectors_results

        libs = self._standard_libraries()
        if libs:
            txt += f'\nUse: {", ".join(libs)}\n'
            results["standard_libraries"] = [str(l) for l in libs]

        ercs = self._ercs()
        if ercs:
            txt += f'ERCs: {", ".join(ercs)}\n'
            results["ercs"] = [str(e) for e in ercs]

        table = MyPrettyTable(
            ["Name", "# functions", "ERCS", "ERC20 info", "Complex code", "Features"]
        )
        for contract in self.slither.contracts_derived:

            if contract.is_from_dependency() or contract.is_test:
                continue

            is_complex = self.is_complex_code(contract)
            number_functions = self._number_functions(contract)
            ercs = ",".join(contract.ercs())
            is_erc20 = contract.is_erc20()
            erc20_info = ""
            if is_erc20:
                erc20_info += self.get_summary_erc20(contract)

            features = "\n".join(
                [name for name, to_print in self._get_features(contract).items() if to_print]
            )

            table.add_row(
                [contract.name, number_functions, ercs, erc20_info, is_complex, features,]
            )

        self.info(txt + "\n" + str(table))

        results_contract = output.Output("")
        for contract in self.slither.contracts_derived:
            if contract.is_test or contract.is_from_dependency():
                continue

            contract_d = {
                "contract_name": contract.name,
                "is_complex_code": self._is_complex_code(contract),
                "is_erc20": contract.is_erc20(),
                "number_functions": self._number_functions(contract),
                "features": [
                    name for name, to_print in self._get_features(contract).items() if to_print
                ],
            }
            if contract_d["is_erc20"]:
                pause, mint_limited, race_condition_mitigated = self._get_summary_erc20(contract)
                contract_d["erc20_pause"] = pause
                if mint_limited is not None:
                    contract_d["erc20_can_mint"] = True
                    contract_d["erc20_mint_limited"] = mint_limited
                else:
                    contract_d["erc20_can_mint"] = False
                contract_d["erc20_race_condition_mitigated"] = race_condition_mitigated
            results_contract.add_contract(contract, additional_fields=contract_d)

        results["contracts"]["elements"] = results_contract.elements

        json = self.generate_output(txt, additional_fields=results)

        return json