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)
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)
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)
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
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