diff --git a/slither/printers/all_printers.py b/slither/printers/all_printers.py index d3e836d711..5855a7095f 100644 --- a/slither/printers/all_printers.py +++ b/slither/printers/all_printers.py @@ -26,3 +26,4 @@ from .summary.martin import Martin from .summary.cheatcodes import CheatcodePrinter from .summary.entry_points import PrinterEntryPoints +from .summary.storage_variables import PrinterStorageVariables diff --git a/slither/printers/summary/storage_variables.py b/slither/printers/summary/storage_variables.py new file mode 100644 index 0000000000..c915cf2ca7 --- /dev/null +++ b/slither/printers/summary/storage_variables.py @@ -0,0 +1,66 @@ +""" +Module printing all storage variables of the contracts +""" + +from slither.printers.abstract_printer import AbstractPrinter +from slither.utils.colors import Colors +from slither.utils.output import Output +from slither.utils.myprettytable import MyPrettyTable + + +class PrinterStorageVariables(AbstractPrinter): + + ARGUMENT = "storage-variables" + HELP = "Print all storage variables of the contracts" + + WIKI = "https://github.com/trailofbits/slither/wiki/Printer-documentation#storage-variables" + + def output(self, _filename) -> Output: + """ + _filename is not used + Args: + _filename(string) + """ + all_contracts = [] + + for contract in sorted( + ( + c + for c in self.slither.contracts_derived + if not c.is_test and not c.is_from_dependency() + ), + key=lambda x: x.name, + ): + storage_vars = contract.storage_variables_ordered + + if not storage_vars: + continue + + table = MyPrettyTable( + ["Variable", "Type", "Visibility", "Slot", "Offset", "Inherited From"] + ) + + contract_info = [ + f"\nContract {Colors.BOLD}{Colors.YELLOW}{contract.name}{Colors.END}" + f" ({contract.source_mapping})" + ] + + for v in storage_vars: + slot, offset = contract.compilation_unit.storage_layout_of(contract, v) + inherited = v.contract.name if v.contract != contract else "" + table.add_row( + [ + f"{Colors.BOLD}{Colors.RED}{v.name}{Colors.END}", + f"{Colors.GREEN}{v.type}{Colors.END}", + f"{Colors.BLUE}{v.visibility}{Colors.END}", + slot, + offset, + f"{Colors.MAGENTA}{inherited}{Colors.END}", + ] + ) + + all_contracts.append("\n".join(contract_info + [str(table)])) + + info = "\n".join(all_contracts) if all_contracts else "" + self.info(info) + return self.generate_output(info)