Esempio n. 1
0
    def output(self, _filename):
        """
            _filename is not used
            Args:
                _filename(string)
        """

        txt = ""
        for c in self.contracts:
            (name, _inheritance, _var, func_summaries, _modif_summaries) = c.get_summary()
            txt += blue("\n+ Contract %s\n"%name)
            for (f_name, visi, _, _, _, _, _) in func_summaries:
                txt += "  - "
                if visi in ['external', 'public']:
                    txt += green("%s (%s)\n"%(f_name, visi))
                elif visi in ['internal', 'private']:
                    txt += magenta("%s (%s)\n"%(f_name, visi))
                else:
                    txt += "%s (%s)\n"%(f_name, visi)
        self.info(txt)
Esempio n. 2
0
def run(filename, mod_name):
    """Executes script"""

    # Init Slither
    slither = Slither(filename)
    if not len(slither.contracts):
        print(f"Error: Slither could not find any contracts")
        exit(-1)

    print(f"== Functions with {yellow(mod_name)} modifier ==")
    txt = ""
    for c in slither.contracts:
            txt += blue(f"\n+ Contract {c.name}\n")

            collect = collections.defaultdict(list)

            for f in filter_by_modifier(c.functions, mod_name):
                collect[f.contract.name].append((f.full_name, f.visibility))
            
            for contract, function_visi_pairs in collect.items():
                txt += blue(f"  - From {contract}\n")
                
                function_visi_pairs = sorted(function_visi_pairs)

                for function, visi in function_visi_pairs:
                    if visi in ['external', 'public']:
                        txt += green(f"    - {function} ({visi})\n")
                
                for function, visi in function_visi_pairs:
                    if visi in ['internal', 'private']:
                        txt += magenta(f"    - {function} ({visi})\n")
                
                for function, visi in function_visi_pairs:
                    if visi not in ['external', 'public', 'internal', 'private']:
                        txt += f"    - {function}  ({visi})\n"

    print(txt)
Esempio n. 3
0
    def output(self, _filename):
        """
            _filename is not used
            Args:
                _filename(string)
        """

        txt = ""
        for c in self.contracts:
            (name, _inheritance, _var, func_summaries,
             _modif_summaries) = c.get_summary()
            txt += blue("\n+ Contract %s\n" % name)
            # (c_name, f_name, visi, _, _, _, _, _) in func_summaries
            public = [(elem[0], (elem[1], elem[2])) for elem in func_summaries]

            collect = collections.defaultdict(list)
            for a, b in public:
                collect[a].append(b)
            public = list(collect.items())

            for contract, functions in public:
                txt += blue("  - From {}\n".format(contract))
                functions = sorted(functions)
                for (function, visi) in functions:
                    if visi in ['external', 'public']:
                        txt += green("    - {} ({})\n".format(function, visi))
                for (function, visi) in functions:
                    if visi in ['internal', 'private']:
                        txt += magenta("    - {} ({})\n".format(
                            function, visi))
                for (function, visi) in functions:
                    if visi not in [
                            'external', 'public', 'internal', 'private'
                    ]:
                        txt += "    - {}  ({})\n".format(function, visi)

        self.info(txt)
Esempio n. 4
0
    def output(self, _filename):
        """
            _filename is not used
            Args:
                _filename(string)
        """

        txt = ""

        all_contracts = []
        for c in self.contracts:
            if c.is_top_level:
                continue

            is_upgradeable_proxy = c.is_upgradeable_proxy
            is_upgradeable = c.is_upgradeable

            additional_txt_info = ''

            if is_upgradeable_proxy:
                additional_txt_info += ' (Upgradeable Proxy)'

            if is_upgradeable:
                additional_txt_info += ' (Upgradeable)'

            if c in self.slither.contracts_derived:
                additional_txt_info += ' (Most derived contract)'

            txt += blue(f"\n+ Contract {c.name}{additional_txt_info}\n")
            additional_fields = output.Output(
                '',
                additional_fields={
                    'is_upgradeable_proxy': is_upgradeable_proxy,
                    'is_upgradeable': is_upgradeable,
                    'is_most_derived': c in self.slither.contracts_derived
                })

            # Order the function with
            # contract_declarer -> list_functions
            public = [(f.contract_declarer.name, f) for f in c.functions
                      if (not f.is_shadowed and not f.is_constructor_variables)
                      ]
            collect = collections.defaultdict(list)
            for a, b in public:
                collect[a].append(b)
            public = list(collect.items())

            for contract, functions in public:
                txt += blue("  - From {}\n".format(contract))

                functions = sorted(functions, key=lambda f: f.full_name)

                for function in functions:
                    if function.visibility in ['external', 'public']:
                        txt += green("    - {} ({})\n".format(
                            function.full_name, function.visibility))
                    if function.visibility in ['internal', 'private']:
                        txt += magenta("    - {} ({})\n".format(
                            function.full_name, function.visibility))
                    if function.visibility not in [
                            'external', 'public', 'internal', 'private'
                    ]:
                        txt += "    - {}  ({})\n".format(
                            function.full_name, function.visibility)

                    additional_fields.add(
                        function,
                        additional_fields={"visibility": function.visibility})

            all_contracts.append((c, additional_fields.data))

        self.info(txt)

        res = self.generate_output(txt)
        for contract, additional_fields in all_contracts:
            res.add(contract, additional_fields=additional_fields)

        return res
    def output(self, _filename):  # pylint: disable=too-many-locals
        """
        _filename is not used
        Args:
            _filename(string)
        """

        txt = ""

        all_contracts = []
        for c in self.contracts:
            if c.is_top_level:
                continue

            is_upgradeable_proxy = c.is_upgradeable_proxy
            is_upgradeable = c.is_upgradeable

            additional_txt_info = ""

            if is_upgradeable_proxy:
                additional_txt_info += " (Upgradeable Proxy)"

            if is_upgradeable:
                additional_txt_info += " (Upgradeable)"

            if c in self.slither.contracts_derived:
                additional_txt_info += " (Most derived contract)"

            txt += blue(f"\n+ Contract {c.name}{additional_txt_info}\n")
            additional_fields = output.Output(
                "",
                additional_fields={
                    "is_upgradeable_proxy": is_upgradeable_proxy,
                    "is_upgradeable": is_upgradeable,
                    "is_most_derived": c in self.slither.contracts_derived,
                },
            )

            # Order the function with
            # contract_declarer -> list_functions
            public = [
                (f.contract_declarer.name, f)
                for f in c.functions
                if (not f.is_shadowed and not f.is_constructor_variables)
            ]
            collect = collections.defaultdict(list)
            for a, b in public:
                collect[a].append(b)
            public = list(collect.items())

            for contract, functions in public:
                txt += blue(f"  - From {contract}\n")

                functions = sorted(functions, key=lambda f: f.full_name)

                for function in functions:
                    if function.visibility in ["external", "public"]:
                        txt += green(f"    - {function.full_name} ({function.visibility})\n")
                    if function.visibility in ["internal", "private"]:
                        txt += magenta(f"    - {function.full_name} ({function.visibility})\n")
                    if function.visibility not in [
                        "external",
                        "public",
                        "internal",
                        "private",
                    ]:
                        txt += f"    - {function.full_name}  ({function.visibility})\n"

                    additional_fields.add(
                        function, additional_fields={"visibility": function.visibility}
                    )

            all_contracts.append((c, additional_fields.data))

        self.info(txt)

        res = self.generate_output(txt)
        for contract, additional_fields in all_contracts:
            res.add(contract, additional_fields=additional_fields)

        return res
Esempio n. 6
0
    def output(self, _filename):
        """
        _filename is not used
        Args:
            _filename(string)
        """

        txt = ""
        if not self.slither.crytic_compile:
            txt = "The EVM printer requires to compile with crytic-compile"
            self.info(red(txt))
            res = self.generate_output(txt)
            return res
        evm_info = _extract_evm_info(self.slither)

        for contract in self.slither.contracts_derived:
            txt += blue("Contract {}\n".format(contract.name))

            contract_file = self.slither.source_code[
                contract.source_mapping["filename_absolute"]
            ].encode("utf-8")
            contract_file_lines = open(
                contract.source_mapping["filename_absolute"], "r"
            ).readlines()

            contract_pcs = {}
            contract_cfg = {}

            for function in contract.functions:
                txt += blue(f"\tFunction {function.canonical_name}\n")

                # CFG and source mapping depend on function being constructor or not
                if function.is_constructor:
                    contract_cfg = evm_info["cfg_init", contract.name]
                    contract_pcs = evm_info["mapping_init", contract.name]
                else:
                    contract_cfg = evm_info["cfg", contract.name]
                    contract_pcs = evm_info["mapping", contract.name]

                for node in function.nodes:
                    txt += green("\t\tNode: " + str(node) + "\n")
                    node_source_line = (
                        contract_file[0 : node.source_mapping["start"]].count("\n".encode("utf-8"))
                        + 1
                    )
                    txt += green(
                        "\t\tSource line {}: {}\n".format(
                            node_source_line,
                            contract_file_lines[node_source_line - 1].rstrip(),
                        )
                    )
                    txt += magenta("\t\tEVM Instructions:\n")
                    node_pcs = contract_pcs.get(node_source_line, [])
                    for pc in node_pcs:
                        txt += magenta(
                            "\t\t\t0x{:x}: {}\n".format(
                                int(pc), contract_cfg.get_instruction_at(pc)
                            )
                        )

            for modifier in contract.modifiers:
                txt += blue(f"\tModifier {modifier.canonical_name}\n")
                for node in modifier.nodes:
                    txt += green("\t\tNode: " + str(node) + "\n")
                    node_source_line = (
                        contract_file[0 : node.source_mapping["start"]].count("\n".encode("utf-8"))
                        + 1
                    )
                    txt += green(
                        "\t\tSource line {}: {}\n".format(
                            node_source_line,
                            contract_file_lines[node_source_line - 1].rstrip(),
                        )
                    )
                    txt += magenta("\t\tEVM Instructions:\n")
                    node_pcs = contract_pcs.get(node_source_line, [])
                    for pc in node_pcs:
                        txt += magenta(
                            "\t\t\t0x{:x}: {}\n".format(
                                int(pc), contract_cfg.get_instruction_at(pc)
                            )
                        )

        self.info(txt)
        res = self.generate_output(txt)
        return res