From d186612d4cefd3882533dfe68584692ea37c4282 Mon Sep 17 00:00:00 2001 From: nisedo <73041332+nisedo@users.noreply.github.com> Date: Mon, 17 Feb 2025 15:19:59 +0100 Subject: [PATCH 1/5] Add storage_variables printer --- slither/printers/all_printers.py | 1 + slither/printers/summary/storage_variables.py | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 slither/printers/summary/storage_variables.py 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..92890a0a12 --- /dev/null +++ b/slither/printers/summary/storage_variables.py @@ -0,0 +1,71 @@ +""" +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) + """ + excluded_paths = {"lib/", "node_modules/", "test/", "tests/", "mock/", "mocks/", "scripts/"} + all_contracts = [] + + for contract in sorted( + ( + c + for c in self.contracts + if not (c.is_interface or c.is_library or c.is_abstract) + and not any(path in c.source_mapping.filename.absolute for path in excluded_paths) + ), + key=lambda x: x.name, + ): + storage_vars = [ + v for v in contract.state_variables if not (v.is_constant or v.is_immutable) + ] + + if not storage_vars: + continue + + table = MyPrettyTable(["Variable", "Type", "Visibility", "Slot", "Inherited From"]) + contract_info = [ + f"\nContract {Colors.BOLD}{Colors.YELLOW}{contract.name}{Colors.END}" + f" ({contract.source_mapping})" + ] + + storage_vars = sorted( + storage_vars, + key=lambda x: contract.compilation_unit.storage_layout_of(contract, x)[0], + ) + + for v in storage_vars: + slot = contract.compilation_unit.storage_layout_of(contract, v)[0] + inherited = v.contract.name if v.contract != contract else "" + table.add_row( + [ + f"{Colors.BOLD}{Colors.RED}{v.name}{Colors.END}", + f"{Colors.GREEN}{str(v.type)}{Colors.END}", + f"{Colors.BLUE}{v.visibility}{Colors.END}", + str(slot), + f"{Colors.MAGENTA}{inherited}{Colors.END}" if inherited else "", + ] + ) + + 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) From 81e414089068a77cc25b02efba98f342e1ecdeac Mon Sep 17 00:00:00 2001 From: nisedo <73041332+nisedo@users.noreply.github.com> Date: Mon, 17 Feb 2025 15:58:38 +0100 Subject: [PATCH 2/5] Update storage_variables.py for linter --- slither/printers/summary/storage_variables.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slither/printers/summary/storage_variables.py b/slither/printers/summary/storage_variables.py index 92890a0a12..c3c380eeea 100644 --- a/slither/printers/summary/storage_variables.py +++ b/slither/printers/summary/storage_variables.py @@ -48,7 +48,9 @@ def output(self, _filename) -> Output: storage_vars = sorted( storage_vars, - key=lambda x: contract.compilation_unit.storage_layout_of(contract, x)[0], + key=lambda x, contract=contract: contract.compilation_unit.storage_layout_of( + contract, x + )[0], ) for v in storage_vars: From 02778e29a2fce408045ee974656f77203fc6bb9a Mon Sep 17 00:00:00 2001 From: nisedo <73041332+nisedo@users.noreply.github.com> Date: Mon, 17 Feb 2025 20:42:53 +0100 Subject: [PATCH 3/5] Refactor storage variables printer to use derived contracts and improve filtering --- slither/printers/summary/storage_variables.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/slither/printers/summary/storage_variables.py b/slither/printers/summary/storage_variables.py index c3c380eeea..fd0360d0e3 100644 --- a/slither/printers/summary/storage_variables.py +++ b/slither/printers/summary/storage_variables.py @@ -21,15 +21,13 @@ def output(self, _filename) -> Output: Args: _filename(string) """ - excluded_paths = {"lib/", "node_modules/", "test/", "tests/", "mock/", "mocks/", "scripts/"} all_contracts = [] for contract in sorted( ( c - for c in self.contracts - if not (c.is_interface or c.is_library or c.is_abstract) - and not any(path in c.source_mapping.filename.absolute for path in excluded_paths) + for c in self.slither.contracts_derived + if not c.is_test and not c.is_from_dependency() ), key=lambda x: x.name, ): From 394436bb2e7fb5a01e22dc2d86ff4703e7bf2ff5 Mon Sep 17 00:00:00 2001 From: nisedo <73041332+nisedo@users.noreply.github.com> Date: Fri, 21 Feb 2025 15:11:30 +0100 Subject: [PATCH 4/5] Clean the code + add slot offset + left-aligned text --- slither/printers/summary/storage_variables.py | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/slither/printers/summary/storage_variables.py b/slither/printers/summary/storage_variables.py index fd0360d0e3..25f7d42636 100644 --- a/slither/printers/summary/storage_variables.py +++ b/slither/printers/summary/storage_variables.py @@ -31,36 +31,33 @@ def output(self, _filename) -> Output: ), key=lambda x: x.name, ): - storage_vars = [ - v for v in contract.state_variables if not (v.is_constant or v.is_immutable) - ] + storage_vars = contract.storage_variables_ordered if not storage_vars: continue - table = MyPrettyTable(["Variable", "Type", "Visibility", "Slot", "Inherited From"]) + table = MyPrettyTable( + ["Variable", "Type", "Visibility", "Slot", "Offset", "Inherited From"] + ) + for field in table._field_names: + table._options["set_alignment"] += [(field, "l")] + contract_info = [ f"\nContract {Colors.BOLD}{Colors.YELLOW}{contract.name}{Colors.END}" f" ({contract.source_mapping})" ] - storage_vars = sorted( - storage_vars, - key=lambda x, contract=contract: contract.compilation_unit.storage_layout_of( - contract, x - )[0], - ) - for v in storage_vars: - slot = contract.compilation_unit.storage_layout_of(contract, v)[0] + 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}{str(v.type)}{Colors.END}", + f"{Colors.GREEN}{v.type}{Colors.END}", f"{Colors.BLUE}{v.visibility}{Colors.END}", - str(slot), - f"{Colors.MAGENTA}{inherited}{Colors.END}" if inherited else "", + slot, + offset, + f"{Colors.MAGENTA}{inherited}{Colors.END}", ] ) From 70e384858366974826e6df03c14c709272d0714b Mon Sep 17 00:00:00 2001 From: nisedo <73041332+nisedo@users.noreply.github.com> Date: Fri, 21 Feb 2025 15:34:37 +0100 Subject: [PATCH 5/5] Remove unnecessary table alignment configuration --- slither/printers/summary/storage_variables.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/slither/printers/summary/storage_variables.py b/slither/printers/summary/storage_variables.py index 25f7d42636..c915cf2ca7 100644 --- a/slither/printers/summary/storage_variables.py +++ b/slither/printers/summary/storage_variables.py @@ -39,8 +39,6 @@ def output(self, _filename) -> Output: table = MyPrettyTable( ["Variable", "Type", "Visibility", "Slot", "Offset", "Inherited From"] ) - for field in table._field_names: - table._options["set_alignment"] += [(field, "l")] contract_info = [ f"\nContract {Colors.BOLD}{Colors.YELLOW}{contract.name}{Colors.END}"